package com.xunwang.education.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.gson.Gson;
import com.xunwang.education.util.ThreadPoolUtil;
import com.xunwang.servicebase.utils.JwtUtils;
import com.xunwang.servicebase.utils.R;
import com.xunwang.education.entity.InviteInfo;
import com.xunwang.education.entity.OrderInfo;
import com.xunwang.education.entity.StuNeeds;
import com.xunwang.education.entity.TeacherCertifications;
import com.xunwang.education.entity.dto.MyInviteInfoDto;
import com.xunwang.education.entity.socket.Commucation;
import com.xunwang.education.entity.socket.Type;
import com.xunwang.education.feign.PayFeign;
import com.xunwang.education.feign.UserFeign;
import com.xunwang.education.handler.ChatEndpoint;
import com.xunwang.education.mapper.InviteInfoMapper;
import com.xunwang.education.service.InviteInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xunwang.education.service.StudentRequirementsService;
import com.xunwang.education.service.TeacherCertificationsService;
import com.xunwang.education.service.TeacherCoursesService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Guan
 * @since 2023-01-03
 */
@Service
public class InviteInfoServiceImpl extends ServiceImpl<InviteInfoMapper, InviteInfo> implements InviteInfoService {

    @Resource
    private TeacherCertificationsService certificationsService;

    @Resource
    private StudentRequirementsService studentRequirementsService;

    @Resource
    private PayFeign payFeign;

    @Resource
    private UserFeign userFeign;

    @Resource
    private TeacherCoursesService teacherCoursesService;

    @Resource
    private ChatEndpoint chatEndpoint;

    //点击进入我收到的邀请详情，未读变已读，操作变待定
    @Override
    public void modifyStatusToHold(String id) {
        LambdaQueryWrapper<InviteInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(InviteInfo::getId, id).eq(InviteInfo::getReadStatus, "未读");
        InviteInfo inviteInfo = baseMapper.selectOne(queryWrapper);
        if (inviteInfo != null){
            inviteInfo.setReadStatus("已读");
            inviteInfo.setOperateStatus("待定");
            baseMapper.update(inviteInfo, new LambdaQueryWrapper<InviteInfo>().eq(InviteInfo::getId, id));
        }
    }

    // 查询发送的邀请信息list
    @Override
    public List<MyInviteInfoDto> sendMyInviteInfoList(HttpServletRequest request, String status) {
        String methodName = "sendMyInviteInfoList";
        return MyInviteInfoList(request, status, methodName);
    }

    // 查询接受的邀请信息list
    @Override
    public List<MyInviteInfoDto> receiveMyInviteInfoList(HttpServletRequest request, String status) {
        String methodName = "receiveMyInviteInfoList";
        return MyInviteInfoList(request, status, methodName);
    }

    // 获取邀请详情
    @Override
    public InviteInfo getInvitationDetail(HttpServletRequest request) {
        String inviteId = request.getParameter("inviteId");
        InviteInfo inviteInfo = baseMapper.selectOne(new LambdaQueryWrapper<InviteInfo>().eq(InviteInfo::getId, inviteId));
        if ("教员".equals(inviteInfo.getIdentity())) {
            String fromUid = inviteInfo.getFromUid();
            TeacherCertifications one = certificationsService.getOne(new LambdaQueryWrapper<TeacherCertifications>().eq(TeacherCertifications::getUid, fromUid).select(TeacherCertifications::getTeacherPhoto));
            String profilePhoto = one.getTeacherPhoto();
            inviteInfo.setImgUrl(profilePhoto);
        } else {
            // 学员
            String requireId = inviteInfo.getRequireId();
            StuNeeds one = studentRequirementsService.getOne(new LambdaQueryWrapper<StuNeeds>().eq(StuNeeds::getRequireId, requireId).select(StuNeeds::getSex));
            String sex = one.getSex();
            inviteInfo.setSex(sex);
        }
        if (inviteInfo.getRequireDetail() == null) {
            inviteInfo.setRequireDetail("无");
        }
        return inviteInfo;
    }

