package com.cool.store.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.RedisConstant;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.context.PartnerUserHolder;
import com.cool.store.dao.*;
import com.cool.store.dto.log.AddTagsDTO;
import com.cool.store.dto.log.BlackListLogDTO;
import com.cool.store.dto.log.LineLogInfo;
import com.cool.store.dto.log.WantInfoUpdateDTO;
import com.cool.store.entity.*;
import com.cool.store.enums.*;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.HyPartnerCertificationInfoMapper;
import com.cool.store.request.AddTagsRequest;
import com.cool.store.request.PartnerBaseInfoRequest;
import com.cool.store.service.HyPartnerBaseInfoService;
import com.cool.store.service.HyPartnerLineInfoService;
import com.cool.store.service.HyPhoneLocationService;
import com.cool.store.service.LogService;
import com.cool.store.utils.CoolDateUtils;
import com.cool.store.utils.RedisUtilPool;
import com.cool.store.vo.PartnerBaseInfoVO;
import com.cool.store.vo.PartnerUserInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.Date;

/**
 * @Author suzhuhong
 * @Date 2023/6/13 21:37
 * @Version 1.0
 */
@Service
@Slf4j
public class HyPartnerBaseInfoServiceImpl implements HyPartnerBaseInfoService {

    @Resource
    HyPartnerBaseInfoDAO hyPartnerBaseInfoDAO;

    @Resource
    HyPartnerLineInfoService hyPartnerLineInfoService;

    @Resource
    HyPartnerLineInfoDAO hyPartnerLineInfoDAO;

    @Resource
    HyPartnerUserInfoDAO hyPartnerUserInfoDAO;

    @Resource
    private RedisUtilPool redisUtilPool;

    @Resource
    HyPartnerTaskInfoLogDAO hyPartnerTaskInfoLogDAO;
    @Resource
    HyPhoneLocationService hyPhoneLocationService;
    @Resource
    HyPartnerIntentInfoDAO hyPartnerIntentInfoDAO;

    @Resource
    HyInterviewDAO hyInterviewDAO;

    @Resource
    HyPartnerInterviewPlanDAO hyPartnerInterviewPlanDAO;

    @Resource
    HyPartnerClerkDAO hyPartnerClerkDAO;

    @Resource
    HyPartnerCertificationInfoMapper hyPartnerCertificationInfoMapper;

    @Autowired
    private LogService logService;


    @Override
    public Boolean addTags(LoginUserInfo user, AddTagsRequest addTagsRequest) {
        HyPartnerBaseInfoDO hyPartnerBaseInfo = hyPartnerBaseInfoDAO.selectById(addTagsRequest.getPartnerBaseInfoId());
        if (hyPartnerBaseInfo==null){
            throw new ServiceException(ErrorCodeEnum.PARTNER_BASE_INFO_NOT_EXIST);
        }
        hyPartnerBaseInfo.setId(addTagsRequest.getPartnerBaseInfoId());
        hyPartnerBaseInfo.setUserPortrait(CollectionUtils.isNotEmpty(addTagsRequest.getTags())? JSONObject.toJSONString(addTagsRequest.getTags()):"");
        hyPartnerBaseInfoDAO.updateByPrimaryKeySelective(hyPartnerBaseInfo);
        HyPartnerLineInfoDO line = hyPartnerLineInfoDAO.getByPartnerId(hyPartnerBaseInfo.getPartnerId());
        //添加日志
        LineLogInfo lineLogInfo = new LineLogInfo(line.getPartnerId(), line.getId(), user.getUserId(),
                user.getName(), OperateTypeEnum.ADD_TAGS,
                WorkflowStageEnum.getWorkflowStageByCode(line.getWorkflowStage()),
                line.getWorkflowStatus(), "");
        AddTagsDTO logDTO = AddTagsDTO.builder().operateUserId(user.getUserId()).operateUsername(user.getName())
                .mobile(user.getMobile()).operateTime(DateUtil.format(new Date(), CoolDateUtils.DATE_FORMAT_SEC_2)).build();
        lineLogInfo.setData(logDTO);
        hyPartnerTaskInfoLogDAO.addOperateLog(lineLogInfo);
        return Boolean.TRUE;
    }

