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.context.LoginUserInfo;
import com.cool.store.dao.*;
import com.cool.store.dto.PartnerBankInfoDTO;
import com.cool.store.entity.*;
import com.cool.store.enums.*;
import com.cool.store.enums.point.ShopSubStageEnum;
import com.cool.store.enums.point.ShopSubStageStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.*;
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.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 lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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 {

    @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
    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;


    @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);
        }
        SignFranchiseDO isExist = signFranchiseMapper.selectByShopId(request.getShopId());
        if (Objects.nonNull(isExist) && Objects.isNull(request.getId())) {
            throw new ServiceException(ErrorCodeEnum.DUPLICATE_SUBMISSION);
        }
        ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(request.getShopId());
        PointInfoDO pointInfoById = pointInfoDAO.getPointInfoById(shopInfoDO.getPointId());
        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)) {
                SignFranchiseDO signFranchiseDO = request.toSignFranchiseDO();
                if (Objects.isNull(request.getId())) {
                    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.getRegionId());
                    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);

                } else {
                    signFranchiseMapper.updateByPrimaryKeySelective(signFranchiseDO);
                }
                //修改shop & point
                updateShopAndPoint(request, shopInfoDO, pointInfoById);

                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);
                }
            }
        }

    }


    @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);
        }
        ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(request.getShopId());
        PointInfoDO pointInfoById = pointInfoDAO.getPointInfoById(shopInfoDO.getPointId());
        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.getRegionId());
        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);

        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());
        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());
                //驳回
                if (Constants.ZERO_INTEGER.equals(request.getAuditResult())) {
                    shopAuditInfoDO.setResultType(Constants.ONE_INTEGER);
                    shopAuditInfoDO.setRejectReason(request.getCause());
                    Map<String, String> requestMap = new HashMap<>();
                    LineInfoDO lineInfo = lineInfoMapper.getByLineId(shopInfoDO.getLineId());
                    shopStageInfoDAO.updateShopStageInfo(shopId, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_85);
                    Set<String> auditFranchiseFeeUsers = new HashSet<>();
                    List<EnterpriseUserDO> branchUser = userAuthMappingService.getAllUserByRoleEnumAndRegionId(UserRoleEnum.JOIN_OFFICE, shopInfoDO.getRegionId());
                    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.getRegionId());
                    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);
                } 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
                        ));
                    }else{
                        //，加盟公司自有店->加盟公司建店 不推送数据 再crm中完成
                        if ( !shopInfoDO.getJoinMode().equals(JoinModeEnum.OWN_STORE.getCode())){
                            hqtAPIService.pushHqtBuild(getHqtBuildRequest(request.getShopId()));
                        }
                        shopStageInfoDAO.updateShopStageInfo(shopId, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_861);
                    }
                    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);
                    //初始化数据
                    preparationService.contractAndBuildStoreCompletion(request.getShopId());

                    SignFranchiseDO signFranchiseDO = signFranchiseMapper.selectByShopId(shopId);
                    log.info("加盟合同审批时签约类型:{}", SignTypeEnum.getDescByCode(signFranchiseDO.getSignType()));
                    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());
                        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()));
                        }
//                        List<String> liGuiNeiQinList = enterpriseUserRoleDao.selectUserIdsByRoleIdList(Arrays.asList(UserRoleEnum.CONSTRUCTION_CUSTOMER.getCode()));
//                        commonService.sendQWMessage(liGuiNeiQinList,
//                                MessageEnum.MESSAGE_57,
//                                map);
                        commonService.sendQWMessage(Collections.singletonList(shopInfoDO.getInvestmentManager()),
                                MessageEnum.MESSAGE_26,
                                map);
                    }
                }
                shopAuditInfoMapper.insertSelective(shopAuditInfoDO);
                Long auditId = shopAuditInfoDO.getId();
                signFranchiseMapper.updateAuditByShopId(auditId, shopId);
                //审批记录表记录
                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);
                }
            }
        }
    }

    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();
        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);
        if (StringUtils.isNotBlank(shopInfo.getFranchiseBrand())) {
            request.setFranchiseBrand(Integer.valueOf(shopInfo.getFranchiseBrand()));
        }
        return request;
    }

    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 = linePayMapper.getFranchiseFeePayInfoByShopId(shopId);
