package com.cool.store.service.impl;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.CommonConstants;
import com.cool.store.constants.RedisConstant;
import com.cool.store.constants.DictConstants;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.*;
import com.cool.store.dao.fees.WalletPayInfoDAO;
import com.cool.store.dao.order.PreAllocationRecordDAO;
import com.cool.store.dto.ContractInformationDTO;
import com.cool.store.dao.decoration.DecorationTeamConfigDAO;
import com.cool.store.dao.decoration.ShopDecorationAssignDAO;
import com.cool.store.dao.decoration.TeamAreaMappingDAO;
import com.cool.store.dto.PartnerBankInfoDTO;
import com.cool.store.dto.contract.ContractCallbackDTO;
import com.cool.store.dto.contract.PushContractDTO;
import com.cool.store.entity.*;
import com.cool.store.entity.decoration.DecorationTeamConfigDO;
import com.cool.store.entity.decoration.ShopDecorationAssignDO;
import com.cool.store.entity.decoration.TeamAreaMappingDO;
import com.cool.store.entity.fees.WalletPayInfoDO;
import com.cool.store.entity.order.PreAllocationRecordDO;
import com.cool.store.enums.*;
import com.cool.store.enums.Decoration.DecorationDescStatus;
import com.cool.store.enums.fees.AllocationPayStatusEnum;
import com.cool.store.enums.fees.PayTypeEnum;
import com.cool.store.enums.Decoration.DecorationUseSystemEnum;
import com.cool.store.enums.point.ShopSubStageEnum;
import com.cool.store.enums.point.ShopSubStageStatusEnum;
import com.cool.store.enums.wallet.WalletTradeModuleEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.*;
import com.cool.store.mq.producer.SimpleMessageService;
import com.cool.store.request.*;
import com.cool.store.response.AddSignFranchiseResponse;
import com.cool.store.response.ResponseResult;
import com.cool.store.service.*;
import com.cool.store.service.dict.impl.DictService;
import com.cool.store.utils.GeoMapUtil;
import com.cool.store.utils.RedisUtilPool;
import com.cool.store.utils.poi.DateUtils;
import com.cool.store.utils.poi.StringUtils;
import com.cool.store.utils.poi.constant.Constants;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.protobuf.StringValue;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.font.Decoration;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.cool.store.enums.UserRoleEnum.*;
import static com.cool.store.enums.point.ShopSubStageStatusEnum.*;
import static com.cool.store.utils.CommonUtil.convertToBig;

@Service
@Slf4j
public class SignFranchiseServiceImpl implements SignFranchiseService, AuditResultService {

    private static final BigDecimal STANDARD_TOTAL_AMOUNT = new BigDecimal("63200");

    @Resource
    private BigRegionDAO bigRegionDAO;
    @Resource
    private ShopInfoDAO shopInfoDAO;
    @Resource
    private LineInfoDAO lineInfoDAO;
    @Resource
    private EnterpriseUserDAO enterpriseUserDAO;
    @Resource
    private HqtAPIService hqtAPIService;
    @Resource
    private RegionDao regionDao;
    @Resource
    private PointInfoDAO pointInfoDAO;
    @Resource
    private EnterpriseUserRoleDao enterpriseUserRoleDao;
    @Resource
    SignFranchiseMapper signFranchiseMapper;
    @Resource
    SignFranchiseDAO signFranchiseDAO;

    @Resource
    UserAuthMappingService userAuthMappingService;

    @Resource
    FranchiseFeeMapper franchiseFeeMapper;

    @Resource
    ShopInfoMapper shopInfoMapper;

    @Resource
    IntentAgreementMapper intentAgreementMapper;

    @Resource
    LinePayMapper linePayMapper;

    @Resource
    PointInfoMapper pointInfoMapper;

    @Resource
    LineInfoMapper lineInfoMapper;

    @Resource
    SystemBuildingShopMapper systemBuildingShopMapper;

    @Resource
    ApplyLicenseMapper applyLicenseMapper;

    @Resource
    ThirdDepartmentMapper thirdDepartmentMapper;

    @Resource
    JoinIntentionMapper joinIntentionMapper;

    @Resource
    ShopStageInfoDAO shopStageInfoDAO;

    @Resource
    ShopAuditInfoMapper shopAuditInfoMapper;

    @Resource
    PreparationService preparationService;

    @Resource
    CommonService commonService;

    @Resource
    RedisUtilPool redisUtilPool;
    @Resource
    QualificationsInfoDAO qualificationsInfoDAO;

    @Resource
    RegionMapper regionMapper;

    @Resource
    private OrderSysInfoDAO orderSysInfoDAO;
    @Resource
    OperationLogService operationLogService;
    @Resource
    OperationLogDAO operationLogDAO;
    @Resource
    ContractConfigDAO contractConfigDAO;
    @Resource
    PushService pushService;
    @Resource
    TeamAreaMappingDAO teamAreaMappingDAO;
    @Resource
    DecorationTeamConfigDAO decorationTeamConfigDAO;
    @Resource
    ShopDecorationAssignDAO shopDecorationAssignDAO;
    @Resource
    private SimpleMessageService simpleMessageService;
    @Resource
    private OperationsConsultantAssignDAO operationsConsultantAssignDAO;
    @Resource
    private DictService dictService;
    @Resource
    private WalletPayInfoDAO walletPayInfoDAO;
    @Resource
    private SignFranchiseService signFranchiseService;
    @Resource
    private PreAllocationRecordDAO preAllocationRecordDAO;


    @Override
    public Boolean auditResult(AuditResultRequest request) {
        log.info("SignFranchiseServiceImpl auditResult request：{}", JSONObject.toJSONString(request));
//        Long shopId = getShopId(request.getKdzBusinessId());
//        ShopSubStageStatusEnum shopSubStageStatusEnum = null;
//        if (request.getAuditResult() == 1) {
//            shopSubStageStatusEnum = SHOP_SUB_STAGE_STATUS_84;
//        } else if (request.getAuditResult() == 0) {
//            shopSubStageStatusEnum = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_85;
//        }
//        ShopAuditInfoDO shopAuditInfoDO = new ShopAuditInfoDO();
//        shopAuditInfoDO.setShopId(shopId);
//        shopAuditInfoDO.setAuditType(AuditTypeEnum.SIGN_FRANCHISE.getCode());
//        shopAuditInfoDO.setSubmittedUserId("");
//        shopAuditInfoDO.setSubmittedUserName("");
//        if (Constants.ZERO_INTEGER.equals(request.getAuditResult())) {
//            shopAuditInfoDO.setResultType(Constants.ONE_INTEGER);
//            shopAuditInfoDO.setRejectReason(request.getCause());
//            Map<String, String> requestMap = new HashMap<>();
//            ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(shopId);
//            LineInfoDO lineInfo = lineInfoMapper.getByLineId(shopInfoDO.getLineId());
//            requestMap.put("storeName", shopInfoDO.getShopName());
//            requestMap.put("partnerName", lineInfo.getUsername());
//            requestMap.put("partnerMobile", lineInfo.getMobile());
//            requestMap.put("lineId", String.valueOf(lineInfo.getId()));
//            requestMap.put("shopId", String.valueOf(shopInfoDO.getId()));
//            commonService.sendMessage(Collections.singletonList(lineInfo.getInvestmentManager()), MessageEnum.MESSAGE_20, requestMap);
//        } else if (Constants.ONE_INTEGER.equals(request.getAuditResult())) {
//            shopAuditInfoDO.setResultType(Constants.ZERO_INTEGER);
//            shopAuditInfoDO.setPassReason(request.getCause());
//            //校验建店与加盟签约合同是否完成 并初始化后续流程数据
//            //preparationService.contractAndBuildStoreCompletion(shopId);
//        }
//        shopAuditInfoMapper.insertSelective(shopAuditInfoDO);
//        Long auditId = shopAuditInfoDO.getId();
//        shopStageInfoDAO.updateShopStageAndAuditInfo(shopId, shopSubStageStatusEnum, auditId);
        //signFranchiseMapper.updateAuditByShopId(auditId, shopId);
        return true;
    }