    /**
     * //前提 未提交加盟申请
     * //成功 意向区域变更成功  失败 您已进入意向申请流程，当前不可变更意向区域
     * @param request
     * @return
     */
    @Override
    public Boolean submitPartnerBaseInfo(PartnerBaseInfoRequest request, PartnerUserInfoVO currentUser) {
        log.info("HyPartnerBaseInfoServiceImpl#submitPartnerBaseInfo request:{}", JSONObject.toJSONString(request));

        String cacheKey = MessageFormat.format(RedisConstant.PARTNER_BASEINFO_CACHE_KEY, request.getPartnerId(), request.getPartnerLineId());
        if(!request.getSubmitFlag()){
            // 自动保存时
            redisUtilPool.setString(cacheKey, JSONObject.toJSONString(request), RedisConstant.ONE_DAY_SECONDS);
            return Boolean.TRUE;
        }
        WantInfoUpdateDTO.BaseInfoUpdate beforeBaseInfoUpdate = new WantInfoUpdateDTO.BaseInfoUpdate();
        WantInfoUpdateDTO.BaseInfoUpdate afterBaseInfoUpdate = new WantInfoUpdateDTO.BaseInfoUpdate();
        OperateTypeEnum operateTypeEnum = OperateTypeEnum.INTENT_INFO_UPDATE;

        HyPartnerBaseInfoDO baseInfoDO = hyPartnerBaseInfoDAO.getByPartnerIdAndLineId(request.getPartnerId(), request.getPartnerLineId());
        if(baseInfoDO == null){
            baseInfoDO = new HyPartnerBaseInfoDO();
            fillBaseInfo(baseInfoDO, request);
            hyPartnerBaseInfoDAO.insertSelective(baseInfoDO);
            BeanUtil.copyProperties(baseInfoDO, afterBaseInfoUpdate);
            operateTypeEnum = OperateTypeEnum.INTENT_INFO_SUBMIT;
        }else {
            BeanUtil.copyProperties(baseInfoDO, beforeBaseInfoUpdate);
            fillBaseInfo(baseInfoDO, request);
            hyPartnerBaseInfoDAO.updateByPrimaryKeySelective(baseInfoDO);
            BeanUtil.copyProperties(baseInfoDO, afterBaseInfoUpdate);
        }
        if(request.getSubmitFlag()){
            // 更新线索表状态
            HyPartnerLineInfoDO hyPartnerLineInfoDO = hyPartnerLineInfoDAO.selectByPrimaryKeySelective(request.getPartnerLineId());
            hyPartnerLineInfoDO.setWorkflowStatus(WorkflowStatusEnum.INTENT_1.getCode());
            hyPartnerLineInfoDAO.updateByPrimaryKeySelective(hyPartnerLineInfoDO);
            // 更新意向基本信息表状态
            HyPartnerBaseInfoDO hyPartnerBaseInfoDO = hyPartnerBaseInfoDAO.getByPartnerIdAndLineId(request.getPartnerId(), request.getPartnerLineId());
            hyPartnerBaseInfoDO.setStatus(Integer.valueOf(WorkflowStatusEnum.INTENT_1.getCode()));
            hyPartnerBaseInfoDAO.updateByPrimaryKeySelective(hyPartnerBaseInfoDO);

            HyPartnerUserInfoDO hyPartnerUserInfoDO = hyPartnerUserInfoDAO.selectByPartnerId(request.getPartnerId());
            if(!hyPartnerUserInfoDO.getUsername().equals(request.getUsername())){
                hyPartnerUserInfoDO.setUsername(request.getUsername());
                hyPartnerUserInfoDAO.updateByPrimaryKeySelective(hyPartnerUserInfoDO);
            }

            HyPartnerTaskInfoLogDO logDO = new  HyPartnerTaskInfoLogDO(request.getPartnerId(), request.getPartnerLineId(), WorkflowStageEnum.INTENT.getCode(), WorkflowStatusEnum.INTENT_1.getCode(), currentUser.getPartnerId(), currentUser.getUsername(), null);

           //  hyPartnerTaskInfoLogDAO.insertSelective(logDO);
        }
        // 清空暂存信息
        redisUtilPool.delKey(cacheKey);
        //记录日志
        PartnerUserInfoVO operator = PartnerUserHolder.getUser();
        WantInfoUpdateDTO log = WantInfoUpdateDTO.builder().mobile(operator.getMobile()).operateUserId(operator.getPartnerId()).operateUsername(operator.getUsername())
                .operateTime(DateUtil.format(new Date(), CoolDateUtils.DATE_FORMAT_SEC))
                .beforeBaseInfoUpdate(beforeBaseInfoUpdate).afterBaseInfoUpdate(afterBaseInfoUpdate).build();
        logService.recordPartnerBizLog(operator, baseInfoDO.getPartnerLineId(), operateTypeEnum,log);
        return Boolean.TRUE;
    }

