package com.fs.app.controller;

import com.alibaba.fastjson.JSON;
import com.fs.common.core.redis.RedisCache;
import com.fs.company.service.ICompanyConfigService;
import com.fs.course.mapper.FsCourseSopLogsMapper;
import com.fs.course.mapper.FsCourseSopMapper;
import com.fs.course.mapper.FsCourseWatchLogMapper;
import com.fs.crm.mapper.CrmCustomerMapper;
import com.fs.qw.domain.QwExternalContact;
import com.fs.qw.domain.QwUser;
import com.fs.qw.mapper.*;
import com.fs.qw.param.QwAutoSopTimeParam;
import com.fs.qw.service.IQwContactWayService;
import com.fs.qw.service.IQwExternalContactCrmService;
import com.fs.qw.vo.QwSopRuleTimeVO;
import com.fs.qwApi.service.QwApiService;
import com.fs.sop.domain.SopUserLogs;
import com.fs.sop.domain.SopUserLogsInfo;
import com.fs.sop.mapper.QwSopMapper;
import com.fs.sop.mapper.SopUserLogsInfoMapper;
import com.fs.sop.params.QwSopAutoByTags;
import com.fs.sop.params.SopUserLogsParamByDate;
import com.fs.sop.service.IQwSopService;
import com.fs.sop.service.ISopUserLogsService;
import com.fs.voice.utils.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
public class testService {
    @Autowired
    RedisCache redisCache;
    @Autowired
    QwExternalContactMapper qwExternalContactMapper;
    @Autowired
    QwUserMapper qwUserMapper;
    @Autowired
    RedisTemplate<String, String> redisTemplate;
    @Autowired
    IQwSopService qwSopService;
    @Autowired
    QwSopMapper qwSopMapper;

    @Autowired
    ICompanyConfigService companyConfigService;

    @Autowired
    QwApiService qwApiService;
    @Autowired
    QwContactWayMapper qwContactWayMapper;

    @Autowired
    IQwContactWayService qwContactWayService;
    @Autowired
    QwContactWayUserMapper qwContactWayUserMapper;
    @Autowired
    QwContactWayLogsMapper qwContactWayLogsMapper;

    @Autowired
    QwFriendWelcomeMapper qwFriendWelcomeMapper;

    @Autowired
    QwAutoTagsMapper qwAutoTagsMapper;
    @Autowired
    CrmCustomerMapper crmCustomerMapper;
    @Autowired
    QwAutoTagsLogsMapper qwAutoTagsLogsMapper;

    @Autowired
    IQwExternalContactCrmService contactCrmService;

    @Autowired
    FsCourseSopLogsMapper fsSopLogsMapper;

    @Autowired
    FsCourseSopMapper fsSopMapper;

    @Autowired
    CrmCustomerMapper customerMapper;

    @Autowired
    FsCourseWatchLogMapper fsCourseWatchLogMapper;

    @Autowired
    QwAppContactWayLogsMapper qwAppContactWayLogsMapper;

    @Autowired
    private SopUserLogsInfoMapper sopUserLogsInfoMapper;


    @Autowired
    private ISopUserLogsService sopUserLogsService;

    int i=0;


