package com.cool.store.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.cool.store.context.PartnerUserHolder;
import com.cool.store.dao.HyInterviewDAO;
import com.cool.store.dto.log.ModifyInterviewTimeDTO;
import com.cool.store.dto.partner.EnterInterviewDto;
import com.cool.store.dto.partner.LineQueryInterviewDto;
import com.cool.store.entity.HyPartnerInterviewDO;
import com.cool.store.entity.HyPartnerInterviewPlanDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.OperateTypeEnum;
import com.cool.store.enums.RoomStatus;
import com.cool.store.enums.WorkflowStatusEnum;
import com.cool.store.exception.ApiException;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.HyPartnerInterviewMapper;
import com.cool.store.mapper.HyPartnerInterviewPlanMapper;
import com.cool.store.request.ModifyInterviewTimeReq;
import com.cool.store.service.LogService;
import com.cool.store.service.PartnerInterviewService;
import com.cool.store.utils.CoolDateUtils;
import com.cool.store.utils.TRTCUtils;
import com.cool.store.vo.EnterInterviewVO;
import com.cool.store.vo.PartnerInterviewInfoVO;
import com.cool.store.vo.PartnerPassLetterDetailVO;
import com.cool.store.vo.PartnerUserInfoVO;
import com.cool.store.vo.interview.InterviewVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
@Slf4j
public class PartnerInterviewServiceImpl implements PartnerInterviewService {

    @Autowired
    private HyPartnerInterviewMapper interviewMapper;

    @Autowired
    private HyPartnerInterviewPlanMapper  interviewPlanMapper;

    @Autowired
    private HyInterviewDAO interviewDAO;

    @Value("${trtc.sdkAppId}")
    private Long sdkAppId;

    @Value("${trtc.secretKey}")
    private String key;

    @Autowired
    private LogService logService;

    /**
     * 加盟商查询面试信息
     *
     * @param partnerId
     * @return
     */
    @Override
    public PartnerInterviewInfoVO queryByPartnerId(String partnerId) {
        return interviewMapper.queryByPartnerId(partnerId);
    }

    @Override
    public PartnerInterviewInfoVO queryByPartnerLineId(LineQueryInterviewDto request) throws ApiException {
        return interviewMapper.queryByPartnerLineId(request.getPartnerLineId());
    }

    /**
     * 进入面试间的方法
     * 修改一些面试状态
     * 最后返回 userSign 用于进入腾讯云音视频房间
     *
     * @return userSign 进入视频所需签名
     */
    @Override
    @Transactional
    public EnterInterviewVO enterInterviewRoom(EnterInterviewDto dto) throws ApiException {
        try {
            //房间状态
            Integer roomStatus = interviewPlanMapper.getRoomStatus(dto.getInterviewPlanId());
            //面试流程状态
            String status = interviewMapper.getStatus(dto.getInterviewPlanId());
            //如果面试间状态是 0 待开放或者面试流程状态是 2 待面试，就不让进
            //再判断时间是否是正确的时间
            if (roomStatus.equals(RoomStatus.WAIT_FOR_OPEN.getCode()) || WorkflowStatusEnum.INTERVIEW_2.getCode().equals(status)) {
                HyPartnerInterviewPlanDO interviewPlan = interviewPlanMapper.getInterviewPlanById(dto.getInterviewPlanId());
                //面试预期开始时间
                DateTime exceptTime = DateUtil.offsetMinute(interviewPlan.getStartTime(), -5);
                //面试结束时间
                DateTime endTime = DateUtil.parseDateTime(DateUtil.formatDateTime(interviewPlan.getEndTime()));
                DateTime now = DateUtil.date();
                //如果当前时间在预期开始时间和结束时间之间
                //修改面试状态和房间状态（修改房间状态在后面 hyPartnerInterviewPlanDO 中一并修改）
                if (exceptTime.isBefore(now) && now.isBefore(endTime)) {
                    //1. 将面试状态改为 --> 2 已开始
                    interviewDAO.updateInterviewWorkflowStatus(dto.getInterviewPlanId(), WorkflowStatusEnum.INTERVIEW_3);
                    //hyPartnerInterviewDO.setStatus(Integer.parseInt(WorkflowStatusEnum.INTERVIEW_3.getCode()));
                } else {
                    throw new ApiException(ErrorCodeEnum.ROOM_STATUS_ERROR);
                }
            }
            HyPartnerInterviewDO hyPartnerInterviewDO = new HyPartnerInterviewDO();
            hyPartnerInterviewDO.setInterviewPlanId(Long.parseLong(dto.getInterviewPlanId()));
            //2. 修改加盟商或面试官进入面试时间
            //加盟商
            if (dto.getUserType().equals(2)) {
                hyPartnerInterviewDO.setPartnerEnterTime(DateUtil.date());
            } else if (dto.getUserType().equals(1)) {
                hyPartnerInterviewDO.setInterviewerEnterTime(DateUtil.date());
            }
            //更新
            interviewMapper.updateByPrimaryKeySelective(hyPartnerInterviewDO);
            HyPartnerInterviewPlanDO hyPartnerInterviewPlanDO = new HyPartnerInterviewPlanDO();
            hyPartnerInterviewPlanDO.setId(Long.parseLong(dto.getInterviewPlanId()));
            //修改面试房间状态
            hyPartnerInterviewPlanDO.setRoomStatus(RoomStatus.OPEN.getCode());
            //3. TODO（待确认） 修改面试实际开始时间，以第一个人进来的时间为准，后续不再修改
            interviewPlanMapper.updateActualStartTime(hyPartnerInterviewPlanDO.getId(), DateUtil.now());
            //4. 加盟商如果进入了，就修改面试计划表 is_partner_interview 字段
            if (dto.getUserType().equals(2)) {
                hyPartnerInterviewPlanDO.setIsPartnerInterview(1);
            }
            interviewPlanMapper.updateByPrimaryKeySelective(hyPartnerInterviewPlanDO);
            //5. 查询对应的面试官id、姓名及加盟商姓名
            EnterInterviewVO vo = interviewMapper.getInterviewerByInterviewPlanId(dto.getInterviewPlanId());
            //6. 生成 userSign
            String userSig = TRTCUtils.genUserSig(sdkAppId, key, dto.getUserId());
            vo.setUserSign(userSig);
            return vo;
        } catch (ApiException apiException) {
            throw apiException;
        } catch (Exception e) {
            throw new ApiException(ErrorCodeEnum.INTERVIEW_ENTER_FAIL);
        }
    }

