package com.cool.store.service.impl;

import cn.hutool.core.bean.BeanUtil;
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.decoration.*;
import com.cool.store.dto.openPreparation.OpenPlanShopInfoDTO;
import com.cool.store.dto.openPreparation.UserNameDTO;
import com.cool.store.entity.*;
import com.cool.store.enums.*;
import com.cool.store.enums.point.PayBusinessTypeEnum;
import com.cool.store.enums.point.ShopStageEnum;
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.LineInfoMapper;
import com.cool.store.mapper.ShopInfoMapper;
import com.cool.store.request.*;

import com.cool.store.response.ThreeSignResponse;
import com.cool.store.service.*;
import com.cool.store.utils.CoolDateUtils;
import com.cool.store.utils.RedisUtilPool;
import com.cool.store.utils.poi.StringUtils;
import com.cool.store.vo.*;
import com.cool.store.vo.Fitment.DecorationStageVO;
import com.cool.store.vo.Fitment.DesignInfoVo;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * @Auther: WangShuo
 * @Date: 2024/04/28/下午4:46
 * @Version 1.0
 * @注释:
 */
@Service
public class DecorationServiceImpl implements DecorationService {

    private static final Logger log = LoggerFactory.getLogger(DecorationServiceImpl.class);

    private static final String payPic = "https://store-inspections-server.oss-cn-hangzhou.aliyuncs.com/coolstore/%E8%A3%85%E4%BF%AE%E6%AC%BE.png";
    @Resource
    private AssessmentDataDAO assessmentDataDAO;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private EnterpriseUserDAO enterpriseUserDAO;
    @Resource
    private RegionService regionService;
    @Resource
    private YlfService ylfService;
    @Resource
    private LineInfoMapper lineInfoMapper;
    @Resource
    private RegionQrcodeConfigDao regionQrcodeConfigDao;
    @Resource
    private ShopInfoDAO shopInfoDAO;
    @Resource
    private AcceptanceInfoDAO acceptanceInfoDAO;
    @Resource
    private PreparationService preparationService;
    @Resource
    private LinePayService linePayService;
    @Resource
    private ShopStageInfoDAO shopStageInfoDAO;
    @Resource
    private AssessmentDataService assessmentDataService;
    @Resource
    private UserAuthMappingService userAuthMappingService;
    @Resource
    private ShopInfoMapper shopInfoMapper;
    @Resource
    private CommonService commonService;
    @Resource
    private AssessmentTemplateService assessmentTemplateService;
    @Resource
    RedisUtilPool redisUtilPool;
    @Resource
    DecorationDesignInfoDAO decorationDesignInfoDAO;

    @Override
    public DesignInfoVo DesignInfo(Long shopId) {
        return null;
    }

    @Override
    public DecorationStageVO getDecorationGoldStage(Long shopId) {
        ShopStageInfoDO shopSubStageInfo = shopStageInfoDAO.getShopSubStageInfo(shopId, null);
        if (Objects.isNull(shopSubStageInfo)) {
            log.error("getDecorationModeStage , shopSubStageInfo is null");
            return null;
        }
        DecorationStageVO decorationStageVO = new DecorationStageVO();
        decorationStageVO.setShopSubStageStatus(shopSubStageInfo.getShopSubStageStatus());
        decorationStageVO.setPlanEndTDate(shopSubStageInfo.getPlanCompleteTime());
        decorationStageVO.setActualEndDate(shopSubStageInfo.getActualCompleteTime());
        LinePayVO linePayInfo = linePayService.
                getLinePayInfo(shopSubStageInfo.getLineId(), PayBusinessTypeEnum.DECORATION_MODEL.getCode(), shopId);
        if (Objects.nonNull(linePayInfo)) {
            decorationStageVO.setCreateDate(linePayInfo.getCreateTime());
        }
        return decorationStageVO;
    }


    @Override
    public DecorationModelDTO decorationModel(Long shopId) {
        DecorationDTO decoration = getDecorationDTO(shopId);
        if (decoration == null) {
            log.error("拉取云立方接口获取数据为空");
            return null;
        }
        //预算
        BudgetDTO proposedBookBudget = getBudgetDTOS(decoration);
        if (proposedBookBudget == null) {return null;}
        BigDecimal vzHj = proposedBookBudget.getVzHj();
        //支付二维码url
        DecorationModelDTO decorationModelDTO = new DecorationModelDTO();
        decorationModelDTO.setPayUrl(payPic);
        decorationModelDTO.setTotalAmount(vzHj);
        return decorationModelDTO;
    }