    /**
     * 同意邀请
     * @param request
     * @return
     */
    @Override
    public R agreeInvitation(HttpServletRequest request) throws IOException {
        String id = request.getParameter("id");
        InviteInfo invite = getById(id);
        String lock = invite.getCourseId();

        // 1.查询课程是否下架,是否上锁
        String s = teacherCoursesService.queryLockOrDisplay(invite.getCourseId());
        String[] ss = s.split(" ");
        if (!"课程ok".equals(ss[0])) {
            return R.ok().message(s);
        }
        String courseVersion = ss[1];

        // 2.查询需求是否下架,是否上锁
        String s1 = studentRequirementsService.queryLockOrDisplay(invite.getRequireId());
        String[] s11 = s1.split(" ");
        if (!"需求ok".equals(s11[0])) {
            return R.ok().message(s1);
        }
        String requireVersion = s11[1];

        boolean b;
        boolean b1;
        // 3.锁定需求号和课程号
        synchronized (lock) {
            b = teacherCoursesService.lockCourseId(invite.getCourseId(), courseVersion);
            b1 = studentRequirementsService.lockStuNeedId(invite.getRequireId(), requireVersion);
        }

        if (!b || !b1) {
            return R.ok().message("同意失败，请稍后在试");
        }

        // 修改邀请信息
        invite.setOperateStatus("同意");
        update(invite,new LambdaQueryWrapper<InviteInfo>().eq(InviteInfo::getId, id));

        // 4.新增订单表
        R r = payFeign.generateOrder(id);
        if ("教员".equals(invite.getIdentity())) {
            Object info = r.getData().get("info");
            Gson gson = new Gson();
            String infos = gson.toJson(info);
            OrderInfo orderInfo = gson.fromJson(infos, OrderInfo.class);
            // 5.向客户端(教员)主动推送订单消息
            chatEndpoint.sendInvited(invite.getFromUid(), orderInfo.getOrderId(), Commucation.PAYNOTICE.getMessage(), Type.PAYNOTICE.getType());
            r.data("identify", "教员");
        } else {
            r.data("identify", "学员");
        }

        ThreadPoolExecutor threadPool = ThreadPoolUtil.getThreadPool();
        threadPool.submit(() -> {
            // 6.向教员发送公众号支付消息
            String requireId = invite.getRequireId();
            StuNeeds stuNeeds = studentRequirementsService.getOne(new LambdaQueryWrapper<StuNeeds>().eq(StuNeeds::getRequireId, requireId));
            String subjectBig = stuNeeds.getSubjectBig();
            String subjectSmall = stuNeeds.getSubjectSmall();
            String locationStr = stuNeeds.getLocationStr();
            BigDecimal salary = stuNeeds.getSalary();
            String stringSalary = salary.toString();
            String phone = stuNeeds.getPhone();
            String teacherId = "";
            if ("教员".equals(invite.getIdentity())) {
                teacherId = invite.getFromUid();
            } else {
                teacherId = invite.getToUid();
            }
            String unionid = userFeign.getUnionIdByUid(teacherId);
            payFeign.sendTemplateMsgPay(unionid, subjectBig, subjectSmall, locationStr, stringSalary, phone, "");
        });

        return r;
    }

    private List<MyInviteInfoDto> MyInviteInfoList(HttpServletRequest request, String status, String methodName) {
        String id = JwtUtils.getUIdByJwtToken(request);
        List<MyInviteInfoDto> list = new ArrayList<>();
        if (methodName.equals("receiveMyInviteInfoList")) {
            list = this.baseMapper.receiveMyInviteInfoList(id, status);
        }
        if (methodName.equals("sendMyInviteInfoList")) {
            list = this.baseMapper.sendMyInviteInfoList(id, status);
        }
        list.stream().peek(item -> {
            if (item.getRequireDetail() == null) {
                item.setRequireDetail("无");
            }
        }).collect(Collectors.toList());
        return list;
    }
}