    private Long getShopId(String kdzBusinessId) {
        String shopId = kdzBusinessId.substring(kdzBusinessId.indexOf("_") + 1, kdzBusinessId.lastIndexOf("_"));
        return Long.valueOf(shopId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult submitSignFranchise(AddSignFranchiseRequest request, LoginUserInfo user) {
        log.info("submitSignFranchise request:{}", JSONObject.toJSONString(request));
        if (Objects.isNull(request)) {
            throw new ServiceException(ErrorCodeEnum.PARAMS_VALIDATE_ERROR);
        }
        if (Objects.isNull(request.getShopId())) {
            throw new ServiceException(ErrorCodeEnum.SHOP_ID_NOT_EXIST);
        }
        //不要使用系统默认名称
        if (StringUtils.isNotEmpty(request.getShopName())&&request.getShopName().matches("^店铺.$")) {
            throw new ServiceException(ErrorCodeEnum.SYSTEM_NAME_NOT__SUPPORT);
        }
        //校验金额
        if (!feeCheck(request)){
            throw new ServiceException(ErrorCodeEnum.FEE_NOT_CONSISTENT);
        }
        SignFranchiseDO isExist = signFranchiseMapper.selectByShopId(request.getShopId());
        if (Objects.nonNull(isExist) && Objects.isNull(request.getId())) {
            throw new ServiceException(ErrorCodeEnum.DUPLICATE_SUBMISSION);
        }
        // 正新鸡排校验字段
        verifyParams(request);
        ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(request.getShopId());
        PointInfoDO pointInfoById = pointInfoDAO.getPointInfoById(shopInfoDO.getPointId());
        FranchiseFeeDO franchiseFeeDO = franchiseFeeMapper.selectByShopId(request.getShopId());
        if (franchiseFeeDO!=null){
            franchiseFeeDO.setFirstYearStartTime(request.getFirstYearStartTime());
            franchiseFeeDO.setFirstYearEndTime(request.getFirstYearEndTime());
            franchiseFeeMapper.updateByPrimaryKeySelective(franchiseFeeDO);
        }
        String lockKey = "submitSignFranchise:" + request.getShopId();
        //流水
        String lockValue = UUID.randomUUID().toString();
        boolean acquired = false;
        try {
            //10s过期
            acquired = redisUtilPool.setNxExpire(lockKey, lockValue, CommonConstants.TEN_SECONDS);
            if (Boolean.TRUE.equals(acquired)) {
                //修改shop & point
                updateShopAndPoint(request, shopInfoDO, pointInfoById);

                SignFranchiseDO signFranchiseDO = request.toSignFranchiseDO();
                if (Objects.isNull(request.getId())) {
                    signFranchiseDO.setCreateUserId(user.getUserId());
                    signFranchiseMapper.insertSelective(signFranchiseDO);
                    shopStageInfoDAO.updateShopStageInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_83);
                    //发送通知
                    List<EnterpriseUserDO> auditFranchiseFeeUsers = userAuthMappingService.getUserIdByRoleEnumAndRegionId(Arrays.asList(BRANCH_OFFICE, REGION_OFFICE), shopInfoDO.getInvestRegionId());
                    List<String> auditFranchiseFeeUserList = auditFranchiseFeeUsers.stream().distinct().map(EnterpriseUserDO::getUserId).collect(Collectors.toList());
                    LineInfoDO lineInfo = lineInfoMapper.getByLineId(shopInfoDO.getLineId());
                    HashMap<String, String> map = new HashMap<>();
                    map.put("partnerUsername", lineInfo.getUsername());
                    map.put("partnerMobile", lineInfo.getMobile());
                    map.put("storeName", shopInfoDO.getShopName());
                    commonService.sendQWMessage(auditFranchiseFeeUserList,
                            MessageEnum.MESSAGE_19_1,
                            map);
                    operationLogService.addOperationLog(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_80, user.getUserId(), user.getName(),
                            OperationTypeEnum.OPERATION_TYPE_0, "加盟签约合同提交", OperationStatusEnum.PROCESSED);
                    operationLogService.addOperationLog(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_83,
                            user.getUserId(), auditFranchiseFeeUsers,
                            OperationTypeEnum.OPERATION_TYPE_1, "加盟签约合同审批", OperationStatusEnum.NOT_PROCESSED, 1);
                } else {
                    //修改签约人信息
                    signFranchiseMapper.updateByPrimaryKeySelective(signFranchiseDO);
                    //如果已经签约 修改之后从新推送数据到新管家
                    ShopStageInfoDO shopSubStageInfo = shopStageInfoDAO.getShopSubStageInfo(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_8);
                    if (shopSubStageInfo.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_84.getShopSubStageStatus())){
                        //如果已经签约 修改之后从新推送数据
                        ContractCallbackDTO contractCallbackDTO = pushContractRequest(shopInfoDO, request.getShopId());
                        if (!Objects.isNull(contractCallbackDTO)){
                            if (StringUtils.isNoneEmpty(contractCallbackDTO.getStoreCode())&&StringUtils.isBlank(shopInfoDO.getShopCode())){
                                shopInfoDO.setShopCode(contractCallbackDTO.getStoreCode());
                                shopInfoDAO.updateShopInfo(shopInfoDO);
                            }
                            signFranchiseDAO.updateAuditByShopId(null, request.getShopId(),contractCallbackDTO);
                        }

                    }
                }

                return new ResponseResult(200000, "提交成功");
            } else {
                throw new ServiceException(ErrorCodeEnum.DUPLICATE_SUBMISSION);
            }

        } finally {
            if (Boolean.TRUE.equals(acquired)) {
                String currentValue = redisUtilPool.getString(lockKey);
                if (lockValue.equals(currentValue)) {
                    redisUtilPool.delKey(lockKey);
                }
            }
        }

    }

