package com.cool.store.job;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.CommonConstants;
import com.cool.store.dao.*;
import com.cool.store.dto.StaffExamInfoDTO;
import com.cool.store.dto.decoration.ConstructionScheduleDTO;
import com.cool.store.dto.openPreparation.OpenPlanShopInfoDTO;
import com.cool.store.dto.xfsgFirstOderDTO;
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.LineInfoMapper;
import com.cool.store.mapper.TrainingExperienceMapper;
import com.cool.store.mq.util.HttpRestTemplateService;
import com.cool.store.request.xfsgFirstOrderListRequest;
import com.cool.store.response.xfsgFirstOderListResponse;
import com.cool.store.service.*;
import com.cool.store.service.impl.CommonService;
import com.cool.store.utils.CoolDateUtils;
import com.cool.store.utils.NumberConverter;
import com.cool.store.utils.poi.DateUtils;
import com.cool.store.utils.poi.StringUtils;
import com.cool.store.utils.poi.constant.Constants;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class XxlJobHandler {


    @Resource
    TrainingExperienceMapper trainingExperienceMapper;
    @Value("${xfsg.url}")
    private String xfsgUrl;
    @Resource
    private HttpRestTemplateService httpRestTemplateService;
    @Resource
    LineInfoMapper lineInfoMapper;
    @Resource
    private PreparationService preparationService;
    @Resource
    private LineInterviewDAO lineInterviewDAO;
    @Resource
    private LineInfoDAO lineInfoDAO;
    @Resource
    private ShopInfoDAO shopInfoDAO;
    @Resource
    private ShopStageInfoDAO shopStageInfoDAO;
    @Resource
    private CoolStoreStartFlowService coolStoreStartFlowService;
    @Resource
    private AcceptanceInfoDAO acceptanceInfoDAO;
    @Resource
    private DecorationService decorationService;
    @Resource
    private CommonService commonService;
    @Resource
    private EmployeeTrainingDAO employeeTrainingDAO;
    @Resource
    private XfsgEhrService xfsgEhrService;
    @Resource
    private TempUserDetailDAO tempUserDetailDAO;
    @Resource
    private EnterpriseUserDAO enterpriseUserDAO;
    @Resource
    private UserAuthMappingService userAuthMappingService;
    @Resource
    private OpenAcceptanceInfoDAO openAcceptanceInfoDAO;




    /**
     * @Auther: wangshuo
     * @Date: 2024/4/29
     * @description: 每天更新装修阶段进场时间等
     */
    @XxlJob("updateEntryTime")
    public void updateEntryTime() {
        log.info("----定时任务每天更新装修阶段进场时间，施工完成时间等----");
        boolean hasNext = true;
        int pageNum = 1;
        int pageSize = 50;
        while (hasNext) {
            PageHelper.startPage(pageNum, pageSize);
            //获取表中进场时间为空的
            List<AcceptanceInfoDO> acceptanceInfoDOS = acceptanceInfoDAO.selectByEntryTimeNull();
            if (CollectionUtils.isEmpty(acceptanceInfoDOS)) {
                log.info("------定时任务结束每天更新至预约状态结束------");
                return;
            }
            for (AcceptanceInfoDO acceptanceInfoDO : acceptanceInfoDOS) {
                int flag = CommonConstants.ZERO;
                while (flag < CommonConstants.TWO) {
                    try {
                        Long shopId = acceptanceInfoDO.getShopId();
                        //施工子阶段 更新装修阶段进场时间等
                        decorationService.getConstruction(shopId);
                        break;
                    } catch (Exception e) {
                        log.error("定时任务设置进场时间失败,shopId:{},e:{}", acceptanceInfoDO.getShopId(), e.getMessage());
                        flag++;
                    }
                }
            }
            hasNext = acceptanceInfoDOS.size() >= pageSize;
            pageNum++;
        }
        log.info("------定时任务结束每天更新至预约状态结束------");
        XxlJobHelper.handleSuccess();
    }


    /**
     * @Auther: wangshuo
     * @Date: 2024/5/10
     * @description:实际进场时间+5天，发送钉钉通知到工程监理
     */
    @XxlJob("threeAcceptanceBookingMessage")
    public void threeAcceptanceBookingMessage() {
        log.info("------定时任务三方验收待预约钉钉通知-----");
        boolean hasNext = true;
        int pageNum = 1;
        int pageSize = 50;
        while (hasNext) {
            PageHelper.startPage(pageNum, pageSize);
            //进场时间不为空的
            List<AcceptanceInfoDO> acceptanceInfoDOS = acceptanceInfoDAO
                    .selectListNotNullEntryTime();
            if (CollectionUtils.isEmpty(acceptanceInfoDOS)) {
                log.info("------定时任务结束三方验收待预约钉钉通知------");
                return;
            }
            for (AcceptanceInfoDO acceptanceInfoDO : acceptanceInfoDOS) {
                int flag = CommonConstants.ZERO;
                //进场时间
                while (flag < CommonConstants.TWO) {
                    try {
                        Date approach = acceptanceInfoDO.getActualEntryTime();
                        LocalDate plusFDays = DateUtils.getPlusFDays(approach, CommonConstants.FOUR);
                        if (plusFDays.equals(LocalDate.now())) {
                            ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(acceptanceInfoDO.getShopId());
                            List<EnterpriseUserDO> supervisor = userAuthMappingService
                                    .getUserByRoleEnumAndRegionIdList(UserRoleEnum.ENGINEER_DEP_SUPERVISOR, shopInfo.getRegionId());
                            LineInfoDO lineInfo = lineInfoDAO.getLineInfo(shopInfo.getLineId());
                            for (EnterpriseUserDO enterpriseUserDO : supervisor) {
                                Map<String, String> messageMap = new HashMap<>();
                                messageMap.put("storeName", shopInfo.getShopName());
                                messageMap.put("partnerUsername", lineInfo.getUsername());
                                messageMap.put("partnerMobile", lineInfo.getMobile());
                                commonService.sendMessage(Arrays.asList(enterpriseUserDO.getUserId()), MessageEnum.MESSAGE_24, messageMap);
                            }
                        }
                        break;
                    } catch (Exception e) {
                        log.error("------定时任务三方验收待预约钉钉通知失败,shopId:{},e:{}", acceptanceInfoDO.getShopId(), e.getMessage());
                        flag++;
                    }
                }
            }
            hasNext = acceptanceInfoDOS.size() >= pageSize;
            pageNum++;
        }
    }

    /**
     * 店铺新店开业状态更新
     */
    @XxlJob("shopOpenAcceptanceStatusUpdate")
    public void shopOpenAcceptanceStatusUpdate() {
        log.info("------店铺新店开业状态更新------");
        int num = openAcceptanceInfoDAO.shopOpenAcceptanceStatusUpdate();
        log.info("------店铺新店开业状态更新完成num:{}------", num);
        XxlJobHelper.handleSuccess();
    }

}