    @Override
    public PartnerBaseInfoVO queryPartnerBaseInfo(String partnerId, Long lineId) {
        String cacheKey = MessageFormat.format(RedisConstant.PARTNER_BASEINFO_CACHE_KEY, partnerId, lineId);
        if (StringUtils.isNotBlank(redisUtilPool.getString(cacheKey))) {
            PartnerBaseInfoVO partnerBaseInfoVO = JSONObject.parseObject(redisUtilPool.getString(cacheKey), PartnerBaseInfoVO.class);
            return partnerBaseInfoVO;
        }
        HyPartnerBaseInfoDO hyPartnerBaseInfoDO = hyPartnerBaseInfoDAO.getByPartnerIdAndLineId(partnerId, lineId);
        PartnerBaseInfoVO baseInfoVO = new PartnerBaseInfoVO();
        if (hyPartnerBaseInfoDO != null){
            BeanUtil.copyProperties(hyPartnerBaseInfoDO, baseInfoVO);
        }
        return baseInfoVO;
    }

    @Override
    public PartnerBaseInfoVO getByPartnerLineId(Long lineId) {
        HyPartnerBaseInfoDO hyPartnerBaseInfoDO = hyPartnerBaseInfoDAO.getByPartnerLineId(lineId);
        if (hyPartnerBaseInfoDO == null){
            throw new ServiceException(ErrorCodeEnum.PARTNER_BASEINFO_NOT_EXIST);
        }
        PartnerBaseInfoVO baseInfoVO = new PartnerBaseInfoVO();
        BeanUtil.copyProperties(hyPartnerBaseInfoDO, baseInfoVO);
        return baseInfoVO;
    }

    @Override
    public HyPartnerBaseInfoDO getByIdCard(String idCard) {
        return hyPartnerBaseInfoDAO.getByIdCard(idCard);
    }