    public void verifyParams(AddSignFranchiseRequest request) {
        // 正新鸡排校验字段
        if (String.valueOf(FranchiseBrandEnum.ZXJP.getCode()).equals(request.getFranchiseBrand())) {
            if (Objects.isNull(request.getChickenAmount())) {
                throw new ServiceException(ErrorCodeEnum.ERROR_MESSAGE, "鸡排价格不能为空");
            }
            if (BigDecimal.valueOf(10).compareTo(request.getChickenAmount()) != 0 && StringUtils.isBlank(request.getChickenInstruction())) {
                throw new ServiceException(ErrorCodeEnum.ZXJP_AMOUNT_INSTRUCTION_IS_BLANK);
            }
            if (Objects.isNull(request.getShopDecorationAttributes())) {
                throw new ServiceException(ErrorCodeEnum.ERROR_MESSAGE, "门店装修属性不能为空");
            }
            if (StringUtils.isBlank(request.getDecorationLevel())) {
                throw new ServiceException(ErrorCodeEnum.ERROR_MESSAGE, "门店装修等级不能为空");
            }
            if (StringUtils.isBlank(request.getDecorationRequirement())) {
                throw new ServiceException(ErrorCodeEnum.ERROR_MESSAGE, "门店装修要求不能为空");
            }
            // 门店类型为‘普通门店’或装修设计要求不为‘统一装修设计’时，特殊情况说明必填
            if (StringUtils.isBlank(request.getSpecialInstruction()) && (Integer.valueOf(2).equals(request.getStoreType()) || !DictConstants.DECORATION_REQUIREMENT_UNIFORM.equals(request.getDecorationRequirement()))) {
                throw new ServiceException(ErrorCodeEnum.ERROR_MESSAGE, "特殊情况说明不能为空");
            }
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean reSubmitSignFranchise(AddSignFranchiseRequest request, LoginUserInfo user) {
        log.info("reSubmitSignFranchise request:{}", JSONObject.toJSONString(request));
        if (Objects.isNull(request)) {
            throw new ServiceException(ErrorCodeEnum.PARAMS_VALIDATE_ERROR);
        }
        if (Objects.isNull(request.getShopId())) {
            throw new ServiceException(ErrorCodeEnum.SHOP_ID_NOT_EXIST);
        }
        //校验金额
        if (!feeCheck(request)){
            throw new ServiceException(ErrorCodeEnum.FEE_NOT_CONSISTENT);
        }
        // 正新鸡排校验字段
        verifyParams(request);
        ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(request.getShopId());
        PointInfoDO pointInfoById = pointInfoDAO.getPointInfoById(shopInfoDO.getPointId());
        FranchiseFeeDO franchiseFeeDO = franchiseFeeMapper.selectByShopId(request.getShopId());
        if (franchiseFeeDO!=null){
            franchiseFeeDO.setFirstYearStartTime(request.getFirstYearStartTime());
            franchiseFeeDO.setFirstYearEndTime(request.getFirstYearEndTime());
            franchiseFeeMapper.updateByPrimaryKeySelective(franchiseFeeDO);
        }
        SignFranchiseDO signFranchiseDO = request.toSignFranchiseDO();
        //修改信息
        signFranchiseMapper.updateByPrimaryKeySelective(signFranchiseDO);
        // //修改shop & point & 同步建店资料地址
        updateShopAndPoint(request, shopInfoDO, pointInfoById);
        //修改阶段状态
        shopStageInfoDAO.updateShopStageInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_83);
        //发送通知
        List<EnterpriseUserDO> userIds = userAuthMappingService.getUserIdByRoleEnumAndRegionId(Arrays.asList(BRANCH_OFFICE, REGION_OFFICE), shopInfoDO.getInvestRegionId());
       List<String> auditFranchiseFeeUserList = userIds.stream().distinct().map(EnterpriseUserDO::getUserId).collect(Collectors.toList());
        LineInfoDO lineInfo = lineInfoMapper.getByLineId(shopInfoDO.getLineId());
        HashMap<String, String> map = new HashMap<>();
        map.put("partnerUsername", lineInfo.getUsername());
        map.put("partnerMobile", lineInfo.getMobile());
        map.put("storeName", shopInfoDO.getShopName());
        commonService.sendQWMessage(auditFranchiseFeeUserList,
                MessageEnum.MESSAGE_19_1,
                map);
        //新增审批记录
        operationLogService.addOperationLog(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_80, user.getUserId(), user.getName(),
                OperationTypeEnum.OPERATION_TYPE_0, "加盟签约合同重新提交提交", OperationStatusEnum.PROCESSED);
        operationLogService.addOperationLog(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_83,
                user.getUserId(), userIds,
                OperationTypeEnum.OPERATION_TYPE_1, "加盟签约合同审批", OperationStatusEnum.NOT_PROCESSED, 1);
        return Boolean.TRUE;
    }

    @Override
    public Boolean decorationUpdate(SignFranchiseDecorationRequest request) {
        ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(request.getShopId());
        if (Objects.isNull(shopInfo)) {
            throw new ServiceException(ErrorCodeEnum.SHOP_NOT_EXIST);
        }
        ShopStageInfoDO shopStageInfo = shopStageInfoDAO.getShopSubStageInfo(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_9);
        if (shopStageInfo.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_91.getShopSubStageStatus())) {
            throw new ServiceException(ErrorCodeEnum.SHOP_STAGE_NOT_OPERATE);
        }
        ShopInfoDO update = new ShopInfoDO();
        update.setId(request.getShopId());
        update.setDecorationRequirement(request.getDecorationRequirement());
        update.setSpecialInstruction(request.getSpecialInstruction());
        return shopInfoDAO.updateShopInfo(update) > 0;
    }