    private static @Nullable BudgetDTO getBudgetDTOS(DecorationDTO decoration) {
        List<BudgetDTO> proposedBookBudget = decoration.getProposedBookBudget();
        if (CollectionUtils.isEmpty(proposedBookBudget)) {
            log.error("云立方获取预算 is null");
            return null;
        }
        Collections.sort(decoration.getProposedBookBudget(), (x1, x2) -> x2.getId().compareTo(x1.getId()));
        BudgetDTO budgetDTO = proposedBookBudget.get(CommonConstants.ZERO);
        return budgetDTO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean submitDecorationModel(LinePaySubmitRequest request, PartnerUserInfoVO partnerUserInfoVO) {
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LinePayVO getDecorationModel(Long shopId, PartnerUserInfoVO partnerUserInfoVO) {
        //获取支付信息
        LinePayVO linePayInfo = new LinePayVO();
        if (Objects.isNull(partnerUserInfoVO)) {
            ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
            linePayInfo = linePayService.getLinePayInfo(shopInfo.getLineId(), PayBusinessTypeEnum.DECORATION_MODEL.getCode(), shopId);
        } else {
            linePayInfo = linePayService.getLinePayInfo(partnerUserInfoVO.getLineId(), PayBusinessTypeEnum.DECORATION_MODEL.getCode(), shopId);
        }
        if (Objects.isNull(linePayInfo)) {
            log.error("LinePayInfo  is null");
            return null;
        }
        //已缴费直接返回支付信息
        if (((byte) WorkflowSubStageStatusEnum.PAY_DEPOSIT_50.getCode().intValue() == linePayInfo.getPayStatus())) {
            return linePayInfo;
        }
        //云立方
        DecorationDTO decoration = getDecorationDTO(shopId);
        if (decoration == null) {
            log.error("拉取云立方接口获取数据为空");
            return null;
        }
        BudgetDTO proposedBookBudget = getBudgetDTOS(decoration);
        if (Objects.isNull(proposedBookBudget)) {
            log.error("拉取云立方接口获取缴费信息为空");
            return null;
        }
        return linePayInfo;
    }

    @Override
    public List<ConstructionScheduleDTO> getConstruction(Long shopId) {
        DecorationDTO decoration = getDecorationDTO(shopId);
        if (decoration == null) {
            log.error("DecorationModel storeNum is null");
            return null;
        }
        List<ConstructionScheduleDTO> constructionSchedule = decoration.getConstructionSchedule();
        List<ConstructionScheduleDTO> collect = new ArrayList<>();
        List<String> name = new ArrayList<>();
        name.add(CommonConstants.APPROACH);
        name.add(CommonConstants.ONE_DAY);
        name.add(CommonConstants.TWO_DAY);
        name.add(CommonConstants.THREE_DAY);
        name.add(CommonConstants.FOUR_DAY);
        name.add(CommonConstants.FIVE_DAY);
        name.add(CommonConstants.SIX_DAY);
        name.add(CommonConstants.SEVEN_DAY);
        name.add(CommonConstants.EIGHT_DAY);
        name.add(CommonConstants.WITHDRAWAL);
        ConstructionScheduleDTO approach = new ConstructionScheduleDTO();
        AcceptanceInfoDO acceptanceInfoDO = acceptanceInfoDAO.selectByShopId(shopId);

        ConstructionScheduleDTO constructionSage = new ConstructionScheduleDTO();
        ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
        LineInfoDO lineInfo = lineInfoMapper.getByLineId(shopInfo.getLineId());
        for (ConstructionScheduleDTO constructionScheduleDTO : constructionSchedule) {
            if (name.contains(constructionScheduleDTO.getName())) {
                collect.add(constructionScheduleDTO);
                if (constructionScheduleDTO.getName().equals(CommonConstants.APPROACH)) {
                    approach = constructionScheduleDTO;
                }
                //计划撤场时间 //如果撤场并且视觉验收状态为-100则更新待验收
//                if (constructionScheduleDTO.getName().equals(CommonConstants.WITHDRAWAL)) {
//                    ShopStageInfoDO shopSubStageInfo = shopStageInfoDAO.getShopSubStageInfo(shopId, ShopSubStageEnum.SHOP_STAGE_13);
//                    if(shopSubStageInfo.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_00.getShopSubStageStatus())
//                            && constructionScheduleDTO.getState().equals(ConstructionPhaseEnum.construction_FINSH.getCode())){
//                        //发送给品牌设计经理
//                        EnterpriseUserDO enterpriseUser = userAuthMappingService.getUserByRoleEnumAndWantShopAreaId(UserRoleEnum.DESIGN_MANAGER, lineInfo.getWantShopAreaId());
//                        if (Objects.nonNull(enterpriseUser)){
//                            Map<String, String> messageMap = new HashMap<>();
//                            messageMap.put("storeName",shopInfo.getShopName());
//                            messageMap.put("shopId",String.valueOf(shopId));
//                            messageMap.put("shopName",shopInfo.getShopName());
//                            messageMap.put("partnerUsername",lineInfo.getUsername());
//                            messageMap.put("partnerMobile",lineInfo.getMobile());
//                            commonService.sendMessage(Arrays.asList(enterpriseUser.getUserId()), MessageEnum.MESSAGE_28, messageMap);
//                        }
//                    }
//                    ConstructionScheduleDTO withdrawal = constructionScheduleDTO;
//                    if (Objects.nonNull(acceptanceInfoDO)) {
//                        Date date = CoolDateUtils.parseDate(withdrawal.getPlanBeginDate(), CoolDateUtils.DATE_FORMAT_DAY);
//                        acceptanceInfoDO.setPlanExitTime(date);
//                    }
//                }
            }
            if (constructionScheduleDTO.getName().equals(CommonConstants.CONSTRUCTION_PHASE)) {
                constructionSage = constructionScheduleDTO;
            }
        }

        //设置进场时间xfsg_acceptance_info
        if (Objects.nonNull(acceptanceInfoDO) && StringUtils.isNotEmpty(approach.getActualBeginDate())) {
            Date date = CoolDateUtils.parseDate(approach.getActualBeginDate(), CoolDateUtils.DATE_FORMAT_DAY);
            acceptanceInfoDO.setActualEntryTime(date);
        }
        //施工完成时间,计划开始和完成时间 //
        if (Objects.nonNull(acceptanceInfoDO) && StringUtils.isNotEmpty(constructionSage.getActualEndDate())) {
            Date date = CoolDateUtils.parseDate(constructionSage.getActualEndDate(), CoolDateUtils.DATE_FORMAT_DAY);
            acceptanceInfoDO.setConstructionCompletionTime(date);
        }
        if (Objects.nonNull(acceptanceInfoDO) && StringUtils.isNotEmpty(constructionSage.getPlanBeginDate())) {
            Date date = CoolDateUtils.parseDate(constructionSage.getPlanBeginDate(), CoolDateUtils.DATE_FORMAT_DAY);
            acceptanceInfoDO.setPlannedStartTime(date);
        }
        if (Objects.nonNull(acceptanceInfoDO) && StringUtils.isNotEmpty(constructionSage.getPlanEndDate())) {
            Date date = CoolDateUtils.parseDate(constructionSage.getPlanEndDate(), CoolDateUtils.DATE_FORMAT_DAY);
            acceptanceInfoDO.setPlannedCompletionTime(date);
        }
        acceptanceInfoDO.setUpdateTime(new Date());
        acceptanceInfoDAO.updateAcceptanceInfo(acceptanceInfoDO);


        //如果完成更新施工阶段状态
//        if (ConstructionPhaseEnum.construction_FINSH.getCode().equals(constructionSage.getState())) {
//            shopStageInfoDAO.updateShopStageInfo(shopId, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_112);
//        } else {
//            shopStageInfoDAO.updateShopStageInfo(shopId, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_111);
//        }
        return collect;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ConstructionScheduleDTO getConstructionInfo(Long shopId) {
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean submitThreeCheck(ThreeAcceptanceCheckRequest request) {
        log.info("submitThreeCheck, request:{} ", JSONObject.toJSONString(request));
        ShopStageInfoDO shopSubStageInfo = shopStageInfoDAO.getShopSubStageInfo(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_12);
        if (shopSubStageInfo.getShopSubStageStatus()>ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_121.getShopSubStageStatus()){
            throw new ServiceException(ErrorCodeEnum.PARAMS_REQUIRED);
        }
        List<AssessmentTemplateVO> assessmentTemplateVOS = assessmentTemplateService.listByType(AssessmentTemplateType.TRIPARTITE_ACCEPTANCE.getCode());
        Long max = assessmentTemplateVOS.stream().mapToLong(AssessmentTemplateVO::getId).max().orElse(0L);
        Long min = assessmentTemplateVOS.stream().mapToLong(AssessmentTemplateVO::getId).min().orElse(0L);
        List<AssessmentDataDO> assessmentDataDOList = assessmentDataDAO.selectListByShopId(request.getShopId(), min, max);
        List<AssessmentDataDO> assessmentDataDOS = new ArrayList<>();
        for (AssessmentDataDTO assessmentDataDTO : request.getAssessmentDataDTOS()) {
            AssessmentDataDO assessmentDataDO = new AssessmentDataDO();
            assessmentDataDO.setId(assessmentDataDTO.getId());
            assessmentDataDO.setTemplateId(assessmentDataDTO.getTemplateId());
            assessmentDataDO.setQualified(assessmentDataDTO.getQualified());
            assessmentDataDO.setReason(assessmentDataDTO.getReason());
            assessmentDataDO.setComments(assessmentDataDTO.getComments());
            assessmentDataDO.setShopId(request.getShopId());
            assessmentDataDOS.add(assessmentDataDO);
        }
        if (CollectionUtils.isNotEmpty(assessmentDataDOList)) {
            assessmentDataService.batchUpdate(assessmentDataDOS);
        } else {
            assessmentDataService.batchInsertSelective(assessmentDataDOS);
        }
        shopStageInfoDAO.updateShopStageInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_122);
        return Boolean.TRUE;
    }

    @Override
    public ThreeAcceptanceCheckRequest getThreeChecks(Long shopId) {
        List<AssessmentTemplateVO> assessmentTemplateVOS = assessmentTemplateService.listByType(AssessmentTemplateType.TRIPARTITE_ACCEPTANCE.getCode());
        Long max = assessmentTemplateVOS.stream().mapToLong(AssessmentTemplateVO::getId).max().orElse(0L);
        Long min = assessmentTemplateVOS.stream().mapToLong(AssessmentTemplateVO::getId).min().orElse(0L);
        List<AssessmentDataDO> assessmentDataDOS = assessmentDataDAO.selectListByShopId(shopId, min, max);
        if (CollectionUtils.isEmpty(assessmentDataDOS)) {
            log.error("该用户门店三方验收检查项为空");
            return null;
        }
        List<AssessmentDataDTO> assessmentDataDTOS = new ArrayList<>();
        for (AssessmentDataDO assessmentDataDO : assessmentDataDOS) {
            AssessmentDataDTO assessmentDataDTO = new AssessmentDataDTO();
            BeanUtil.copyProperties(assessmentDataDO, assessmentDataDTO);
            assessmentDataDTOS.add(assessmentDataDTO);
        }
        ThreeAcceptanceCheckRequest threeAcceptanceCheckRequest = new ThreeAcceptanceCheckRequest();
        threeAcceptanceCheckRequest.setShopId(shopId);
        threeAcceptanceCheckRequest.setAssessmentDataDTOS(assessmentDataDTOS);
        return threeAcceptanceCheckRequest;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean miniSubmitAcceptanceSign(ThreeAcceptanceRequest request) {
        //加盟商
        if (Objects.nonNull(request.getPartnerAcceptance())) {
            request.getPartnerAcceptance().setStatus(CommonConstants.ONE);
            request.getPartnerAcceptance().setAcceptanceTime(new Date());
            String jsonString = JSONObject.toJSONString(request.getPartnerAcceptance());
            AcceptanceInfoDO acceptanceInfoDO = new AcceptanceInfoDO();
            acceptanceInfoDO.setShopId(request.getShopId());
            acceptanceInfoDO.setPartnerAcceptanceSignatures(jsonString);
            acceptanceInfoDO.setUpdateTime(new Date());
            acceptanceInfoDAO.updateAcceptanceInfo(acceptanceInfoDO);
        }
        //更新阶段状态验收中
        shopStageInfoDAO.updateShopStageInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_122);
        return Boolean.TRUE;
    }

    @Override
    public PageInfo<fitmentCheckVO> getFitmentAcceptanceList(AcceptanceListRequest request, LoginUserInfo user) {
        List<String> authRegionIds = userAuthMappingService.getAuthRegionIdAndSubRegionIdByUserId(user.getUserId());
        List<Long> regions = new ArrayList<>();
        for (String authRegionId : authRegionIds) {
            regions.add(Long.parseLong(authRegionId));
        }
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        if (regions.isEmpty()) {
            log.info("该用户下权限没有管理区域");
            return new PageInfo<>();
        }
        List<fitmentCheckVO> fitmentCheckVOList = new ArrayList<>();
        //shopId,lineid,regionid,shopname,storenum,

        List<ShopInfoDO> shopInfoDOS = shopInfoMapper.selectShopListByRegionId(regions, ShopSubStageEnum.SHOP_STAGE_12.getShopSubStage(),request.getSubStageStatus(),null);
        PageInfo pageInfo = new PageInfo<>(shopInfoDOS);
        if (shopInfoDOS.isEmpty()) {
            log.info("该工程部监理下门店为空");
            return pageInfo;
        }
        Map<Long, ShopInfoDO> ShopIdmap = shopInfoDOS.stream().collect(Collectors.toMap(ShopInfoDO::getId, dto1 -> dto1));
        //招商经理，选址人员（拓展经理）id
        List<Long> lineIds = shopInfoDOS.stream().filter(o -> o.getLineId() != null)
                .map(ShopInfoDO::getLineId).distinct().collect(Collectors.toList());
        List<LineInfoDO> lineInfos = lineInfoMapper.getByLineIds(lineIds);
        Map<Long, LineInfoDO> lineInfoDOMap = lineInfos.stream().collect(Collectors.toMap(LineInfoDO::getId, dto -> dto));
        //招商name
        List<String> userIds = new ArrayList<>();
        userIds.addAll(lineInfos.stream().filter(o -> o.getInvestmentManager() != null)
                .map(LineInfoDO::getInvestmentManager).distinct().collect(Collectors.toList()));
        //选址人员（拓展经理）name
        userIds.addAll(lineInfos.stream().filter(o -> o.getDevelopmentManager() != null)
                .map(LineInfoDO::getDevelopmentManager).distinct().collect(Collectors.toList()));
        Map<String, String> userNameMap = enterpriseUserDAO.getUserNameMap(userIds);
        //所属战区
        List<Long> regionIds = shopInfoDOS.stream().filter(o -> o.getRegionId() != null).
                map(ShopInfoDO::getRegionId).distinct().collect(Collectors.toList());
        Map<Long, String> regionNameMap = regionService.getBelongWarRegionNameMap(regionIds);
        //战区经理name
        Map<Long, String> fightManger = new HashMap<>();
        for (Long regionId : regionIds) {
            String fightMangerUserId = sysRoleService.getUserIdByRegionIdWithRolePriority(regionId, Arrays.asList(UserRoleEnum.THEATER_MANAGER));
            String userName = enterpriseUserDAO.getUserName(fightMangerUserId);
            fightManger.put(regionId, userName);
        }
        //施工计划完成时间 //施工实际完成实际//计划验收时间//验收实际时间
        List<Long> shopIds = new ArrayList<>(ShopIdmap.keySet());
        List<AcceptanceInfoDO> acceptanceInfoDOS = acceptanceInfoDAO.selectByShopIds(shopIds);
        Map<Long, AcceptanceInfoDO> acceptanceInfoDOSMap = acceptanceInfoDOS.stream()
                .collect(Collectors.toMap(AcceptanceInfoDO::getShopId, dto1 -> dto1));
        //验收状态
        List<ShopStageInfoDO> subStageList = shopStageInfoDAO.getSubStageList(shopIds, ShopSubStageEnum.SHOP_STAGE_12.getShopSubStage());
        Map<Long, ShopStageInfoDO> ShopStageInfoDOMap = subStageList.stream()
                .collect(Collectors.toMap(ShopStageInfoDO::getShopId, dto1 -> dto1));
        for (ShopInfoDO shopInfoDO : shopInfoDOS) {
            Long shopId = shopInfoDO.getId();
            Long lineId = shopInfoDO.getLineId();
            Long regionId = shopInfoDO.getRegionId();
            fitmentCheckVO fitmentCheckVO = new fitmentCheckVO();
            fitmentCheckVO.setShopId(shopId);
            fitmentCheckVO.setLineId(lineId);
            fitmentCheckVO.setShopName(shopInfoDO.getShopName());
            fitmentCheckVO.setStoreNum(shopInfoDO.getStoreNum());
            fitmentCheckVO.setShopCode(shopInfoDO.getShopCode());
            fitmentCheckVO.setRegionId(regionId);
            fitmentCheckVO.setRegion(regionNameMap.get(regionId));
            fitmentCheckVO.setFightManager(fightManger.get(regionId));
            if (lineId != null) {
                LineInfoDO a = lineInfoDOMap.getOrDefault(lineId, new LineInfoDO());
                fitmentCheckVO.setInvestmentManagerId(a.getInvestmentManager());
                fitmentCheckVO.setInvestmentManager(userNameMap.getOrDefault(a.getInvestmentManager(), ""));
                fitmentCheckVO.setSitterId(a.getDevelopmentManager());
                fitmentCheckVO.setSitterName(userNameMap.getOrDefault(a.getDevelopmentManager(), ""));
                fitmentCheckVO.setPartnerName(a.getUsername());
            }
            AcceptanceInfoDO acceptanceInfoDO = acceptanceInfoDOSMap.get(shopId);
            if (shopId != null) {
                if (Objects.nonNull(acceptanceInfoDO)) {
                    fitmentCheckVO.setPlanEndTime(acceptanceInfoDO.getDecorationPlannedCompletionTime());
                    fitmentCheckVO.setActualEndTime(acceptanceInfoDO.getConstructionCompletionTime());
                    fitmentCheckVO.setPlanAcceptanceTime(acceptanceInfoDO.getPlanAcceptanceTime());
                    fitmentCheckVO.setAcceptanceTime(acceptanceInfoDO.getActualAcceptanceTime());
                }
            }
            if (Objects.nonNull(ShopStageInfoDOMap.get(shopId))) {
                fitmentCheckVO.setShopSubStageStatus(ShopStageInfoDOMap.getOrDefault(shopId,new ShopStageInfoDO()).getShopSubStageStatus());
            }
            fitmentCheckVOList.add(fitmentCheckVO);
        }
        pageInfo.setList(fitmentCheckVOList);
        return pageInfo;
    }

    @Override
    public fitmentCheckVO getAcceptanceDetail(Long shopId, LoginUserInfo user) {
        fitmentCheckVO fitmentCheckVO = new fitmentCheckVO();
        ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
        if (Objects.isNull(shopInfo)) {
            log.error("店铺信息不存在 shopId:{}", shopId);
            return null;
        }
        //招商经理，选址人员（拓展经理）id
        Long lineId = shopInfo.getLineId();
        LineInfoDO lineInfo = lineInfoMapper.getByLineId(lineId);
        if (Objects.isNull(lineInfo)) {
            log.error("线索信息不存在 shopId:{}", shopId);
            return null;
        }
        //招商name
        List<String> userIds = new ArrayList<>();
        userIds.add(lineInfo.getInvestmentManager());
        //选址人员（拓展经理）name
        userIds.add(lineInfo.getDevelopmentManager());
        Map<String, String> userNameMap = enterpriseUserDAO.getUserNameMap(userIds);
        //所属战区
        Long regionId = shopInfo.getRegionId();
        String regionName = regionService.getBelongWarRegionName(regionId);
        //战区经理name
        String fightMangerUserId = sysRoleService.getUserIdByRegionIdWithRolePriority(regionId, Arrays.asList(UserRoleEnum.THEATER_MANAGER));
        String fightName = enterpriseUserDAO.getUserName(fightMangerUserId);
        //施工计划完成时间 //施工实际完成实际//计划验收时间//验收实际时间
        AcceptanceInfoDO acceptanceInfoDOS = acceptanceInfoDAO.selectByShopId(shopId);
        //验收状态
        ShopStageInfoDO subStage = shopStageInfoDAO.getShopSubStageInfo(shopId, ShopSubStageEnum.SHOP_STAGE_12);
        fitmentCheckVO.setShopId(shopId);
        fitmentCheckVO.setLineId(lineId);
        fitmentCheckVO.setShopName(shopInfo.getShopName());
        fitmentCheckVO.setStoreNum(shopInfo.getStoreNum());
        fitmentCheckVO.setShopCode(shopInfo.getShopCode());
        fitmentCheckVO.setPartnerName(lineInfo.getUsername());
        fitmentCheckVO.setRegionId(regionId);
        fitmentCheckVO.setRegion(regionName);
        fitmentCheckVO.setFightManager(fightName);
        if (userNameMap != null) {
            fitmentCheckVO.setInvestmentManager(userNameMap.get(lineInfo.getInvestmentManager()));
            fitmentCheckVO.setSitterName(userNameMap.get(lineInfo.getDevelopmentManager()));
        }
        if (Objects.nonNull(acceptanceInfoDOS)) {
            fitmentCheckVO.setPlanEndTime(acceptanceInfoDOS.getDecorationPlannedCompletionTime());
            fitmentCheckVO.setActualEndTime(acceptanceInfoDOS.getConstructionCompletionTime());
            fitmentCheckVO.setPlanAcceptanceTime(acceptanceInfoDOS.getPlanAcceptanceTime());
            fitmentCheckVO.setAcceptanceTime(acceptanceInfoDOS.getActualAcceptanceTime());
        }
        fitmentCheckVO.setShopSubStageStatus(subStage.getShopSubStageStatus());
        return fitmentCheckVO;
    }

    @Override
    public Boolean submitDecorationDesign(DecorationDesignRequest request, LoginUserInfo user) {
        //重复提交校验 3秒内不能重复提交
        String lockKey = "submitDecorationDesign:" + request.getShopId();
        String lockValue = UUID.randomUUID().toString();
        boolean acquired = redisUtilPool.setNxExpire(lockKey, lockValue, CommonConstants.THREE*CommonConstants.ONE_SECONDS);
        if (!acquired){
            throw new ServiceException(ErrorCodeEnum.DUPLICATE_SUBMISSION);
        }
        //校验参数
        if (Objects.isNull(request)||request.getShopId()==null){
            throw new ServiceException(ErrorCodeEnum.PARAMS_REQUIRED);
        }
        //必须是待提交状态才能提交
        ShopStageInfoDO shopStageInfo = shopStageInfoDAO.getByShopIdAndSubStage(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_9.getShopSubStage());
        if (shopStageInfo!=null&&!ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_90.getShopSubStageStatus().equals(shopStageInfo.getShopSubStageStatus())) {
            throw new ServiceException(ErrorCodeEnum.STATUS_NOT_SUPPORT_SUMMIT);
        }
        DecorationDesignInfoDO decorationDesignInfoDO = request.toDecorationDesignInfoDO();
        DecorationDesignInfoDO decoration = decorationDesignInfoDAO.getByShopId(request.getShopId());
        if (Objects.nonNull(decoration)){
            decorationDesignInfoDO.setId(decoration.getId());
            decorationDesignInfoDAO.updateByPrimaryKeySelective(decorationDesignInfoDO);
        }else {
            decorationDesignInfoDAO.insertSelective(decorationDesignInfoDO);
        }
        //更新装修设计状态
        shopStageInfoDAO.updateShopStageInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_905);
        ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(request.getShopId());
        LineInfoDO lineInfo = lineInfoMapper.getByLineId(shopInfo.getLineId());
        Map<String, String> templateParam = new HashMap<>();
        templateParam.put("shopName", shopInfo.getShopName());
        commonService.sendSms(lineInfo.getMobile(),SMSMsgEnum.DESIGN_STAGE,templateParam);
        return Boolean.TRUE;
    }

    @Override
    public DecorationDesignVO getDecorationDesign(Long shopId) {
        if (shopId==null){
            throw new ServiceException(ErrorCodeEnum.PARAMS_REQUIRED);
        }
        DecorationDesignInfoDO decoration = decorationDesignInfoDAO.getByShopId(shopId);
        if (!Objects.isNull(decoration)){
            DecorationDesignVO decorationDesignVO = new DecorationDesignVO();
            decorationDesignVO.setDesignUrl(decoration.getDesignUrl());
            decorationDesignVO.setRemark(decoration.getRemark());
            decorationDesignVO.setQuotationUrl(decoration.getQuotationUrl());
            decorationDesignVO.setShopId(decoration.getShopId());
            decorationDesignVO.setPartnerAcceptanceSignatures(decoration.getPartnerAcceptanceSignatures());
            return decorationDesignVO;
        }
        return null;
    }

    @Override
    public Boolean submitConstructionData(ConstructionRequest request, LoginUserInfo user) {
        String lockKey = "submitConstructionData:" + request.getShopId();
        String lockValue = UUID.randomUUID().toString();
        boolean acquired = redisUtilPool.setNxExpire(lockKey, lockValue, CommonConstants.THREE*CommonConstants.ONE_SECONDS);
        if (!acquired){
            throw new ServiceException(ErrorCodeEnum.DUPLICATE_SUBMISSION);
        }
        //校验参数
        if (Objects.isNull(request)||request.getShopId()==null){
            throw new ServiceException(ErrorCodeEnum.PARAMS_REQUIRED);
        }
        //必须是待提交状态才能提交
        ShopStageInfoDO shopStageInfo = shopStageInfoDAO.getByShopIdAndSubStage(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_11.getShopSubStage());
        if (shopStageInfo!=null&&!ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_110.getShopSubStageStatus().equals(shopStageInfo.getShopSubStageStatus())) {
            throw new ServiceException(ErrorCodeEnum.STATUS_NOT_SUPPORT_SUMMIT);
        }
        DecorationDesignInfoDO decoration = decorationDesignInfoDAO.getByShopId(request.getShopId());
        decoration.setConstructionAnnex(request.getConstructionAnnex());
        decoration.setConstructionRemark(request.getConstructionRemark());
        decoration.setConstructionPlanStartTime(new Date(request.getConstructionPlanStartTime()));
        decoration.setConstructionPlanEndTime(new Date(request.getConstructionPlanEndTime()));
        decoration.setConstructionCreateTime(new Date());
        decoration.setConstructionCreateUser(user.getUserId());
        decorationDesignInfoDAO.updateByPrimaryKeySelective(decoration);
        //状态变为施工中
        shopStageInfoDAO.batchUpdateShopStageStatus(request.getShopId(), Arrays.asList(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_111));
        return Boolean.TRUE;
    }

    @Override
    public ConstructionDataVO getConstructionData(Long shopId) {
        ConstructionDataVO constructionDataVO = new ConstructionDataVO();
        DecorationDesignInfoDO decoration = decorationDesignInfoDAO.getByShopId(shopId);
        if (Objects.isNull(decoration)){
            return constructionDataVO;
        }
        constructionDataVO.setConstructionAnnex(decoration.getConstructionAnnex());
        constructionDataVO.setConstructionRemark(decoration.getConstructionRemark());
        constructionDataVO.setConstructionPlanStartTime(decoration.getConstructionPlanStartTime()!=null?decoration.getConstructionPlanStartTime().getTime():null);
        constructionDataVO.setConstructionPlanEndTime(decoration.getConstructionPlanEndTime()!=null?decoration.getConstructionPlanEndTime().getTime():null);
        constructionDataVO.setConstructionCreateTime(decoration.getConstructionCreateTime()!=null?decoration.getConstructionCreateTime().getTime():null);
        constructionDataVO.setConstructionCreateUser(decoration.getConstructionCreateUser());
        if (StringUtils.isNotEmpty(decoration.getConstructionCreateUser())){
            EnterpriseUserDO user = enterpriseUserDAO.getUserInfoById(decoration.getConstructionCreateUser());
            constructionDataVO.setConstructionCreateUserName(user.getName());
        }
        return constructionDataVO;
    }

    @Override
    public Boolean confirmDesign(DecorationDesignRequest request, LoginUserInfo user) {
        //重复提交校验 3秒内不能重复提交
        String lockKey = "confirmDesign:" + request.getShopId();
        String lockValue = UUID.randomUUID().toString();
        boolean acquired = redisUtilPool.setNxExpire(lockKey, lockValue, CommonConstants.THREE*CommonConstants.ONE_SECONDS);
        if (!acquired){
            throw new ServiceException(ErrorCodeEnum.DUPLICATE_SUBMISSION);
        }
        DecorationDesignInfoDO decorationDesignInfoDO = request.toDecorationDesignInfoDO();
        DecorationDesignInfoDO decoration = decorationDesignInfoDAO.getByShopId(request.getShopId());
        if (Objects.nonNull(decoration)){
            decorationDesignInfoDO.setId(decoration.getId());
            decorationDesignInfoDAO.updateByPrimaryKeySelective(decorationDesignInfoDO);
        }
        //更新装修设计状态
        shopStageInfoDAO.batchUpdateShopStageStatus(request.getShopId(), Arrays.asList(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_91, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_110));
        return Boolean.TRUE;
    }

    @Override
    public Boolean confirmComplete(Long shopId, LoginUserInfo user) {
        //判断施工阶段是否时施工中 施工中才能施工完成
        ShopStageInfoDO shopStageInfoDO = shopStageInfoDAO.getByShopIdAndSubStage(shopId, ShopSubStageEnum.SHOP_STAGE_11.getShopSubStage());
        if (shopStageInfoDO!=null && !ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_111.getShopSubStageStatus().equals(shopStageInfoDO.getShopSubStageStatus())){
            throw new ServiceException(ErrorCodeEnum.DESIGN_NO_COMPLETE);
        }
        AcceptanceInfoDO acceptance = acceptanceInfoDAO.selectByShopId(shopId);
        if(Objects.isNull(acceptance)) {
            AcceptanceInfoDO acceptanceInfoDO = new AcceptanceInfoDO();
            acceptanceInfoDO.setShopId(shopId);
            acceptanceInfoDO.setCreateTime(new Date());
            acceptanceInfoDAO.insertSelectiveAcceptanceInfo(acceptanceInfoDO);
        }
        shopStageInfoDAO.batchUpdateShopStageStatus(shopId, Arrays.asList(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_112, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_121));
        ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
        LineInfoDO lineInfo = lineInfoMapper.getByLineId(shopInfo.getLineId());
        Map<String, String> templateParam = new HashMap<>();
        templateParam.put("shopName", shopInfo.getShopName());
        commonService.sendSms(lineInfo.getMobile(),SMSMsgEnum.CONSTRUCTION_STAGE,templateParam);
        return Boolean.TRUE;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean pcSubmitAcceptanceSign(ThreeAcceptanceRequest request) {
        log.info("submitAcceptance, request:{} ", JSONObject.toJSONString(request));
        //营运部 验收签名
        AcceptanceInfoDO acceptanceInfoDO1 = acceptanceInfoDAO.selectByShopId(request.getShopId());
        if (StringUtils.isNotEmpty(acceptanceInfoDO1.getPartnerAcceptanceSignatures())
                && Objects.nonNull(request.getOperationsAcceptance())) {
            ThreeAcceptanceDTO partner = JSONObject.parseObject(acceptanceInfoDO1.getPartnerAcceptanceSignatures(), ThreeAcceptanceDTO.class);
            request.getOperationsAcceptance().setStatus(CommonConstants.ONE);
            request.getOperationsAcceptance().setAcceptanceTime(new Date());
            String jsonString = JSONObject.toJSONString(request.getOperationsAcceptance());
            AcceptanceInfoDO acceptanceInfoDO = new AcceptanceInfoDO();
            acceptanceInfoDO.setShopId(request.getShopId());
            acceptanceInfoDO.setOperationsAcceptanceSignatures(jsonString);
            acceptanceInfoDO.setUpdateTime(new Date());
            acceptanceInfoDO.setActualAcceptanceTime(new Date());
            acceptanceInfoDAO.updateAcceptanceInfo(acceptanceInfoDO);
            if (CommonConstants.ONE == request.getOperationsAcceptance().getResult()
                    && CommonConstants.ONE == partner.getResult()) {
                //更新阶段状态验收完毕
                shopStageInfoDAO.updateShopStageAndAuditInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_123, null);
            } else {
                //未通过至为待验收
                shopStageInfoDAO.updateShopStageAndAuditInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_121, null);
            }
        }
        return Boolean.TRUE;
    }

    @Override
    public ThreeSignResponse getThreeAcceptanceSign(Long shopId) {
        ThreeSignResponse threeSignResponse = new ThreeSignResponse();
        AcceptanceInfoDO acceptanceInfoDO = acceptanceInfoDAO.selectByShopId(shopId);
        if (Objects.isNull(acceptanceInfoDO)) {
            return threeSignResponse;
        }
        //工程部
        if (StringUtils.isNotEmpty(acceptanceInfoDO.getEngineeringAcceptanceSignatures())) {
            ThreeAcceptanceDTO engineering = JSONObject.parseObject(acceptanceInfoDO.getEngineeringAcceptanceSignatures(), ThreeAcceptanceDTO.class);
            threeSignResponse.setEngineeringAcceptance(engineering);
        }
        //营运部
        if (StringUtils.isNotEmpty(acceptanceInfoDO.getOperationsAcceptanceSignatures())) {
            ThreeAcceptanceDTO operations = JSONObject.parseObject(acceptanceInfoDO.getOperationsAcceptanceSignatures(), ThreeAcceptanceDTO.class);
            threeSignResponse.setOperationsAcceptance(operations);
        }
        //加盟商
        if (StringUtils.isNotEmpty(acceptanceInfoDO.getPartnerAcceptanceSignatures())) {
            ThreeAcceptanceDTO partner = JSONObject.parseObject(acceptanceInfoDO.getPartnerAcceptanceSignatures(), ThreeAcceptanceDTO.class);
            threeSignResponse.setPartnerAcceptance(partner);
        }
        return threeSignResponse;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean bookingAcceptance(BookingAcceptanceRequest request, LoginUserInfo user) {
        return Boolean.TRUE;
    }


    private DecorationDTO getDecorationDTO(Long shopId) {
        ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
        if (Objects.isNull(shopInfo)) {
            throw new ServiceException(ErrorCodeEnum.SHOP_ID_NOT_EXIST);
        }
        String storeNum = shopInfo.getStoreNum();
        if (StringUtils.isNotEmpty(storeNum)) {
            ProjectDTO projectList = ylfService.getProjectList(storeNum);
            Long projectId = projectList.getProjectId();
            DecorationDTO decoration = ylfService.getDecoration(projectId);
            return decoration;
        }
        return null;
    }

}
