package com.cool.store.service.impl;

import com.cool.store.constants.CommonConstants;
import com.cool.store.dao.*;
import com.cool.store.dto.Preparation.PreparationDTO;
import com.cool.store.dto.Preparation.ScheduleDTO;
import com.cool.store.dto.decoration.ConstructionScheduleDTO;
import com.cool.store.dto.decoration.DecorationDTO;
import com.cool.store.dto.decoration.ProjectDTO;
import com.cool.store.dto.openPreparation.OpenPlanShopInfoDTO;
import com.cool.store.entity.*;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.MessageEnum;
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.request.PreparationRequest;
import com.cool.store.service.*;
import com.cool.store.utils.poi.DateUtils;
import com.cool.store.utils.poi.StringUtils;
import com.cool.store.utils.poi.constant.Constants;
import com.cool.store.vo.Preparation.PreparationProcessVO;
import com.cool.store.vo.Preparation.PreparationScheduleDetailVO;
import com.cool.store.vo.Preparation.PreparationScheduleVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author suzhuhong
 * @Date 2024/4/22 16:21
 * @Version 1.0
 */
@Service
public class PreparationServiceImpl implements PreparationService {

    private static final Logger log = LoggerFactory.getLogger(PreparationServiceImpl.class);
    @Resource
    private CommonService commonService;
    @Resource
    private ShopStageInfoDAO shopStageInfoDAO;
    @Resource
    private OpenAcceptanceInfoDAO openAcceptanceInfoDAO;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private UserAuthMappingService userAuthMappingService;
    @Resource
    private RegionService regionService;
    @Resource
    ShopInfoDAO shopInfoDAO;
    @Resource
    EnterpriseUserDAO enterpriseUserDAO;
    @Resource
    LineInfoDAO lineInfoDAO;
    @Resource
    private AcceptanceInfoDAO acceptanceInfoDAO;
    @Resource
    private DecorationService decorationService;

    @Override
    public PageInfo<PreparationScheduleVO> getPreparationSchedule(PreparationRequest request) {
        if (!sysRoleService.checkIsAdmin(request.getCurUserId())) {
            request.setAuthRegionIds(userAuthMappingService.getAuthRegionIdAndSubRegionIdByUserId(request.getCurUserId()));
        }
        if (CollectionUtils.isNotEmpty(request.getRegionIds())) {
            if (request.getRegionIds().contains(CommonConstants.ROOT_DEPT_ID_STR)) {
                request.setRegionIds(null);
            } else {
                request.setRegionIds(regionService.getSubRegionIdsByRegionIds(request.getRegionIds()));
            }
        }
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        //开业进度数据
        List<PreparationDTO> preparationDTOS = shopInfoDAO.ListByCondition(request);
        PageInfo pageInfo = new PageInfo<>(preparationDTOS);
        List<Long> shopIds = preparationDTOS.stream().map(PreparationDTO::getId).collect(Collectors.toList());
        List<ScheduleDTO> scheduleList = shopStageInfoDAO.getScheduleList(shopIds);
        List<ShopStageInfoDO> shopContractActualCompletionTime = shopStageInfoDAO.getShopContractActualCompletionTime(shopIds);
        Map<Long, ScheduleDTO> scheduleDTOMap = scheduleList.stream().collect(Collectors.toMap(ScheduleDTO::getShopId, x -> x));
        Map<Long, ShopStageInfoDO> shopStageInfoDOMap = shopContractActualCompletionTime.stream().collect(Collectors.toMap(ShopStageInfoDO::getShopId, x -> x));
        List<Long> regionIds = preparationDTOS.stream().map(PreparationDTO::getRegionId).collect(Collectors.toList());
        Map<Long, String> regionNameMap = regionService.getBelongWarRegionNameMap(regionIds);
        Set<String> userIds = preparationDTOS.stream().filter(x -> StringUtils.isNotEmpty(x.getShopManagerUserId())).map(PreparationDTO::getShopManagerUserId).collect(Collectors.toSet());
        userIds.addAll(preparationDTOS.stream().filter(x -> StringUtils.isNotEmpty(x.getInvestmentManager())).map(PreparationDTO::getInvestmentManager).collect(Collectors.toSet()));
        userIds.addAll(preparationDTOS.stream().filter(x -> StringUtils.isNotEmpty(x.getSupervisorUserId())).map(PreparationDTO::getSupervisorUserId).collect(Collectors.toSet()));
        Map<String, EnterpriseUserDO> userInfoMap = enterpriseUserDAO.getUserInfoMap(new ArrayList<>(userIds));

        List<PreparationScheduleVO> preparationScheduleVOS = new ArrayList<>();
        preparationDTOS.forEach(x -> {
            PreparationScheduleVO preparationScheduleVO = new PreparationScheduleVO();
            preparationScheduleVO.setMobile(x.getMobile());
            preparationScheduleVO.setUsername(x.getUsername());
            preparationScheduleVO.setShopId(x.getId());
            preparationScheduleVO.setLineId(x.getLineId());
            preparationScheduleVO.setShopName(x.getShopName());
            preparationScheduleVO.setPlanOpenTime(x.getPlanOpenTime());
            preparationScheduleVO.setStoreNum(x.getStoreNum());
            preparationScheduleVO.setShopManagerUserName(userInfoMap.getOrDefault(x.getShopManagerUserId(), new EnterpriseUserDO()).getName());
            preparationScheduleVO.setSupervisionName(userInfoMap.getOrDefault(x.getSupervisorUserId(), new EnterpriseUserDO()).getName());
            preparationScheduleVO.setInvestmentManagerName(userInfoMap.getOrDefault(x.getInvestmentManager(), new EnterpriseUserDO()).getName());
            preparationScheduleVO.setRegionNodeName(regionNameMap.getOrDefault(x.getRegionId(), ""));
            ScheduleDTO dto = scheduleDTOMap.getOrDefault(x.getId(), new ScheduleDTO());
            preparationScheduleVO.setCompletionColumn(dto.getCompletionColumn());
            //-1 去掉视觉验收
            preparationScheduleVO.setTotalColumn(dto.getTotalColumn()-1);
            ShopStageInfoDO stageInfoDO = shopStageInfoDOMap.getOrDefault(x.getId(), new ShopStageInfoDO());
            if (StringUtils.isNotEmpty(stageInfoDO.getActualCompleteTime())) {
                preparationScheduleVO.setContractCompletionTime(DateUtils.strToDate(stageInfoDO.getActualCompleteTime(), DateUtils.YYYY_MM_DD_HH_MM_SS));
            }
            preparationScheduleVO.setDays();
            preparationScheduleVOS.add(preparationScheduleVO);
        });
        pageInfo.setList(preparationScheduleVOS);
        return pageInfo;
    }