    /**
     * 费用校验
     * @param request
     * @return
     */
    private Boolean feeCheck(AddSignFranchiseRequest request){
        //查询账单金额
        FranchiseFeeDO franchiseFeeDO = franchiseFeeMapper.selectByShopId(request.getShopId());

        //正新鸡排
        if (StringUtils.isNotEmpty(franchiseFeeDO.getYearFranchiseFee())&&request.getContractFranchiseFee()!=null&&!request.getContractFranchiseFee().equals(franchiseFeeDO.getYearFranchiseFee())){
            return Boolean.FALSE;
        }
        //合同设计费
        if (StringUtils.isNotEmpty(franchiseFeeDO.getPerformanceBond())&&request.getContractPerformanceBond()!=null&&!request.getContractPerformanceBond().equals(franchiseFeeDO.getPerformanceBond())){
            return Boolean.FALSE;
        }
        //品牌使用费
        if (StringUtils.isNotEmpty(franchiseFeeDO.getFirstYearFee())&&request.getContractBrandUseFee()!=null&&!request.getContractBrandUseFee().equals(franchiseFeeDO.getFirstYearFee())){
            return Boolean.FALSE;
        }
        //合同保证金
        if (StringUtils.isNotEmpty(franchiseFeeDO.getLoanMargin())&&request.getContractLoanMargin()!=null&&!request.getContractLoanMargin().equals(franchiseFeeDO.getLoanMargin())){
            return Boolean.FALSE;
        }
        //合同管理费
        if (StringUtils.isNotEmpty(franchiseFeeDO.getFirstYearManageFee())&&request.getContractManageFee()!=null&&!request.getContractManageFee().equals(franchiseFeeDO.getFirstYearManageFee())){
            return Boolean.FALSE;
        }
        if (StringUtils.isNotEmpty(franchiseFeeDO.getCashierFee())&&request.getContractSysUserFee()!=null&&!request.getContractSysUserFee().equals(franchiseFeeDO.getCashierFee())){
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }




    private void updateShopAndPoint(AddSignFranchiseRequest request, ShopInfoDO shopInfoDO, PointInfoDO pointInfoById) {
        //店铺信息
        shopInfoDO.setManagerRegionId(request.getManagerRegionId());
        shopInfoDO.setRegionId(request.getRegionId());
        shopInfoDO.setShopName(request.getShopName());
        shopInfoDO.setDetailAddress(request.getDetailAddress());
        shopInfoDO.setJoinMode(request.getJoinMode());
        shopInfoDO.setFranchiseBrand(request.getFranchiseBrand());
        shopInfoDO.setProvince(request.getProvince());
        shopInfoDO.setCity(request.getCity());
        shopInfoDO.setDistrict(request.getDistrict());
        shopInfoDO.setProvinceCode(request.getProvinceCode());
        shopInfoDO.setCityCode(request.getCityCode());
        shopInfoDO.setDistrictCode(request.getDistrictCode());
        shopInfoDO.setUpdateTime(new Date());
        shopInfoDO.setStoreType(request.getStoreType());
        shopInfoDO.setShopDecorationAttributes(request.getShopDecorationAttributes());
        shopInfoDO.setChickenAmount(request.getChickenAmount());
        shopInfoDO.setChickenInstruction(request.getChickenInstruction());
        shopInfoDO.setDecorationLevel(request.getDecorationLevel());
        shopInfoDO.setDecorationRequirement(request.getDecorationRequirement());
        shopInfoDO.setSpecialInstruction(request.getSpecialInstruction());
        shopInfoMapper.updateByPrimaryKeySelective(shopInfoDO);
        if (Objects.nonNull(pointInfoById)) {
            pointInfoById.setProvince(request.getProvince());
            pointInfoById.setCity(request.getCity());
            pointInfoById.setDistrict(request.getDistrict());
            pointInfoById.setAddress(request.getDetailAddress());
            pointInfoById.setUpdateTime(new Date());
            pointInfoDAO.updatePointInfo(pointInfoById);
        }
        OrderSysInfoDO orderSysInfoDO = orderSysInfoDAO.selectByShopId(request.getShopId());
        if (Objects.isNull(orderSysInfoDO)) {
            orderSysInfoDO = new OrderSysInfoDO();
            orderSysInfoDO.setShopId(request.getShopId());
            orderSysInfoDAO.insertSelective(orderSysInfoDO);
        } else {
            //同步建店资料地址
            orderSysInfoDO.setAddresseeAddress(request.getDetailAddress());
            orderSysInfoDO.setAddresseeCity(request.getCity());
            orderSysInfoDO.setAddresseeDistrict(request.getDistrict());
            orderSysInfoDO.setAddresseeProvince(request.getProvince());
            orderSysInfoDAO.updateAddresseeAddress(orderSysInfoDO);
        }
    }

    @Override
    public AddSignFranchiseResponse getSignFranchise(Long shopId) {
        SignFranchiseDO signFranchiseDO = signFranchiseMapper.selectByShopId(shopId);
        AddSignFranchiseResponse response = from(signFranchiseDO, shopId);
        ShopAuditInfoDO shopAuditInfoDO = null;
        if (Objects.nonNull(signFranchiseDO)) {
            shopAuditInfoDO = shopAuditInfoMapper.selectByPrimaryKey(signFranchiseDO.getAuditId());
        }
        if (Objects.nonNull(shopAuditInfoDO)) {
            response.setStatus(shopAuditInfoDO.getResultType());
            if (shopAuditInfoDO.getResultType() == 0) {
                response.setResult(shopAuditInfoDO.getPassReason());
            } else {
                response.setResult(shopAuditInfoDO.getRejectReason());
            }
        }
        if (signFranchiseDO != null) {
            response.setResultTime(signFranchiseDO.getCreateTime());
        }
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean auditApprove(AuditApproveRequest request, LoginUserInfo user) {
        log.info("SignFranchiseServiceImpl auditApprove request：{}", JSONObject.toJSONString(request));
        Long shopId = request.getShopId();
        String lockKey = "auditApproveSignFranchise:" + request.getShopId();
        //流水
        String lockValue = UUID.randomUUID().toString();
        boolean acquired = false;
        try {
            //10s过期
            acquired = redisUtilPool.setNxExpire(lockKey, lockValue, CommonConstants.TEN_SECONDS);
            if (Boolean.TRUE.equals(acquired)) {
                ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(shopId);
                ShopAuditInfoDO shopAuditInfoDO = new ShopAuditInfoDO();
                shopAuditInfoDO.setShopId(shopId);
                shopAuditInfoDO.setAuditType(AuditTypeEnum.SIGN_FRANCHISE.getCode());
                shopAuditInfoDO.setSubmittedUserId(user.getUserId());
                shopAuditInfoDO.setSubmittedUserName(user.getName());
                //驳回
                ContractCallbackDTO contractCallbackDTO = null;
                if (Constants.ZERO_INTEGER.equals(request.getAuditResult())) {
                    auditReject(request, shopAuditInfoDO, shopInfoDO);
                } else if (Constants.ONE_INTEGER.equals(request.getAuditResult())) {
                    shopAuditInfoDO.setResultType(Constants.ZERO_INTEGER);
                    shopAuditInfoDO.setPassReason(request.getCause());
                    //更新状态为加盟商
                    LineInfoDO lineInfoDO = lineInfoMapper.getByLineId(shopInfoDO.getLineId());
                    shopStageInfoDAO.updateShopStageInfo(shopId, SHOP_SUB_STAGE_STATUS_83_5);
                    //推送数据
                    contractCallbackDTO = pushContractRequest(shopInfoDO, request.getShopId());
                    Boolean sendNotice = Boolean.TRUE;
                    if (sendNotice) {
                        HashMap<String, String> map = new HashMap<>();
                        map.put("partnerUsername", lineInfoDO.getUsername());
                        map.put("partnerMobile", lineInfoDO.getMobile());
                        map.put("storeName", shopInfoDO.getShopName());
                        List<EnterpriseUserDO> userDOList = userAuthMappingService.getAllUserByRoleEnumAndRegionId(UserRoleEnum.FINANCE, shopInfoDO.getRegionId());
                        List<String> finances = new ArrayList<>();
                        if (Objects.nonNull(userDOList)) {
                            finances.addAll(userDOList.stream().map(EnterpriseUserDO::getUserId).collect(Collectors.toList()));
                        }
                        operationLogService.addOperationLog(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_83_5,
                                user.getUserId(), userDOList,
                                OperationTypeEnum.OPERATION_TYPE_1, "加盟签约合同财务审批", OperationStatusEnum.NOT_PROCESSED, 2);
                        commonService.sendQWMessage(finances,
                                MessageEnum.MESSAGE_19_1,
                                map);
                    }
                }
                shopAuditInfoMapper.insertSelective(shopAuditInfoDO);
                Long auditId = shopAuditInfoDO.getId();
                if (contractCallbackDTO != null && StringUtils.isNotEmpty(contractCallbackDTO.getStoreCode())) {
                    shopInfoDO.setShopCode(contractCallbackDTO.getStoreCode());
                    shopInfoMapper.updateByPrimaryKeySelective(shopInfoDO);
                }
                signFranchiseDAO.updateAuditByShopId(auditId, shopId, contractCallbackDTO);
                //审批记录表记录
                List<OperationLogDO> operationLogs = operationLogDAO.getBySubStageStatusEnumAndsStatus(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_83, OperationTypeEnum.OPERATION_TYPE_1.getCode());
                operationLogService.batchUpdateProcessed(operationLogs, auditId, user.getUserId(), request.getCause());
                return true;
            } else {
                throw new ServiceException(ErrorCodeEnum.DUPLICATE_SUBMISSION);
            }
        } finally {
            if (Boolean.TRUE.equals(acquired)) {
                String currentValue = redisUtilPool.getString(lockKey);
                if (lockValue.equals(currentValue)) {
                    redisUtilPool.delKey(lockKey);
                }
            }
        }
    }

    /**
     * 分部内勤/财务审批拒绝
     */
    private void auditReject(AuditApproveRequest request, ShopAuditInfoDO shopAuditInfoDO, ShopInfoDO shopInfoDO) {
        shopAuditInfoDO.setResultType(Constants.ONE_INTEGER);
        shopAuditInfoDO.setRejectReason(request.getCause());
        Map<String, String> requestMap = new HashMap<>();
        LineInfoDO lineInfo = lineInfoMapper.getByLineId(shopInfoDO.getLineId());
        shopStageInfoDAO.updateShopStageInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_85);
        Set<String> auditFranchiseFeeUsers = new HashSet<>();
        List<EnterpriseUserDO> branchUser = userAuthMappingService.getAllUserByRoleEnumAndRegionId(UserRoleEnum.JOIN_OFFICE, shopInfoDO.getInvestRegionId());
        if (Objects.nonNull(branchUser)) {
            Set<String> branchUserIds = branchUser.stream().map(EnterpriseUserDO::getUserId).collect(Collectors.toSet());
            auditFranchiseFeeUsers.addAll(branchUserIds);
        }
        List<EnterpriseUserDO> regionUser = userAuthMappingService.getAllUserByRoleEnumAndRegionId(REGION_OFFICE, shopInfoDO.getInvestRegionId());
        if (Objects.nonNull(regionUser)) {
            Set<String> regionUserIds = regionUser.stream().map(EnterpriseUserDO::getUserId).collect(Collectors.toSet());
            auditFranchiseFeeUsers.addAll(regionUserIds);
        }
        requestMap.put("storeName", shopInfoDO.getShopName());
        requestMap.put("partnerName", lineInfo.getUsername());
        requestMap.put("partnerMobile", lineInfo.getMobile());
        requestMap.put("lineId", String.valueOf(lineInfo.getId()));
        requestMap.put("shopId", String.valueOf(shopInfoDO.getId()));
        commonService.sendMessage(new ArrayList<>(auditFranchiseFeeUsers), MessageEnum.MESSAGE_20, requestMap);
    }

    @Override
    @Transactional
    public Boolean financeAuditApprove(AuditApproveRequest request, LoginUserInfo user) {
        log.info("SignFranchiseServiceImpl financeAuditApprove request：{}", JSONObject.toJSONString(request));
        Long shopId = request.getShopId();
        String lockKey = "financeAuditApprove:" + request.getShopId();
        //流水
        String lockValue = UUID.randomUUID().toString();
        boolean acquired = false;
        try {
            //10s过期
            acquired = redisUtilPool.setNxExpire(lockKey, lockValue, CommonConstants.TEN_SECONDS);
            if (Boolean.TRUE.equals(acquired)) {
                ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(shopId);
                ShopAuditInfoDO shopAuditInfoDO = new ShopAuditInfoDO();
                shopAuditInfoDO.setShopId(shopId);
                shopAuditInfoDO.setAuditType(AuditTypeEnum.SIGN_FRANCHISE.getCode());
                shopAuditInfoDO.setSubmittedUserId(user.getUserId());
                shopAuditInfoDO.setSubmittedUserName(user.getName());
                //驳回
                if (Constants.ZERO_INTEGER.equals(request.getAuditResult())) {
                    auditReject(request, shopAuditInfoDO, shopInfoDO);
                } else if (Constants.ONE_INTEGER.equals(request.getAuditResult())) {
                    log.info("合同审核，装修属性:{}，加盟模式：{}", ShopDecorationAttributesEnum.getDescByCode(shopInfoDO.getShopDecorationAttributes()),
                            JoinModeEnum.getByCode(shopInfoDO.getJoinMode()));
                    if (shopInfoDO.getShopDecorationAttributes().equals(ShopDecorationAttributesEnum.OLD_NEW_OPEN.getCode())) {
                        //老店新开时装修与开业直接完成
                        shopStageInfoDAO.batchUpdateByShopIdsAndSubStageStatus(Arrays.asList(shopId), Arrays.asList(
                                SHOP_SUB_STAGE_STATUS_863, SHOP_SUB_STAGE_STATUS_91, SHOP_SUB_STAGE_STATUS_112, SHOP_SUB_STAGE_STATUS_123, SHOP_SUB_STAGE_STATUS_143,
                                SHOP_SUB_STAGE_STATUS_276
                        ));
                    } else {
                        //，加盟公司自有店->加盟公司建店 不推送数据 再crm中完成
                        //v2.0.0 先确认装修团队
                        Long teamId = getTeamId(shopInfoDO);
                        ShopDecorationAssignDO shopDecorationAssignDO = new ShopDecorationAssignDO();
                        shopDecorationAssignDO.setDecorationDescStatus(DecorationDescStatus.TO_BE_ASSIGNED.getCode());
                        shopDecorationAssignDO.setDecorationTeamId(teamId);
                        shopDecorationAssignDO.setShopId(shopId);
                        shopDecorationAssignDAO.insert(shopDecorationAssignDO);
                        //新增一个延迟队列 四个小时之后确定是否手动分配 没有手动分配 直接自动分配  红圈通推送和下一个流程开始改为分配团队之后 触发
                        simpleMessageService.send(String.valueOf(shopDecorationAssignDO.getId()), RocketMqTagEnum.DELAY_SHOP_DECORATION_ASSIGN, System.currentTimeMillis() + 1 * 60 * 60 * 1000);
                    }
                    shopAuditInfoDO.setResultType(Constants.ZERO_INTEGER);
                    shopAuditInfoDO.setPassReason(request.getCause());
                    //更新状态为加盟商
                    LineInfoDO lineInfoDO = lineInfoMapper.getByLineId(shopInfoDO.getLineId());
                    //暂时去掉
                    lineInfoDO.setJoinStatus(CommonConstants.TWO);
                    lineInfoMapper.insertOrUpdate(lineInfoDO);
                    shopStageInfoDAO.updateShopStageInfo(shopId, SHOP_SUB_STAGE_STATUS_84);
                    //初始化数据 如果是正新鸡排 需要手动分配 其他品牌直接开始 且将招商经理给到运营经理
                    if (FranchiseBrandEnum.ZXJP.getCode() == Integer.valueOf(shopInfoDO.getFranchiseBrand())) {
                        log.info("zxjp_assign shopId:{}", shopId);
                        //新增分配信息
                        OperationsConsultantAssignDO operationsConsultantAssignDO = new OperationsConsultantAssignDO();
                        operationsConsultantAssignDO.setShopId(shopId);
                        operationsConsultantAssignDO.setAssignStatus(0);
                        operationsConsultantAssignDO.setRegionId(shopInfoDO.getRegionId());
                        operationsConsultantAssignDAO.addOperationsConsultantAssign(operationsConsultantAssignDO);
                    } else {
                        //其他品牌直接开始 且将招商经理给到运营经理
                        shopInfoDO.setOperationsConsultant(shopInfoDO.getInvestmentManager());
                        shopInfoDAO.updateShopInfo(shopInfoDO);
                        preparationService.contractAndBuildStoreCompletion(request.getShopId());
                    }


                    Boolean sendNotice = Boolean.TRUE;
                    commonService.sendSms(lineInfoDO.getMobile(), SMSMsgEnum.SIGN_CONTRACT);
                    if (sendNotice) {
                        HashMap<String, String> map = new HashMap<>();
                        map.put("partnerUsername", lineInfoDO.getUsername());
                        map.put("partnerMobile", lineInfoDO.getMobile());
                        map.put("storeName", shopInfoDO.getShopName());
                        commonService.sendQWMessage(Collections.singletonList(shopInfoDO.getInvestmentManager()),
                                MessageEnum.MESSAGE_26,
                                map);
                    }
                }
                shopAuditInfoMapper.insertSelective(shopAuditInfoDO);
                Long auditId = shopAuditInfoDO.getId();
                signFranchiseDAO.updateAuditByShopId(auditId, shopId);
                //审批记录表记录
                List<OperationLogDO> operationLogs = operationLogDAO.getBySubStageStatusEnumAndsStatus(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_83_5, OperationTypeEnum.OPERATION_TYPE_1.getCode());
                operationLogService.batchUpdateProcessed(operationLogs, auditId, user.getUserId(), request.getCause());
                return true;
            } else {
                throw new ServiceException(ErrorCodeEnum.DUPLICATE_SUBMISSION);
            }
        } finally {
            if (Boolean.TRUE.equals(acquired)) {
                String currentValue = redisUtilPool.getString(lockKey);
                if (lockValue.equals(currentValue)) {
                    redisUtilPool.delKey(lockKey);
                }
            }
        }
    }


    /**
     * 获取装修团队
     * @param shopInfoDO
     * @return
     */
    private Long getTeamId(ShopInfoDO shopInfoDO) {
        // 标准店统一使用默认立规团队
        if (isStandardStore(shopInfoDO)) {
            log.info("标准店使用默认团队, 门店名称: {}", shopInfoDO.getShopName());
            return getDefaultTeamId();
        }

        // 根据城市获取团队
        TeamAreaMappingDO cityMapping = teamAreaMappingDAO.getByCityId(shopInfoDO.getWantShopAreaId());
        if (cityMapping == null) {
            log.warn("未找到城市映射, cityId: {}, 使用默认团队", shopInfoDO.getWantShopAreaId());
            return getDefaultTeamId();
        }

        DecorationTeamConfigDO teamConfig = decorationTeamConfigDAO.getById(cityMapping.getTeamId());
        if (teamConfig == null) {
            log.warn("未找到团队配置, teamId: {}, 使用默认团队", cityMapping.getTeamId());
            return getDefaultTeamId();
        }

        return teamConfig.getId();
    }

    /**
     * 判断是否为标准店
     */
    private boolean isStandardStore(ShopInfoDO shopInfoDO) {
        return shopInfoDO != null && Integer.valueOf(1).equals(shopInfoDO.getUseStandardStore());
    }

    /**
     * 获取默认团队ID
     */
    private Long getDefaultTeamId() {
        return 1L;
    }

    /**
     * 推送合同信息请求
     * @param shopId
     */
    @Override
    public ContractCallbackDTO pushContractRequest(ShopInfoDO shopInfoDO,Long shopId){
        //推送法大大数据
        //查询缴费信息
        FranchiseFeeDO franchiseFeeDO = franchiseFeeMapper.selectByShopId(shopId);
        SignFranchiseDO signFranchiseDO = signFranchiseMapper.selectByShopId(shopId);

        String userName = "";
        if (signFranchiseDO != null){
             userName = enterpriseUserDAO.getUserName(signFranchiseDO.getCreateUserId());
        }

        LineInfoDO lineInfo = lineInfoDAO.getLineInfo(shopInfoDO.getLineId());

        List<Long> regionIds = Arrays.asList(shopInfoDO.getRegionId(), shopInfoDO.getInvestRegionId(), shopInfoDO.getManagerRegionId());

        Map<Long, String> regionNameMap = regionDao.getRegionNameMap(regionIds);


        log.info("加盟合同审批时签约类型:{}", SignTypeEnum.getDescByCode(signFranchiseDO.getSignType()));

        ContractInformationDTO contractInformationDTO = new ContractInformationDTO();
        if (Objects.nonNull(lineInfo)){
            contractInformationDTO.setSignerAddress(lineInfo.getLiveAddress());
            contractInformationDTO.setSignerPhone(lineInfo.getMobile());
        }

        //自营店 无缴费信息 不需要校验
        if (franchiseFeeDO != null){
            contractInformationDTO.setShopId(shopId);
            contractInformationDTO.setJoinModel(shopInfoDO.getJoinMode());
            contractInformationDTO.setShopName(shopInfoDO.getShopName());
            //品牌信息
            contractInformationDTO.setSign1Name(signFranchiseDO.getPartnershipSignatoryFirst());
            contractInformationDTO.setSign2Name(signFranchiseDO.getPartnershipSignatorySecond());
            contractInformationDTO.setFirstYearFee(franchiseFeeDO.getFirstYearFee());
            contractInformationDTO.setLoanMargin(franchiseFeeDO.getLoanMargin());
            contractInformationDTO.setFirstYearManagementFee(franchiseFeeDO.getFirstYearManageFee());
            contractInformationDTO.setYearFranchiseFee(franchiseFeeDO.getYearFranchiseFee());
            contractInformationDTO.setPerformanceBond(franchiseFeeDO.getPerformanceBond());

            contractInformationDTO.setContractFranchiseFee(signFranchiseDO.getContractFranchiseFee());
            contractInformationDTO.setContractManageFee(signFranchiseDO.getContractManageFee());
            contractInformationDTO.setContractBrandUseFee(signFranchiseDO.getContractBrandUseFee());
            contractInformationDTO.setContractPerformanceBond(signFranchiseDO.getContractPerformanceBond());
            contractInformationDTO.setContractLoanMargin(signFranchiseDO.getContractLoanMargin());
            contractInformationDTO.setContractSysUserFee(signFranchiseDO.getContractSysUserFee());
            contractInformationDTO.setSignModality(signFranchiseDO.getSignModality());
            contractInformationDTO.setFranchiseFeeFrequency(signFranchiseDO.getFranchiseFeeFrequency());
            contractInformationDTO.setBrandUseFeeFrequency(signFranchiseDO.getBrandUseFeeFrequency());
            contractInformationDTO.setJoinSource(signFranchiseDO.getJoinSource());
            contractInformationDTO.setManageFeeFrequency(signFranchiseDO.getManageFeeFrequency());
            contractInformationDTO.setDiscountAmount(signFranchiseDO.getDiscountAmount());
            contractInformationDTO.setSummitUserName(userName);
            contractInformationDTO.setCurrency(signFranchiseDO.getCurrency());
            contractInformationDTO.setContractStartTime(DateUtils.dateTime(signFranchiseDO.getContractStartTime()));
            contractInformationDTO.setContractEndTime(DateUtils.dateTime(signFranchiseDO.getContractEndTime()));
            contractInformationDTO.setContractServiceLife(signFranchiseDO.getContractServiceLife());

            contractInformationDTO.setStoreAddress(shopInfoDO.getDetailAddress());
            contractInformationDTO.setDiscountReason(franchiseFeeDO.getDiscountReason());
            if (shopInfoDO.getRegionId()!=null){
                contractInformationDTO.setRegionName(regionNameMap.get(shopInfoDO.getRegionId()));
            }
            if (shopInfoDO.getInvestRegionId()!=null){
                contractInformationDTO.setInvestRegionName(regionNameMap.get(shopInfoDO.getInvestRegionId()));
            }
            if (shopInfoDO.getRegionId()!=null){
                contractInformationDTO.setSubRegionName(regionNameMap.get(shopInfoDO.getManagerRegionId()));
            }


            //老店转加盟(也叫直营转加盟)
            if (SignTypeEnum.DIRECT_SALES_TO_JOINING.getCode().equals(signFranchiseDO.getSignType())){
                contractInformationDTO.setOldShopCode(signFranchiseDO.getOldShopCode());
            }
            FranchiseBrandEnum enumByCode = FranchiseBrandEnum.getEnumByCode(shopInfoDO.getFranchiseBrand());
            if (enumByCode != null){
                contractInformationDTO.setPayeeName(enumByCode.getPayeeName());
                contractInformationDTO.setBrandOwner(enumByCode.getBrandOwner());
            }
            contractInformationDTO.setContractNo(signFranchiseDO.getContractCode());
            contractInformationDTO.setStoreCode(shopInfoDO.getShopCode());
            try {
                return pushService.pushContract(contractInformationDTO);
            } catch (Exception e) {
                log.error("推送合同信息失败", e);
            }
        }
        return null;
    }

    @Override
    public HqtBuildRequest getHqtBuildRequest(Long shopId) {
        ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
        LineInfoDO lineInfoDO = lineInfoDAO.getLineInfo(shopInfo.getLineId());
        EnterpriseUserDO userInfoById = enterpriseUserDAO.getUserInfoById(shopInfo.getInvestmentManager());
        BigRegionDO bigRegionDO = bigRegionDAO.getByRegionId(shopInfo.getRegionId());
        if (StringUtils.isBlank(bigRegionDO.getHqtRegionCode())){
            bigRegionDO = hqtAPIService.pushHqtRegion(bigRegionDO);
        }
        HqtBuildRequest request = new HqtBuildRequest();
        //新增邮箱
        String email = redisUtilPool.hashGet(RedisConstant.BIG_REGION_EMAIL, String.valueOf(shopInfo.getRegionId()));
        if (StringUtils.isNotEmpty(email)){
            request.setEmail(email);
        }
        String investReginMail = redisUtilPool.hashGet(RedisConstant.INVEST_BIG_REGION_EMAIL, String.valueOf(shopInfo.getInvestRegionId()));
        if (StringUtils.isNotBlank(investReginMail)) {
            request.setInvestRegionEmail(investReginMail);
        }
        request.setShopId(shopId);
        request.setShopCode(shopInfo.getShopCode());
        request.setShopName(shopInfo.getShopName());
        request.setShopDecorationAttributes(shopInfo.getShopDecorationAttributes());
        request.setHqtRegionCode(bigRegionDO.getHqtRegionCode());
        request.setHqtRegionName(bigRegionDO.getHqtRegionName());
        request.setSupervisorName(userInfoById.getName());
        request.setSupervisorMobile(userInfoById.getMobile());
        request.setPartnershipSignatoryFirst(lineInfoDO.getUsername());
        request.setPartnershipSignatoryFirstMobile(lineInfoDO.getMobile());
        request.setShopAddress(shopInfo.getDetailAddress());
        request.setIsPayDesignFee(CommonConstants.ONE);
        request.setDecorationLevel(shopInfo.getDecorationLevel());
        request.setDecorationRequirement(shopInfo.getDecorationRequirement());
        request.setSpecialInstruction(shopInfo.getSpecialInstruction());
        request.setStoreType(shopInfo.getStoreType());
        if (StringUtils.isNotEmpty(shopInfo.getOperationsConsultant())){
            String userName = enterpriseUserDAO.getUserName(shopInfo.getOperationsConsultant());
            request.setOperationsConsultant(userName);
        }
        if (shopInfo.getInvestRegionId()!=null){
            RegionDO region = regionDao.getRegionById(shopInfo.getInvestRegionId());
            if (region!=null){
                request.setInvestRegionName(region.getName());
            }
        }
        if (StringUtils.isNotBlank(shopInfo.getFranchiseBrand())) {
            request.setFranchiseBrand(Integer.valueOf(shopInfo.getFranchiseBrand()));
        }
        return request;
    }


    @Override
    @Transactional
    public Boolean assignOperationConsultant(AssignOperationConsultantRequest request) {
        log.info("assignOperationConsultant:{}",JSONObject.toJSONString(request));
        //查询分配信息
        OperationsConsultantAssignDO operationsConsultantAssignDO = operationsConsultantAssignDAO.selectByShopId(request.getShopId());
        if (operationsConsultantAssignDO == null){
            throw new ServiceException(ErrorCodeEnum.PARAMS_VALIDATE_ERROR);
        }
        if (operationsConsultantAssignDO.getAssignStatus()==1){
            throw new ServiceException(ErrorCodeEnum.OPERATIONS_CONSULTANT_ASSIGNED);
        }
        //已分配
        operationsConsultantAssignDO.setAssignStatus(1);
        operationsConsultantAssignDAO.updateById(operationsConsultantAssignDO);
        ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(request.getShopId());
        shopInfo.setOperationsConsultant(request.getOperationConsultantUserId());
        shopInfoDAO.updateShopInfo(shopInfo);

        //分配之后 开始以下阶段
        preparationService.contractAndBuildStoreCompletion(request.getShopId());

        // 推送红圈通
        if (StringUtils.isBlank(shopInfo.getHqtShopId())) {
            try {
                ShopDecorationAssignDO assignDO = shopDecorationAssignDAO.getByShopId(shopInfo.getId());
                if (Objects.nonNull(assignDO)) {
                    DecorationTeamConfigDO teamInfo = decorationTeamConfigDAO.getById(assignDO.getDecorationTeamId());
                    if (Objects.nonNull(teamInfo) && DecorationUseSystemEnum.HQT.getCode().equals(teamInfo.getUseSystem())) {
                        hqtAPIService.pushHqtBuild(signFranchiseService.getHqtBuildRequest(shopInfo.getId()));
                    }
                }
            } catch (Exception e) {
                log.error("推送红圈通失败", e);
            }
        }

        return Boolean.TRUE;
    }

    public AddSignFranchiseResponse from(SignFranchiseDO signFranchiseDO,
                                         Long shopId) {
        AddSignFranchiseResponse addSignFranchiseResponse = new AddSignFranchiseResponse();
        //店铺信息
        ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(shopId);
        //线索信息
        LineInfoDO lineInfoDO = lineInfoMapper.getByLineId(shopInfoDO.getLineId());
        //加盟问卷信息
        QualificationsInfoDO qualificationsInfoDO = qualificationsInfoDAO.getByLineId(shopInfoDO.getLineId());
        //缴费信息
        FranchiseFeeDO franchiseFeeDO = franchiseFeeMapper.selectOne(FranchiseFeeDO.builder().shopId(shopId).build());
        //线索id
        Long lineId = shopInfoDO.getLineId();
        //缴款信息
        List<LinePayDO> linePayList = null;
        List<WalletPayInfoDO> payInfoList = null;
        if (PayTypeEnum.OFFLINE.getType().equals(franchiseFeeDO.getPayType())) {
            linePayList = linePayMapper.getFranchiseFeePayInfoByShopId(shopId);
        } else {
            payInfoList = walletPayInfoDAO.getByShopId(shopId, WalletTradeModuleEnum.FRANCHISE_PAY.getModule(), AllocationPayStatusEnum.PAID.getStatus());
        }
//        //铺位信息
//        PointInfoDO pointInfoDO = pointInfoMapper.getDataByShopIdAndLineId(lineId, shopId);
        //证照办理
        LicenseTransactDO licenseTransactDO = applyLicenseMapper.selectByShopId(shopId);

        RegionDO regionInfo = regionDao.selectById(shopInfoDO.getRegionId());

        RegionDO managerRegion = regionDao.selectById(shopInfoDO.getManagerRegionId());


//        if (Objects.nonNull(pointInfoDO)) {
//          //  addSignFranchiseResponse.setStoreAddress(pointInfoDO.getAddress());
//           if (StringUtils.isNoneBlank(pointInfoDO.getLatitude(), pointInfoDO.getLongitude())) {
//              //GeoMapUtil.AddressInfo addressInfo = GeoMapUtil.reverseGeoCoding(pointInfoDO.getLatitude(), pointInfoDO.getLongitude());
//               //addSignFranchiseResponse.setStoreProvinceCity(String.format("%s%s%s", addressInfo.getProvince(), addressInfo.getCity(), addressInfo.getDistrict()));
//            }
//        }
        addSignFranchiseResponse.setPartnershipSignatoryFirst(lineInfoDO.getUsername());
        addSignFranchiseResponse.setDetailAddress(shopInfoDO.getDetailAddress());
        addSignFranchiseResponse.setStoreType(shopInfoDO.getStoreType());
        addSignFranchiseResponse.setProvince(shopInfoDO.getProvince());
        addSignFranchiseResponse.setCity(shopInfoDO.getCity());
        addSignFranchiseResponse.setDistrict(shopInfoDO.getDistrict());
        addSignFranchiseResponse.setProvinceCode(shopInfoDO.getProvinceCode());
        addSignFranchiseResponse.setCityCode(shopInfoDO.getCityCode());
        addSignFranchiseResponse.setDistrictCode(shopInfoDO.getDistrictCode());
        addSignFranchiseResponse.setManagerRegionId(shopInfoDO.getManagerRegionId());
        addSignFranchiseResponse.setShopDecorationAttributes(shopInfoDO.getShopDecorationAttributes());
        if (Objects.nonNull(managerRegion)){
            addSignFranchiseResponse.setManagerRegionName(managerRegion.getName());
        }
        if (Objects.nonNull(signFranchiseDO)) {
            BeanUtils.copyProperties(signFranchiseDO, addSignFranchiseResponse);
        } else {
            if (Objects.nonNull(franchiseFeeDO)) {
                BigDecimal total = convertToBig(franchiseFeeDO.getYearFranchiseFee())
                        .add(convertToBig(franchiseFeeDO.getLoanMargin()))
                        .add(convertToBig(franchiseFeeDO.getFirstYearFee()))
                        .add(convertToBig(franchiseFeeDO.getFirstYearManageFee()))
                        .add(convertToBig(franchiseFeeDO.getPerformanceBond()))
                        .add(convertToBig(franchiseFeeDO.getCashierFee()));
                addSignFranchiseResponse.setContractAmount(total.toString());
                if (FranchiseBrandEnum.ZXJP.getCode()==Integer.valueOf(shopInfoDO.getFranchiseBrand())){
                    BigDecimal discountAmount = STANDARD_TOTAL_AMOUNT.subtract(total);
                    addSignFranchiseResponse.setDiscountAmount(discountAmount.toString());
                }
            }
            addSignFranchiseResponse.setMobile(lineInfoDO.getMobile());
        }
        addSignFranchiseResponse.setStoreName(shopInfoDO.getShopName());
        addSignFranchiseResponse.setShopCode(shopInfoDO.getShopCode());
        addSignFranchiseResponse.setFranchiseBrand(shopInfoDO.getFranchiseBrand());
        addSignFranchiseResponse.setJoinMode(shopInfoDO.getJoinMode());
        addSignFranchiseResponse.setChickenAmount(shopInfoDO.getChickenAmount());
        addSignFranchiseResponse.setChickenInstruction(shopInfoDO.getChickenInstruction());
        addSignFranchiseResponse.setDecorationLevel(shopInfoDO.getDecorationLevel());
        addSignFranchiseResponse.setDecorationRequirement(shopInfoDO.getDecorationRequirement());
        addSignFranchiseResponse.setSpecialInstruction(shopInfoDO.getSpecialInstruction());
        dictService.fillDictField(addSignFranchiseResponse);

        if (Objects.nonNull(regionInfo)) {
            addSignFranchiseResponse.setRegionId(shopInfoDO.getRegionId());
            addSignFranchiseResponse.setRegionName(regionInfo.getName());
        }
        if(CollectionUtils.isNotEmpty(linePayList)){
            Set<String> payNameSet = new HashSet<>();
            List<Date> payTimeList = new ArrayList<>();
            List<PartnerBankInfoDTO> partnerPayData = new ArrayList<>();
            for (LinePayDO linePayDO : linePayList){
                payNameSet.add(linePayDO.getPayUserName());
                payTimeList.add(linePayDO.getPayTime());
                PartnerBankInfoDTO dto = new PartnerBankInfoDTO();
                dto.setBankCardNo(linePayDO.getPayAccount());
                dto.setBank(linePayDO.getBankName());
                dto.setSubBank(linePayDO.getBranchBankName());
                partnerPayData.add(dto);
            }
            addSignFranchiseResponse.setPayName(new ArrayList<>(payNameSet));
            addSignFranchiseResponse.setPartnerPayData(partnerPayData);
            Date earliestPayTime = payTimeList.stream().filter(Objects::nonNull)
                    .min(Comparator.naturalOrder())
                    .orElse(null);
            addSignFranchiseResponse.setPayDate(earliestPayTime);
        }

        if(CollectionUtils.isNotEmpty(payInfoList)){
            Set<String> payNameSet = new HashSet<>();
            List<Date> payTimeList = new ArrayList<>();
            for (WalletPayInfoDO payInfoDO : payInfoList){
                payNameSet.add(payInfoDO.getPayUserName());
                payTimeList.add(payInfoDO.getPayTime());
            }
            addSignFranchiseResponse.setPayName(new ArrayList<>(payNameSet));
            Date earliestPayTime = payTimeList.stream().filter(Objects::nonNull)
                    .min(Comparator.naturalOrder())
                    .orElse(null);
            addSignFranchiseResponse.setPayDate(earliestPayTime);
        }
        if (Objects.nonNull(licenseTransactDO)) {
            addSignFranchiseResponse.setLicenseName(licenseTransactDO.getBusinessLicense());
            addSignFranchiseResponse.setOpeAddress(licenseTransactDO.getLicenseAddress());
            addSignFranchiseResponse.setOperator(licenseTransactDO.getOperator());
            addSignFranchiseResponse.setLicenseCode(licenseTransactDO.getCreditCode());
            if (licenseTransactDO.getLicenseType() != null) {
                addSignFranchiseResponse.setType(LicenseTypeEnum.match(licenseTransactDO.getLicenseType()).getMessage());
            }
        }
        if (Objects.nonNull(lineInfoDO)) {
            addSignFranchiseResponse.setPartnerName(lineInfoDO.getUsername());
        }
        if (Objects.nonNull(qualificationsInfoDO)) {
            addSignFranchiseResponse.setIdCardNo(qualificationsInfoDO.getIdCardNo());
            addSignFranchiseResponse.setIdCardAddress(qualificationsInfoDO.getHouseholdRegistrationAddress());
            //如果是企业加盟商 签约人1 取 公司名称 ，身份证号使用统一社会信用代码
            if (qualificationsInfoDO.getJoinType()!=null && JoinTypeEnum.JOIN_TYPE_TWO.getCode().equals(qualificationsInfoDO.getJoinType())){
                addSignFranchiseResponse.setPartnershipSignatoryFirst(qualificationsInfoDO.getEnterpriseName());
                addSignFranchiseResponse.setIdCardNo(qualificationsInfoDO.getUnifiedSocialCreditCode());
            }
        }

        if (Objects.nonNull(franchiseFeeDO)) {
            addSignFranchiseResponse.setYearFranchiseFee(franchiseFeeDO.getYearFranchiseFee());
            addSignFranchiseResponse.setBigYearFranchiseFee(Convert.digitToChinese(convertToBig(franchiseFeeDO.getYearFranchiseFee())));
            addSignFranchiseResponse.setLoanMargin(franchiseFeeDO.getLoanMargin());
            addSignFranchiseResponse.setBigLoanMargin(Convert.digitToChinese(convertToBig(franchiseFeeDO.getLoanMargin())));
            addSignFranchiseResponse.setFirstYearStartTime(franchiseFeeDO.getFirstYearStartTime());
            addSignFranchiseResponse.setFirstYearEndTime(franchiseFeeDO.getFirstYearEndTime());
            addSignFranchiseResponse.setFirstYearFee(franchiseFeeDO.getFirstYearFee());
            addSignFranchiseResponse.setFirstYearManageFee(franchiseFeeDO.getFirstYearManageFee());
            addSignFranchiseResponse.setSecondYearStartTime(franchiseFeeDO.getSecondYearStartTime());
            addSignFranchiseResponse.setSecondYearEndTime(franchiseFeeDO.getSecondYearEndTime());
            addSignFranchiseResponse.setSecondYearFee(franchiseFeeDO.getSecondYearFee());
            addSignFranchiseResponse.setThirdYearStartTime(franchiseFeeDO.getThirdYearStartTime());
            addSignFranchiseResponse.setThirdYearEndTime(franchiseFeeDO.getThirdYearEndTime());
            addSignFranchiseResponse.setThirdYearFee(franchiseFeeDO.getThirdYearFee());
            addSignFranchiseResponse.setPerformanceBond(franchiseFeeDO.getPerformanceBond());
            addSignFranchiseResponse.setBigPerformanceBond(Convert.digitToChinese(convertToBig(franchiseFeeDO.getPerformanceBond())));
            addSignFranchiseResponse.setCashierFee(franchiseFeeDO.getCashierFee());
            addSignFranchiseResponse.setBigCashierFee(Convert.digitToChinese(convertToBig(franchiseFeeDO.getCashierFee())));
        }
        //对于AI店
        if (CollectionUtils.isEmpty(linePayList)){
            List<PreAllocationRecordDO> preAllocationRecordDOS = preAllocationRecordDAO.queryPageByShopId(shopId);
            List<Date> dateList = preAllocationRecordDOS.stream().map(PreAllocationRecordDO::getCreateTime).collect(Collectors.toList());
            Date earliestPayTime = dateList.stream().filter(Objects::nonNull)
                    .min(Comparator.naturalOrder())
                    .orElse(null);
            addSignFranchiseResponse.setPayDate(earliestPayTime);
            if (addSignFranchiseResponse.getFirstYearStartTime()==null){
                addSignFranchiseResponse.setFirstYearStartTime(earliestPayTime);
            }
            if (addSignFranchiseResponse.getFirstYearEndTime()==null){
                addSignFranchiseResponse.setFirstYearEndTime(DateUtils.addDays(DateUtils.addYears(earliestPayTime,1),-1));
            }
        }
        return addSignFranchiseResponse;
    }

    public static String getDateTimeFormat(String pattern, Date date) {
        return new SimpleDateFormat(pattern).format(date);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean rePay(Long shopId) {
        shopStageInfoDAO.updateShopStageInfo(shopId, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_74);
        shopStageInfoDAO.updateShopStageToNotStarted(shopId, ShopSubStageEnum.SHOP_STAGE_8);
        return true;
    }

    @Override
    public Boolean backPayFeeStage(AuditApproveRequest request, LoginUserInfo user) {
        ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(request.getShopId());
        if (shopInfo!=null&&shopInfo.getUseStandardStore()==1){
            throw new ServiceException(ErrorCodeEnum.AI_NOT_SUPPORT_OPERATION);
        }
        //回退到对账中 此阶段账单可编辑 可再次对账
        shopStageInfoDAO.updateShopStageInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_72);
        //缴费阶段回退到未开始
        shopStageInfoDAO.updateShopStageToNotStarted(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_8);
        ShopAuditInfoDO shopAuditInfoDO = new ShopAuditInfoDO();
        shopAuditInfoDO.setShopId(request.getShopId());
        shopAuditInfoDO.setAuditType(AuditTypeEnum.SIGN_FRANCHISE.getCode());
        shopAuditInfoDO.setSubmittedUserId(user.getUserId());
        shopAuditInfoDO.setSubmittedUserName(user.getName());
        shopAuditInfoDO.setResultType(Constants.ONE_INTEGER);
        shopAuditInfoDO.setRejectReason(request.getCause());
        shopAuditInfoMapper.insertSelective(shopAuditInfoDO);
        Long auditId = shopAuditInfoDO.getId();
        //审批记录表记录
        List<OperationLogDO> operationLogs = operationLogDAO.getBySubStageStatusEnumAndsStatus(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_83, OperationTypeEnum.OPERATION_TYPE_1.getCode());
        operationLogService.batchUpdateProcessed(operationLogs, auditId, user.getUserId(), "回退到缴费阶段，"+request.getCause());
        return true;
    }

    @Override
    public Integer dateHandle() {
        return signFranchiseMapper.dateHandle();
    }

    private int timeUtils(Date time, String type) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        switch (type) {
            case "year":
                return calendar.get(Calendar.YEAR);
            case "month":
                return calendar.get(Calendar.MONTH) + 1;
            case "day":
                return calendar.get(Calendar.DAY_OF_MONTH);
            default:
                return 0;
        }

    }

    private List<Date> JsonToDate(String json) {
        if (StringUtils.isBlank(json)) {
            return new ArrayList<>();
        }
        ObjectMapper mapper = new ObjectMapper();
        // 解析JSON字符串为JsonNode对象
        JsonNode jsonNode = null;
        try {
            jsonNode = mapper.readTree(json);
            List<Date> payTimeList = new ArrayList<>();
            // 遍历数组节点
            for (JsonNode node : jsonNode) {
                long payTime = node.get("payTime").asLong();
                // 将时间戳转换为Date对象
                Date date = new Date(payTime);
                payTimeList.add(date);
            }
            return payTimeList;
        } catch (Exception e) {
            log.info("解析加盟费缴纳时间json失败");
            throw new RuntimeException(e);
        }
    }
}