    @Override
    public Boolean changeBinding(String idCard, Long lineId, PartnerUserInfoVO currentUser) {
        // 把旧线索的身份证号置空，状态改为待提交
        HyPartnerBaseInfoDO oldBaseInfo = hyPartnerBaseInfoDAO.getByIdCard(idCard);
        HyPartnerLineInfoDO oldLineInfo = hyPartnerLineInfoDAO.selectByPrimaryKeySelective(oldBaseInfo.getPartnerLineId());
        HyPartnerUserInfoDO oldPartnerUser = hyPartnerUserInfoDAO.selectByPartnerId(oldBaseInfo.getPartnerId());
        // 该身份证当前申请状态同步至该账号下，原账号变为【加盟意向申请 待提交状态】
        HyPartnerLineInfoDO newLineInfo =  hyPartnerLineInfoDAO.selectByPrimaryKeySelective(lineId);
        Long newLindId = newLineInfo.getId();
        String newPartnerId = newLineInfo.getPartnerId();
        BeanUtil.copyProperties(oldLineInfo,newLineInfo,"createTime","updateTime","id","deleted");
        newLineInfo.setId(newLindId);
        newLineInfo.setPartnerId(newPartnerId);
        hyPartnerLineInfoDAO.updateByPrimaryKeySelective(newLineInfo);
        cleanOldLineInfo(oldLineInfo);
        hyPartnerLineInfoDAO.updateByPrimaryKey(oldLineInfo);
        // 新线索绑定身份证号
        HyPartnerBaseInfoDO newBaseInfo = hyPartnerBaseInfoDAO.getByPartnerIdAndLineId(currentUser.getPartnerId(), lineId);
        fillBaseInfoIdCard(newBaseInfo, oldBaseInfo.getIdCard(), oldBaseInfo.getIdCardPhotoFront(), oldBaseInfo.getIdCardPhotoBlack(), oldBaseInfo.getUsername(),
                oldBaseInfo.getSex(), oldBaseInfo.getBirthdate(), oldBaseInfo.getNation(), oldBaseInfo.getLiveAddress(), oldBaseInfo.getStatus());
        newBaseInfo.setStatus(oldBaseInfo.getStatus());
        hyPartnerBaseInfoDAO.updateByPrimaryKeySelective(newBaseInfo);
        //修改名称
        HyPartnerUserInfoDO hyPartnerUserInfoDO = hyPartnerUserInfoDAO.selectByPartnerId(newPartnerId);
        HyPartnerIntentInfoDO oldIntentInfo = hyPartnerIntentInfoDAO.getByPartnerIdAndLineId(oldLineInfo.getPartnerId(), oldLineInfo.getId());
        if(!hyPartnerUserInfoDO.getUsername().equals(oldBaseInfo.getUsername()) || !hyPartnerUserInfoDO.getWantShopArea().equals(oldIntentInfo.getWantShopArea())
                || !hyPartnerUserInfoDO.getAcceptAdjustType().equals(oldIntentInfo.getAcceptAdjustType())){
            hyPartnerUserInfoDO.setUsername(oldBaseInfo.getUsername());
            hyPartnerUserInfoDO.setWantShopArea(oldIntentInfo.getWantShopArea());
            hyPartnerUserInfoDO.setAcceptAdjustType(oldIntentInfo.getAcceptAdjustType());

        }
        hyPartnerUserInfoDO.setRecommendPartnerId(oldPartnerUser.getRecommendPartnerId());
        hyPartnerUserInfoDO.setRecommendPartnerName(oldPartnerUser.getRecommendPartnerName());
        hyPartnerUserInfoDO.setRecommendPartnerMobile(oldPartnerUser.getRecommendPartnerMobile());
        hyPartnerUserInfoDO.setShopCode(oldPartnerUser.getShopCode());
        hyPartnerUserInfoDO.setShopName(oldPartnerUser.getShopName());
        hyPartnerUserInfoDO.setShopId(oldPartnerUser.getShopId());
        hyPartnerUserInfoDAO.updateByPrimaryKeySelective(hyPartnerUserInfoDO);
        // 老的身份证信息置空
        fillBaseInfoIdCard(oldBaseInfo, null, null, null, null, null, null, null, null, null);
        oldBaseInfo.setStatus(Integer.valueOf(WorkflowStatusEnum.INTENT_0.getCode()));
        hyPartnerBaseInfoDAO.updateByPrimaryKey(oldBaseInfo);
        hyPartnerIntentInfoDAO.updateLineId(newPartnerId,newLindId,oldLineInfo.getId());
        hyPartnerClerkDAO.updateLineId(newPartnerId,newLindId,oldLineInfo.getId());
        hyPartnerInterviewPlanDAO.updateLineId(newPartnerId,newLindId,oldLineInfo.getId());
        hyInterviewDAO.updateLineId(newPartnerId,newLindId,oldLineInfo.getId());
        hyPartnerCertificationInfoMapper.updateLineId(newPartnerId,newLindId,oldLineInfo.getId());
        hyPartnerTaskInfoLogDAO.updateLineId(newPartnerId,newLindId,oldLineInfo.getId());
        String cacheKeyBaseInfo = MessageFormat.format(RedisConstant.PARTNER_BASEINFO_CACHE_KEY, newPartnerId, newLindId);
        String cacheKeyClerkInfo = MessageFormat.format(RedisConstant.PARTNER_CLERKINFO_CACHE_KEY,newPartnerId, newLindId);
        String cacheKeyIntentInfo = MessageFormat.format(RedisConstant.PARTNER_INTENTINFO_CACHE_KEY, newPartnerId, newLindId);
        redisUtilPool.delKey(cacheKeyBaseInfo);
        redisUtilPool.delKey(cacheKeyClerkInfo);
        redisUtilPool.delKey(cacheKeyIntentInfo);
        return true;
    }