    @Override
    public PreparationScheduleDetailVO getPreparationDetail(Long shopId) {
        ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
        if (shopInfo == null) {
            throw new ServiceException(ErrorCodeEnum.SHOP_ID_IS_NULL);
        }
        LineInfoDO lineInfo = lineInfoDAO.getLineInfo(shopInfo.getLineId());

        List<ScheduleDTO> shopContractActualCompletionTime = shopStageInfoDAO.getScheduleList(Collections.singletonList(shopId));
        PreparationScheduleDetailVO preparationScheduleDetailVO = new PreparationScheduleDetailVO();
        List<ShopStageInfoDO> shop = shopStageInfoDAO.getShopContractActualCompletionTime(Collections.singletonList(shopId));
        Set<Object> userSet = new HashSet<>();
        if (StringUtils.isNotEmpty(lineInfo.getInvestmentManager())) {
            userSet.add(lineInfo.getInvestmentManager());
        }
        if (StringUtils.isNotEmpty(lineInfo.getDevelopmentManager())) {
            userSet.add(lineInfo.getDevelopmentManager());
        }
        Map<Long, String> regionNameMap = regionService.getBelongWarRegionNameMap(Collections.singletonList(shopInfo.getRegionId()));
        Map<String, EnterpriseUserDO> userInfoMap = enterpriseUserDAO.getUserInfoMap(new ArrayList(userSet));
        preparationScheduleDetailVO.setShopId(shopId);
        preparationScheduleDetailVO.setUsername(lineInfo.getUsername());
        preparationScheduleDetailVO.setMobile(lineInfo.getMobile());
        preparationScheduleDetailVO.setJoinStatus(lineInfo.getJoinStatus());
        preparationScheduleDetailVO.setShopName(shopInfo.getShopName());
        preparationScheduleDetailVO.setPlanOpenTime(shopInfo.getPlanOpenTime());
        preparationScheduleDetailVO.setStoreNum(shopInfo.getStoreNum());
        preparationScheduleDetailVO.setJoinStatus(lineInfo.getJoinStatus());
        if (CollectionUtils.isNotEmpty(shopContractActualCompletionTime)) {
            ScheduleDTO scheduleDTO = shopContractActualCompletionTime.get(CommonConstants.ZERO);
            preparationScheduleDetailVO.setCompletionColumn(scheduleDTO.getCompletionColumn());
            preparationScheduleDetailVO.setTotalColumn(scheduleDTO.getTotalColumn()-1);
            preparationScheduleDetailVO.setPlanCompletionTime(scheduleDTO.getPlanCompleteTime());
        }
        if (CollectionUtils.isNotEmpty(shop)) {
            ShopStageInfoDO shopStageInfoDO = shop.get(CommonConstants.ZERO);
            preparationScheduleDetailVO.setContractCompletionTime(DateUtils.strToDate(shopStageInfoDO.getActualCompleteTime(), DateUtils.YYYY_MM_DD_HH_MM_SS));
        }
        EnterpriseUserDO developmentManager = userInfoMap.getOrDefault(lineInfo.getDevelopmentManager(), new EnterpriseUserDO());
        EnterpriseUserDO investmentManager = userInfoMap.getOrDefault(lineInfo.getInvestmentManager(), new EnterpriseUserDO());
        preparationScheduleDetailVO.setDevelopmentManagerName(developmentManager.getName());
        preparationScheduleDetailVO.setDevelopmentManagerMobile(developmentManager.getMobile());
        preparationScheduleDetailVO.setInvestmentManagerName(investmentManager.getName());
        preparationScheduleDetailVO.setInvestmentManagerMobile(investmentManager.getMobile());
        preparationScheduleDetailVO.setRegionNodeName(regionNameMap.get(shopInfo.getRegionId()));
        preparationScheduleDetailVO.setDays();
        return preparationScheduleDetailVO;
    }