    public void add(QwUser qwUser) {
        List<QwExternalContact> qwExternalContacts = qwExternalContactMapper.selectExternalUserIdByQwUserId(qwUser.getId());
        System.out.println("客户数量"+qwExternalContacts.size());
        for (QwExternalContact qwExternalContact : qwExternalContacts) {
            i++;
            System.out.println("客户"+i);
            Date date = qwExternalContact.getCreateTime();
            LocalDate currentDate = date.toInstant()
                    .atZone(ZoneId.systemDefault()) // 使用系统默认时区
                    .toLocalDate();

            LocalTime localTime = date.toInstant()
                    .atZone(ZoneId.systemDefault()) // 使用系统默认时区
                    .toLocalTime();
            // 获取当前系统时间 (HH:mm)

            QwSopAutoByTags qwSopAutoByTags=new QwSopAutoByTags();
            qwSopAutoByTags.setQwUserId(String.valueOf(qwUser.getId()));
            qwSopAutoByTags.setCorpId(qwExternalContact.getCorpId());
            List<String> parsedTags = JSON.parseArray(qwExternalContact.getTagIds(), String.class);
            qwSopAutoByTags.setTagsIdsSelectList(parsedTags);
            qwSopAutoByTags.setSendType(2);
            if (parsedTags!=null&&parsedTags.size()!=0){

                List<QwSopRuleTimeVO> qwSopRuleTimeVOS = qwSopMapper.selectQwSopAutoByTagsByForeachNotAuto(qwSopAutoByTags);

                if (qwSopRuleTimeVOS != null && !qwSopRuleTimeVOS.isEmpty()){
                    //SOP规则
                    qwSopRuleTimeTools(qwSopRuleTimeVOS,qwExternalContact.getUserId(),qwUser,qwExternalContact.getCorpId(),qwExternalContact.getExternalUserId(),qwExternalContact.getName(),qwExternalContact,currentDate,localTime,parsedTags);
                }
            }else {
                System.out.println("标签为空");
            }


        }
    }


    public void qwSopRuleTimeTools(List<QwSopRuleTimeVO> qwSopRuleTimeVOS, String userID, QwUser qwUser, String corpId,
                                   String externalUserID, String externalContactName, QwExternalContact contact,
                                   LocalDate currentDate, LocalTime localTime, List<String> combinedTagsList) {
        // 定义日期和时间格式化器
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");

        // sop任务
        qwSopRuleTimeVOS.forEach(ruleTimeVO -> {

            // 将排除的字符串转成列表
            List<String> excludedTagsList=new ArrayList<>();
            if (ruleTimeVO.getExcludeTags() != null && !ruleTimeVO.getExcludeTags().isEmpty()){
                excludedTagsList= Arrays.asList( ruleTimeVO.getExcludeTags().split(","));
            }

            // 检查 combinedTagsList 是否包含排除列表中的任意一个标签
            boolean containsExcludedTag = combinedTagsList.stream()
                    .anyMatch(excludedTagsList::contains);

            //含任意一个排除标签
            if (containsExcludedTag) {
                return;
            }

            // 自动sop的规则
            QwAutoSopTimeParam qwAutoSopTimeParam = JSON.parseObject(ruleTimeVO.getAutoSopTime(), QwAutoSopTimeParam.class);

            // 用于查询/或新增
            SopUserLogs userLogs = new SopUserLogs();
            userLogs.setSopId(ruleTimeVO.getId());
            userLogs.setSopTempId(ruleTimeVO.getTempId());
            userLogs.setCorpId(ruleTimeVO.getCorpId());
            userLogs.setStatus(1);

            // 用于今天的新增
            SopUserLogsParamByDate userLogsParamByDate = new SopUserLogsParamByDate();
            userLogsParamByDate.setSopId(ruleTimeVO.getId());
            userLogsParamByDate.setSopTempId(ruleTimeVO.getTempId());
            userLogsParamByDate.setCorpId(ruleTimeVO.getCorpId());
            userLogsParamByDate.setStatus(1);

            // 从数据库中取到的开始时间（Date类型），转换为 LocalDate
            Date sopStartTime = ruleTimeVO.getStartTime();
            //开始时间
            LocalDate sopStartLocalDate = sopStartTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

            // 设定用户信息
            userLogs.setQwUserId(userID);
            userLogs.setUserId(qwUser.getId() + "|" + qwUser.getCompanyUserId() + "|" + qwUser.getCompanyId());
            userLogsParamByDate.setQwUserId(userID);
            userLogsParamByDate.setUserId(qwUser.getId() + "|" + qwUser.getCompanyUserId() + "|" + qwUser.getCompanyId());

            // 创建 SopUserLogsInfo
            SopUserLogsInfo logsInfo = new SopUserLogsInfo();
            logsInfo.setQwUserId(userID.trim());
            logsInfo.setCorpId(qwUser.getCorpId());
            logsInfo.setExternalContactId(externalUserID.trim());
            logsInfo.setExternalId(contact.getId());
            logsInfo.setFsUserId(contact.getFsUserId());
            logsInfo.setExternalUserName(externalContactName);
            logsInfo.setSopId(ruleTimeVO.getId());
            // 判断 SOP 任务的开始时间
            qwSopRuleTimeToolsCheck(sopStartLocalDate,currentDate,dateFormatter,userLogs,logsInfo,userLogsParamByDate,qwAutoSopTimeParam,timeFormatter,localTime);
        });
    }