    /**
     * 获取通知函详情
     */
    @Override
    public PartnerPassLetterDetailVO passLetterDetail(String interviewPlanId) throws ApiException {
        PartnerPassLetterDetailVO vo = interviewMapper.getPassLetterDetail(interviewPlanId);
        //如果面试信息为空，抛出异常
        if (vo == null) {
            throw new ApiException(ErrorCodeEnum.INTERVIEW_PLAN_NOT_EXIST);
        }
        //解析意向开店区域为市级行政区
        String verifyCity = vo.getVerifyCity();
        String[] split = verifyCity.split("/");
        //根据长度来取市级行政区域
        if (split.length == 2) {
            vo.setVerifyCity(split[1]);
        } else if (split.length == 3) {
            vo.setVerifyCity(split[1]);
        } else if (split.length == 4) {
            vo.setVerifyCity(split[2]);
        } else {
            throw new ServiceException(ErrorCodeEnum.INTENT_INFO_NOT_EXIST);
        }
        vo.setVerifyCity((verifyCity));
        return vo;
    }

    @Override
    public void modifyInterviewTime(ModifyInterviewTimeReq request) throws ApiException {
        InterviewVO interviewInfo = interviewPlanMapper.getInterviewInfo(request.getInterviewPlanId());
        //如果面试信息为空，抛出异常
        if (interviewInfo == null) {
            throw new ApiException(ErrorCodeEnum.INTERVIEW_PLAN_NOT_EXIST);
        }
        //如果面试状态不是面试时间待审核，抛出异常
        if (interviewInfo.getStatus() != Integer.parseInt(WorkflowStatusEnum.RESERVATION_1.getCode())) {
            throw new ApiException(ErrorCodeEnum.INTERVIEW_STATUS_ERROR);
        }
        if(RoomStatus.WAIT_FOR_OPEN.getCode() != Integer.parseInt(interviewInfo.getRoomStatus())){
            throw new ApiException(ErrorCodeEnum.ROOM_STATUS_ERROR);
        }
        HyPartnerInterviewPlanDO record = new HyPartnerInterviewPlanDO();
        record.setId(Long.valueOf(request.getInterviewPlanId()));
        record.setStartTime(Convert.toDate(request.getNewStartBookingTime()));
        record.setInterviewDate(Convert.toDate(request.getNewStartBookingTime()));
        record.setEndTime(Convert.toDate(request.getNewEndBookingTime()));
        record.setUpdateTime(new Date());
        interviewPlanMapper.updateByPrimaryKeySelective(record);

        //记录日志
        PartnerUserInfoVO operator = PartnerUserHolder.getUser();
        ModifyInterviewTimeDTO log = ModifyInterviewTimeDTO.builder().mobile(operator.getMobile()).operateUserId(operator.getPartnerId()).operateUsername(operator.getUsername())
                .operateTime(DateUtil.format(new Date(), CoolDateUtils.DATE_FORMAT_SEC))
                .beforeInterviewTime(interviewInfo.getStartTime()).afterInterviewTime(request.getNewStartBookingTime()).build();
        logService.recordPartnerBizLog(operator,interviewInfo.getPartnerLineId(), OperateTypeEnum.MODIFY_INTERVIEW_TIME,log);
    }

}