    @Override
    public PreparationProcessVO getPreparationProcess(Long shopId) {
        PreparationProcessVO preparationProcess = shopStageInfoDAO.getPreparationProcess(shopId);
        if (preparationProcess == null){
            return null;
        }
        preparationProcess.setTotalCount(14);
        return preparationProcess;
    }

    @Override
    public void contractAndBuildStoreCompletion(Long shopId) {
        List<ShopStageInfoDO> shopStageInfo = shopStageInfoDAO.getShopStageInfo(shopId, null);
        if (CollectionUtils.isNotEmpty(shopStageInfo)) {
            Map<Integer, ShopStageInfoDO> shopStageInfoDOMap = shopStageInfo.stream().collect(Collectors.toMap(ShopStageInfoDO::getShopSubStage, data -> data));
            Boolean buildStoreCompletionFlag = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_33.getShopSubStageStatus().equals(shopStageInfoDOMap.get(ShopSubStageEnum.SHOP_STAGE_3.getShopSubStage()).getShopSubStageStatus());
            Boolean contractCompletionFlag = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_73.getShopSubStageStatus().equals(shopStageInfoDOMap.get(ShopSubStageEnum.SHOP_STAGE_7.getShopSubStage()).getShopSubStageStatus());
            ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
            LineInfoDO lineInfo = lineInfoDAO.getLineInfo(shopInfo.getLineId());
            //都完成了 初始化后续流程数据
            if (buildStoreCompletionFlag && contractCompletionFlag) {
                //初始化后续流程数据 设计阶段 装修阶段 开业运营方案 首批订货清单
                List<ShopStageInfoDO> list = new ArrayList<>();
                ShopStageInfoDO data1 = shopStageInfoDOMap.get(ShopSubStageEnum.SHOP_STAGE_9.getShopSubStage());
                data1.setShopSubStageStatus(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_90.getShopSubStageStatus());
                list.add(data1);
                ShopStageInfoDO data2 = shopStageInfoDOMap.get(ShopSubStageEnum.SHOP_STAGE_11.getShopSubStage());
                data2.setShopSubStageStatus(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_110.getShopSubStageStatus());
                list.add(data2);
                //初始化xfsg_acceptance_info表
                AcceptanceInfoDO acceptanceInfoDO1 = acceptanceInfoDAO.selectByShopId(shopId);
                AcceptanceInfoDO acceptanceInfoDO = new AcceptanceInfoDO();
                acceptanceInfoDO.setShopId(shopId);
                acceptanceInfoDO.setCreateTime(new Date());
                if(Objects.isNull(acceptanceInfoDO1)) {
                    acceptanceInfoDAO.insertSelectiveAcceptanceInfo(acceptanceInfoDO);
                }
                ShopStageInfoDO data3 = shopStageInfoDOMap.get(ShopSubStageEnum.SHOP_STAGE_14.getShopSubStage());
                data3.setShopSubStageStatus(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_140.getShopSubStageStatus());
                list.add(data3);
                //发送督导钉钉
                Map<String, String> messageMap = new HashMap<>();
                messageMap.put("storeName",shopInfo.getShopName());
                messageMap.put("shopId",String.valueOf(shopId));
                messageMap.put("lineId", shopInfo.getLineId().toString());
                messageMap.put("partnerUsername",lineInfo.getUsername());
                messageMap.put("shopName",shopInfo.getShopName());
                messageMap.put("partnerMobile",lineInfo.getMobile());
                commonService.sendMessage(Arrays.asList(shopInfo.getSupervisorUserId()), MessageEnum.MESSAGE_26, messageMap);
                ShopStageInfoDO data4 = shopStageInfoDOMap.get(ShopSubStageEnum.SHOP_STAGE_15.getShopSubStage());
                data4.setShopSubStageStatus(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_150.getShopSubStageStatus());
                list.add(data4);
                //发送督导钉钉
                Map<String, String> messageMap1 = new HashMap<>();
                messageMap1.put("storeName",shopInfo.getShopName());
                messageMap1.put("shopId",String.valueOf(shopId));
                messageMap1.put("shopName",shopInfo.getShopName());
                messageMap1.put("lineId", String.valueOf(shopInfo.getLineId()));
                messageMap1.put("partnerUsername",lineInfo.getUsername());
                messageMap1.put("partnerMobile",lineInfo.getMobile());
                commonService.sendMessage(Arrays.asList(shopInfo.getSupervisorUserId()), MessageEnum.MESSAGE_27, messageMap1);
                shopStageInfoDAO.batchUpdate(list);
            }
        }
    }