    public void qwSopRuleTimeToolsCheck(LocalDate sopStartLocalDate,LocalDate currentDate,DateTimeFormatter dateFormatter,
                                        SopUserLogs userLogs,SopUserLogsInfo logsInfo,SopUserLogsParamByDate userLogsParamByDate,
                                        QwAutoSopTimeParam qwAutoSopTimeParam,DateTimeFormatter timeFormatter,LocalTime localTime) {
        // 还没开始 (未来,不包括今天)
        if (sopStartLocalDate.isAfter(currentDate)) {
            System.out.println("还没开始");
            // 大于当前日期，说明还没有开始：
            // -> 以 SOP 任务的开始时间为营期
            String sopStartLocalDateStr = sopStartLocalDate.format(dateFormatter);

            userLogs.setStartTime(sopStartLocalDateStr);
            // 查询开始时间营期表
            String unionSopStartId = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogs);

            // 如果营期表里有，则加入；否则创建新营期
            if (!StringUtil.strIsNullOrEmpty(unionSopStartId)) {
                logsInfo.setUserLogsId(unionSopStartId);
                // 查询这个人是否已在该营期里
                handleInsertSopUserLogsInfo(logsInfo);
            }
            else {
                // 没有营期记录就先插入
                userLogsParamByDate.setStartTime(sopStartLocalDateStr);

                sopUserLogsService.insertSopUserLogsByDate(userLogsParamByDate);

                // 再次查询 拿营期主键
                String unionSopStartIdNew = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogs);
                logsInfo.setUserLogsId(unionSopStartIdNew);

                // 查询是否在营期里，如果没有再插入
                handleInsertSopUserLogsInfo(logsInfo);
            }
        }
        else {

            // sopStartLocalDate <= currentDate -> 说明已经开始
            // -> 以“今天 / 明天”作为营期
            // 获取 AutoSopType
            Integer autoSopType = qwAutoSopTimeParam.getAutoSopType();

            // 今天的日期字符串
            String todayStr = currentDate.format(dateFormatter);
            userLogs.setStartTime(todayStr);

            // 查询今天的营期表
            String unionSopStartId2 = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogs);

            // 明天日期字符串
            LocalDate tomorrowDate = currentDate.plusDays(1);
            String tomorrowStr = tomorrowDate.format(dateFormatter);

            // 复制一份 userLogs，设为明天
            SopUserLogs userLogsTomorrow = new SopUserLogs();
            BeanUtils.copyProperties(userLogs, userLogsTomorrow);
            userLogsTomorrow.setStartTime(tomorrowStr);

            // 复制一份 SopUserLogsParamByDate，设为明天
            SopUserLogsParamByDate paramByDateTomorrow=new SopUserLogsParamByDate();
            BeanUtils.copyProperties(userLogsParamByDate, paramByDateTomorrow);
            paramByDateTomorrow.setStartTime(tomorrowStr);

            // 查询明天的营期表
            String unionTomorrowSopId2 = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogsTomorrow);
            // 根据 autoSopType 分支处理
            switch (autoSopType) {
                // 立即执行
                case 1: {
                    String autoStartTime = qwAutoSopTimeParam.getAutoStartTime();
                    String autoEndTime = qwAutoSopTimeParam.getAutoEndTime();

                    // 如果结束时间为 24:00，则替换成 23:59
                    if ("24:00".equals(autoEndTime)) {
                        autoEndTime = "23:59";
                    }

                    // 转为 LocalTime
                    LocalTime startTime = LocalTime.parse(autoStartTime, timeFormatter);
                    LocalTime endTime = LocalTime.parse(autoEndTime, timeFormatter);

                    // 判断当前时间是否在 [startTime, endTime] 范围内
                    if (!localTime.isBefore(startTime) && !localTime.isAfter(endTime)) {
                        // 在范围内 => 加入到今天的营期

                        if (!StringUtil.strIsNullOrEmpty(unionSopStartId2)) {

                            logsInfo.setUserLogsId(unionSopStartId2);
                            // 查询客户是否已存在
                            handleInsertSopUserLogsInfo(logsInfo);

                        } else {
                            // 没有今天天的营期就先建
                            userLogsParamByDate.setStartTime(todayStr);
                            sopUserLogsService.insertSopUserLogsByDate(userLogsParamByDate);

                            // 查询客户是否已存在
                            SopUserLogsInfo userLogsInfo = sopUserLogsInfoMapper.selectSopUserLogsInfo(logsInfo);
                            if (userLogsInfo == null) {

                                // 再查今天的营期的主键
                                userLogs.setStartTime(todayStr);
                                String unionSopStartIdNew = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogs);

                                logsInfo.setUserLogsId(unionSopStartIdNew);
                                //客户入营期
                                sopUserLogsInfoMapper.insertSopUserLogsInfo(logsInfo);

                            }
                        }
                    } else {

                        // 不在范围内 => 加入到明天的营期
                        if (!StringUtil.strIsNullOrEmpty(unionTomorrowSopId2)) {
                            logsInfo.setUserLogsId(unionTomorrowSopId2);
                            // 查询是否已存在客户入营期

                            handleInsertSopUserLogsInfo(logsInfo);
                        } else {
                            // 没有明天的营期就先建

                            handleNextDayExecution( paramByDateTomorrow, logsInfo, userLogsTomorrow);
                        }
                    }
                    break;
                }
                // 次日执行
                case 2: {
                    // 直接加入到明天的营期没有明天的营期就先建
                    if (!StringUtil.strIsNullOrEmpty(unionTomorrowSopId2)) {

                        logsInfo.setUserLogsId(unionTomorrowSopId2);
                        //客户入营期
                        handleInsertSopUserLogsInfo(logsInfo);
                    } else {

                        // 没有明天的营期就先建
                        handleNextDayExecution( paramByDateTomorrow, logsInfo, userLogsTomorrow);
                    }
                    break;
                }
                default:
                    // 其他类型可根据需要自行扩展
                    break;
            }
        }
    }
    public void handleNextDayExecution(SopUserLogsParamByDate paramByDateTomorrow,SopUserLogsInfo sopUserLogsInfo,SopUserLogs userLogsTomorrow) {

        sopUserLogsService.insertSopUserLogsByDate(paramByDateTomorrow);

        SopUserLogsInfo userLogsInfo = sopUserLogsInfoMapper.selectSopUserLogsInfo(sopUserLogsInfo);
        if (userLogsInfo == null) {

            String unionTomorrowSopId2New = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogsTomorrow);
            sopUserLogsInfo.setUserLogsId(unionTomorrowSopId2New);

            sopUserLogsInfoMapper.insertSopUserLogsInfo(sopUserLogsInfo);
        }
    }
    public void handleInsertSopUserLogsInfo(SopUserLogsInfo sopUserLogsInfo){
        SopUserLogsInfo userLogsInfo = sopUserLogsInfoMapper.selectSopUserLogsInfo(sopUserLogsInfo);

        if (userLogsInfo == null) {
            try {
                sopUserLogsInfoMapper.insertSopUserLogsInfo(sopUserLogsInfo);
                System.out.println("新增OK");
            }catch (Exception e){
                System.out.println("新增出错");
            }

        }else {
            System.out.println("已经存在营期");
        }
    }




}