//        //铺位信息
//        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)) {
            addSignFranchiseResponse.setUnifiedManagement(signFranchiseDO.getUnifiedManagement());
            addSignFranchiseResponse.setId(signFranchiseDO.getId());
            addSignFranchiseResponse.setShopId(signFranchiseDO.getShopId());
            addSignFranchiseResponse.setSignType(signFranchiseDO.getSignType());
            addSignFranchiseResponse.setBrandFee(signFranchiseDO.getBrandFee());
            addSignFranchiseResponse.setIsBusinessLicense(signFranchiseDO.getIsBusinessLicense());
            addSignFranchiseResponse.setIsFoodLicense(signFranchiseDO.getIsFoodLicense());
            addSignFranchiseResponse.setContractStartTime(signFranchiseDO.getContractStartTime());
            addSignFranchiseResponse.setContractStartEndTime(signFranchiseDO.getContractEndTime());
            addSignFranchiseResponse.setImpressionNum(signFranchiseDO.getImpressionNum());
            addSignFranchiseResponse.setBusinessStartHours(signFranchiseDO.getBusinessStartHours());
            addSignFranchiseResponse.setBusinessEndHours(signFranchiseDO.getBusinessEndHours());
            addSignFranchiseResponse.setIrregularReason(signFranchiseDO.getIrregularReason());
            addSignFranchiseResponse.setRemark(signFranchiseDO.getRemark());
            addSignFranchiseResponse.setResign(signFranchiseDO.getResign());
            addSignFranchiseResponse.setMobile(signFranchiseDO.getMobile());
            addSignFranchiseResponse.setContractCode(signFranchiseDO.getContractCode());
            addSignFranchiseResponse.setContractAmount(signFranchiseDO.getContractAmount());
            addSignFranchiseResponse.setPartnershipSignatoryFirst(signFranchiseDO.getPartnershipSignatoryFirst());
            addSignFranchiseResponse.setPartnershipSignatorySecond(signFranchiseDO.getPartnershipSignatorySecond());
            addSignFranchiseResponse.setBusinessModel(signFranchiseDO.getBusinessModel());
            addSignFranchiseResponse.setPartnershipSignatorySecondIdNumber(signFranchiseDO.getPartnershipSignatorySecondIdNumber());
            addSignFranchiseResponse.setPartnershipSignatorySecondMobile(signFranchiseDO.getPartnershipSignatorySecondMobile());
            addSignFranchiseResponse.setProtectiveDistance(signFranchiseDO.getProtectiveDistance());
            addSignFranchiseResponse.setIntroducer(signFranchiseDO.getIntroducer());
            addSignFranchiseResponse.setIntroduceStore(signFranchiseDO.getIntroduceStore());
            addSignFranchiseResponse.setIntroductionAward(signFranchiseDO.getIntroductionAward());
            addSignFranchiseResponse.setPartnershipSignatoryFirstWhichStore(signFranchiseDO.getPartnershipSignatoryFirstWhichStore());

        } 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());
            }
            addSignFranchiseResponse.setMobile(lineInfoDO.getMobile());
        }
        addSignFranchiseResponse.setStoreName(shopInfoDO.getShopName());
        addSignFranchiseResponse.setShopCode(shopInfoDO.getShopCode());
        addSignFranchiseResponse.setFranchiseBrand(shopInfoDO.getFranchiseBrand());
        addSignFranchiseResponse.setJoinMode(shopInfoDO.getJoinMode());

        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 (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());
        }

        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())));
        }
        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 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);
        }
    }
}