    private void cleanOldLineInfo(HyPartnerLineInfoDO oldLineInfo) {
        oldLineInfo.setWorkflowStage(WorkflowStageEnum.INTENT.getCode());
        oldLineInfo.setWorkflowStatus(WorkflowStatusEnum.INTENT_0.getCode());
        oldLineInfo.setLineStatus(LineStatusEnum.PUBLIC_SEAS.getCode());
        oldLineInfo.setInvestmentManager(null);
        oldLineInfo.setDevelopmentDirector(null);
        oldLineInfo.setDevelopmentManager(null);
        oldLineInfo.setDeadline(null);
        oldLineInfo.setPassReason(null);
        oldLineInfo.setRejectPublicReason(null);
        oldLineInfo.setRejectRealReason(null);
        oldLineInfo.setCertifyFile(null);
        oldLineInfo.setCloseTime(null);
        oldLineInfo.setCloseUserId(null);
        oldLineInfo.setJoinBlackReason(null);
        oldLineInfo.setRemoveBlackReason(null);
    }

    @Override
    public HyPartnerBaseInfoDO generateBaseInfo(HyPartnerUserInfoDO hyPartnerUserInfoDO, Long partnerLineId, String userPortrait) {
        HyPartnerBaseInfoDO hyPartnerBaseInfoDO = hyPartnerBaseInfoDAO.getByPartnerIdAndLineId(hyPartnerUserInfoDO.getPartnerId(), partnerLineId);
        if(hyPartnerBaseInfoDO == null){
            hyPartnerBaseInfoDO = new HyPartnerBaseInfoDO();
            hyPartnerBaseInfoDO.setPartnerId(hyPartnerUserInfoDO.getPartnerId());
            hyPartnerBaseInfoDO.setPartnerLineId(partnerLineId);
            hyPartnerBaseInfoDO.setMobile(hyPartnerUserInfoDO.getMobile());
            hyPartnerBaseInfoDO.setUsername(hyPartnerUserInfoDO.getUsername());
            hyPartnerBaseInfoDO.setStatus(Integer.valueOf(WorkflowStatusEnum.INTENT_0.getCode()));
            hyPartnerBaseInfoDO.setSex(1);
            if(StringUtils.isNotBlank(userPortrait)){
                hyPartnerBaseInfoDO.setUserPortrait(userPortrait);
            }
            hyPartnerBaseInfoDAO.insertSelective(hyPartnerBaseInfoDO);
        }
        return  hyPartnerBaseInfoDO;
    }

    private void fillBaseInfoIdCard(HyPartnerBaseInfoDO newBaseInfo, String idCard, String idCardPhotoFront, String idCardPhotoBlack,
                                    String username, Integer sex, Date birthdate, String nation, String liveAddress, Integer status) {
        newBaseInfo.setIdCard(idCard);
        newBaseInfo.setIdCardPhotoBlack(idCardPhotoFront);
        newBaseInfo.setIdCardPhotoFront(idCardPhotoBlack);
        newBaseInfo.setUsername(username);
        newBaseInfo.setSex(sex);
        newBaseInfo.setBirthdate(birthdate);
        newBaseInfo.setNation(nation);
        newBaseInfo.setLiveAddress(liveAddress);
        newBaseInfo.setStatus(status);
    }

    private void fillBaseInfo(HyPartnerBaseInfoDO baseInfoDO, PartnerBaseInfoRequest request) {
        baseInfoDO.setPartnerId(request.getPartnerId());
        baseInfoDO.setPartnerLineId(request.getPartnerLineId());
        baseInfoDO.setMobile(request.getMobile());
        baseInfoDO.setUsername(request.getUsername());
        baseInfoDO.setSex(request.getSex());
        baseInfoDO.setNation(request.getNation());
        baseInfoDO.setBirthdate(request.getBirthdate());
        baseInfoDO.setIdCard(request.getIdCard());
        baseInfoDO.setIdCardPhotoFront(request.getIdCardPhotoFront());
        baseInfoDO.setIdCardPhotoBlack(request.getIdCardPhotoBlack());
        baseInfoDO.setLiveAddress(request.getLiveAddress());
    }
}