    @Override
    public void whetherToOpenForAcceptance(Long shopId) {
        Integer allCompletionCount = shopStageInfoDAO.getAllCompletionCount(shopId);
        //如果等于6 表示前面阶段都已经完成  初始化开业验收数据
        if (allCompletionCount.equals(CommonConstants.FIVE)) {
            OpenAcceptanceInfoDO openAcceptanceInfoDO = new OpenAcceptanceInfoDO();
            openAcceptanceInfoDO.setShopId(shopId);
            openAcceptanceInfoDO.setAcceptanceStatus(CommonConstants.ZERO);
            openAcceptanceInfoDAO.insertSelective(openAcceptanceInfoDO);
            shopStageInfoDAO.updateShopStageInfo(shopId, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_160);
        }
    }

    @Override
    public Boolean decorationFlush(Long shopId) {
        List<ShopStageInfoDO> shopStageInfo = shopStageInfoDAO.getShopStageInfo(shopId, ShopStageEnum.SHOP_STAGE_2.getShopStage());
        Map<Integer, ShopStageInfoDO> collect = shopStageInfo.stream().collect(Collectors.toMap(ShopStageInfoDO::getShopSubStage, Function.identity()));
        //设计
        Boolean flushFlag = Boolean.FALSE;
        Integer Status900 = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_90.getShopSubStageStatus();
        Integer Design = collect.get(ShopSubStageEnum.SHOP_STAGE_9.getShopSubStage()).getShopSubStageStatus();
        if (Status900.equals(Design)) {
            decorationService.DesignInfo(shopId);
            flushFlag = Boolean.TRUE;
        }
        //装修款
        Integer Status1000 = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_100.getShopSubStageStatus();
        Integer Status1010 = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_101.getShopSubStageStatus();
        Integer DecorationModel = collect.get(ShopSubStageEnum.SHOP_STAGE_10.getShopSubStage()).getShopSubStageStatus();
        if (Status1000.equals(DecorationModel) || Status1010.equals(DecorationModel)) {
            decorationService.getDecorationModel(shopId, null);
            flushFlag = Boolean.TRUE;
        }
        //施工阶段
        Integer Status1100 = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_110.getShopSubStageStatus();
        Integer Status1110 = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_111.getShopSubStageStatus();
        Integer Construction = collect.get(ShopSubStageEnum.SHOP_STAGE_11.getShopSubStage()).getShopSubStageStatus();
        if (Status1110.equals(Construction) || Status1100.equals(Construction)) {
            decorationService.getConstructionInfo(shopId);
            flushFlag = Boolean.TRUE;
        }
        return flushFlag;
    }


}
