package com.fs.wx.sop.service.impl;


import com.fs.common.annotation.DataSource;
import com.fs.common.core.domain.R;
import com.fs.common.core.domain.entity.SysDictData;
import com.fs.common.enums.DataSourceType;
import com.fs.crm.domain.CrmCustomer;
import com.fs.crm.mapper.CrmCustomerMapper;
import com.fs.sop.params.WxSopTagsParam;
import com.fs.sop.vo.WxFilterSopCustomersResult;
import com.fs.system.service.ISysDictDataService;
import com.fs.wx.sop.domain.WxSop;
import com.fs.wx.sop.domain.WxSopUser;
import com.fs.wx.sop.domain.WxSopUserInfo;
import com.fs.wx.sop.mapper.WxSopMapper;
import com.fs.wx.sop.mapper.WxSopUserInfoMapper;
import com.fs.wx.sop.mapper.WxSopUserMapper;
import com.fs.wx.sop.service.IWxSopExecuteService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

/**
 * 个微SOP执行服务实现类
 *
 * @author fs
 * @date 2025-03-12
 */
@Service
@Slf4j
public class WxSopExecuteServiceImpl implements IWxSopExecuteService {

    @Autowired
    private WxSopMapper wxSopMapper;

    @Autowired
    private WxSopUserMapper wxSopUserMapper;

    @Autowired
    private WxSopUserInfoMapper wxSopUserInfoMapper;

    @Autowired
    private CrmCustomerMapper crmCustomerMapper;

    @Autowired
    private ISysDictDataService sysDictDataService;

    @Override
    @DataSource(DataSourceType.SOP)
    public R processTagFilterWxSop(WxSop wxSop) {
        try {
            log.info("====== 开始执行标签筛选SOP ======");
            log.info("SOP ID: {}, 名称: {}, 筛选标签: {}, 执行账号: {}",
                    wxSop.getId(), wxSop.getName(), wxSop.getSelectTags(), wxSop.getAccountIds());

            // 构建标签筛选参数
            WxSopTagsParam wxSopTagsParam = buildWxSopTagsParam(wxSop);
            log.info("筛选参数: accountIds={}, tags={}, excludeTags={}",
                    wxSopTagsParam.getAccountIdsSelectList(),
                    wxSopTagsParam.getTagsIdsSelectList(),
                    wxSopTagsParam.getOutTagsIdsSelectList());

            // 查询符合条件的客户
            List<WxFilterSopCustomersResult> customerResults = selectFilterWxSopCustomers(wxSopTagsParam);
            log.info("查询到的客户数量: {}", customerResults != null ? customerResults.size() : 0);

            if (customerResults != null && !customerResults.isEmpty()) {
                for (WxFilterSopCustomersResult customer : customerResults) {
                    log.info("符合条件的客户: ID={}, 名称={}, 账号ID={}",
                            customer.getId(), customer.getName(), customer.getAccountId());
                }
            }

            if (customerResults == null || customerResults.isEmpty()) {
                log.warn("未找到符合条件的客户，SOP ID: {}", wxSop.getId());
                return R.error("未找到符合条件的客户");
            }

            // 为客户创建营期记录
            createSopUserLogsWxForCustomers(wxSop, customerResults);

            log.info("标签筛选SOP处理完成，SOP ID: {}，客户数量: {}", wxSop.getId(), customerResults.size());
            return R.ok("标签筛选SOP处理完成");
        } catch (Exception e) {
            log.error("处理标签筛选SOP时发生异常，SOP ID: {}", wxSop.getId(), e);
            return R.error("处理过程中发生异常: " + e.getMessage());
        }
    }

    @Override
    @DataSource(DataSourceType.SOP)
    public R processGroupFilterWxSop(WxSop wxSop) {
        try {
            // 群聊筛选逻辑
            // 这里需要根据群聊ID或其他群聊相关信息筛选客户
            // 暂时留空实现，需要根据具体业务需求完善

            log.info("群聊筛选SOP处理完成，SOP ID: {}", wxSop.getId());
            return R.ok("群聊筛选SOP处理完成");
        } catch (Exception e) {
            log.error("处理群聊筛选SOP时发生异常，SOP ID: {}", wxSop.getId(), e);
            return R.error("处理过程中发生异常: " + e.getMessage());
        }
    }

    @Override
    @DataSource(DataSourceType.SOP)
    public R createSopUserLogsWx(WxSop wxSop) {
        try {
            // 根据SOP的筛选方式进行不同的客户筛选
            if (wxSop.getFilterType() != null && wxSop.getFilterType() == 0) { // 0: 标签筛选
                return processTagFilterWxSop(wxSop);
            } else if (wxSop.getFilterType() != null && wxSop.getFilterType() == 1) { // 1: 群聊筛选
                return processGroupFilterWxSop(wxSop);
            } else {
                return R.error("未知的筛选方式");
            }
        } catch (Exception e) {
            log.error("创建SOP营期记录时发生异常，SOP ID: {}", wxSop.getId(), e);
            return R.error("创建营期记录时发生异常: " + e.getMessage());
        }
    }

    /**
     * 构建标签筛选参数
     *
     * @param wxSop 个微SOP
     * @return 标签筛选参数
     */
    private WxSopTagsParam buildWxSopTagsParam(WxSop wxSop) {
        WxSopTagsParam param = new WxSopTagsParam();

        // 设置执行账号ID列表
        if (wxSop.getAccountIds() != null && !wxSop.getAccountIds().isEmpty()) {
            String[] accountIds = wxSop.getAccountIds().split(",");
            List<String> accountIdsList = new ArrayList<>();
            for (String accountId : accountIds) {
                if (accountId != null && !accountId.trim().isEmpty()) {
                    accountIdsList.add(accountId.trim());
                }
            }
            param.setAccountIdsSelectList(accountIdsList);
        }

        // 设置筛选标签
        if (wxSop.getSelectTags() != null && !wxSop.getSelectTags().isEmpty()) {
            String[] tags = wxSop.getSelectTags().split(",");
            List<String> tagsList = new ArrayList<>();
            for (String tag : tags) {
                if (tag != null && !tag.trim().isEmpty()) {
                    tagsList.add(tag.trim());
                }
            }
            param.setTagsIdsSelectList(tagsList);
        }

        // 设置排除标签
        if (wxSop.getExcludeTags() != null && !wxSop.getExcludeTags().isEmpty()) {
            String[] excludeTags = wxSop.getExcludeTags().split(",");
            List<String> excludeTagsList = new ArrayList<>();
            for (String excludeTag : excludeTags) {
                if (excludeTag != null && !excludeTag.trim().isEmpty()) {
                    excludeTagsList.add(excludeTag.trim());
                }
            }
            param.setOutTagsIdsSelectList(excludeTagsList);
        }

        // 设置筛选类型
        param.setFilterType(wxSop.getFilterType());

        return param;
    }

    /**
     * 查询符合条件的客户
     *
     * @param param 标签筛选参数
     * @return 客户结果列表
     */
    private List<WxFilterSopCustomersResult> selectFilterWxSopCustomers(WxSopTagsParam param) {
        log.info("开始查询符合条件的客户...");
        List<WxFilterSopCustomersResult> results = wxSopMapper.selectFilterWxSopCustomers(param);
        log.info("客户查询完成，结果数: {}", results != null ? results.size() : 0);
        return results;
    }

    /**
     * 为客户创建营期记录
     *
     * @param wxSop 个微SOP
     * @param customerResults 客户结果列表
     */
    @Transactional(rollbackFor = Exception.class)
    @DataSource(DataSourceType.SOP)
    public void createSopUserLogsWxForCustomers(WxSop wxSop, List<WxFilterSopCustomersResult> customerResults) {
        log.info("====== 开始为 {} 个客户创建营期记录 ======", customerResults.size());
        // 按执行账号分组创建营期
        for (WxFilterSopCustomersResult customer : customerResults) {
            try {
                log.info("处理客户: ID={}, 名称={}, 账号ID={}",
                        customer.getId(), customer.getName(), customer.getAccountId());
                Long sopUserId = getOrCreateWxSopUser(wxSop, customer);

                if (sopUserId == null) {
                    log.warn("创建营期失败，跳过客户：{}", customer.getId());
                    continue;
                }

                log.info("营期ID: {}", sopUserId);

                // 2. 检查客户是否已在该营期中
                WxSopUserInfo queryParam = new WxSopUserInfo();
                queryParam.setSopId(wxSop.getId());
                queryParam.setSopUserId(sopUserId);
                queryParam.setWxContactId(Long.parseLong(customer.getId()));

                WxSopUserInfo existingInfo = wxSopUserInfoMapper.selectWxSopUserInfoByCondition(queryParam);
                if (existingInfo != null) {
                    log.info("客户已在营期中，跳过：客户ID={}, 营期ID={}", customer.getId(), sopUserId);
                    continue;
                }

                // 3. 创建营期成员记录（wx_sop_user_info）
                WxSopUserInfo wxSopUserInfo = new WxSopUserInfo();
                wxSopUserInfo.setSopId(wxSop.getId());
                wxSopUserInfo.setSopUserId(sopUserId);
                wxSopUserInfo.setWxContactId(Long.parseLong(customer.getId()));
                if (customer.getCustomerId() != null && !customer.getCustomerId().isEmpty()) {
                    try {
                        wxSopUserInfo.setCustomerId(Long.parseLong(customer.getCustomerId()));
                    } catch (NumberFormatException e) {
                        log.warn("客户ID格式错误：{}", customer.getCustomerId());
                    }
                }

                // 设置小程序ID（如果有）
                if (customer.getFsUserId() != null && !customer.getFsUserId().isEmpty()) {
                    try {
                        wxSopUserInfo.setFsUserId(Long.parseLong(customer.getFsUserId()));
                    } catch (NumberFormatException e) {
                        log.warn("小程序ID格式错误：{}", customer.getFsUserId());
                    }
                }

                wxSopUserInfo.setStatus(0); // 正常状态

                int result = wxSopUserInfoMapper.insertWxSopUserInfo(wxSopUserInfo);
                log.info("成功添加客户到营期：客户ID={}, 营期ID={}, SOP ID={}, 插入结果={}",
                        customer.getId(), sopUserId, wxSop.getId(), result);

            } catch (Exception e) {
                log.error("为客户创建营期记录失败，客户ID: {}", customer.getId(), e);
                // 继续处理其他客户
            }
        }
        log.info("====== 营期记录创建完成 ======");
    }

    /**
     * 获取或创建营期主表记录
     *
     * @param wxSop 个微SOP
     * @param customer 客户信息
     * @return 营期ID
     */
    private Long getOrCreateWxSopUser(WxSop wxSop, WxFilterSopCustomersResult customer) {
        try {
            // 解析账号ID
            Long accountId = null;
            if (customer.getAccountId() != null && !customer.getAccountId().isEmpty()) {
                accountId = Long.parseLong(customer.getAccountId());
            } else {
                log.warn("客户账号ID为空，客户ID: {}", customer.getId());
                return null;
            }

            // 确定营期时间
            LocalDate startTime;
            if (wxSop.getIsFixed() != null && wxSop.getIsFixed() == 1) {
                // 固定营期：使用SOP的开始时间
                startTime = wxSop.getStartTime();
            } else {
                // 非固定营期：使用今天
                startTime = LocalDate.now();
            }

            // 查询是否已存在营期
            WxSopUser queryParam = new WxSopUser();
            queryParam.setSopId(wxSop.getId());
            queryParam.setType(0); // 个人类型
            queryParam.setAccountId(accountId);
            queryParam.setStartTime(startTime);

            WxSopUser existingUser = wxSopUserMapper.selectwxSopUser(queryParam);
            if (existingUser != null) {
                return existingUser.getId();
            }

            // 创建新的营期记录
            WxSopUser wxSopUser = new WxSopUser();
            wxSopUser.setType(0); // 个人类型
            wxSopUser.setSopId(wxSop.getId());
            wxSopUser.setAccountId(accountId);
            wxSopUser.setStartTime(startTime);
            wxSopUser.setStatus(0); // 正常状态

            int result = wxSopUserMapper.insertWxSopUser(wxSopUser);
            if (result > 0) {
                log.info("创建营期成功：SOP ID={}, 账号ID={}, 营期时间={}, 营期ID={}",
                        wxSop.getId(), accountId, startTime, wxSopUser.getId());
                return wxSopUser.getId();
            } else {
                log.error("创建营期失败：SOP ID={}, 账号ID={}", wxSop.getId(), accountId);
                return null;
            }
        } catch (Exception e) {
            log.error("获取或创建营期失败", e);
            return null;
        }
    }

    /**
     * 处理客户标签变更后的SOP营期动态管理
     * 根据客户最新标签，自动加入或移出符合条件的营期
     *
     * @param customerId 客户ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @DataSource(DataSourceType.SOP)
    public void processCustomerTagsChange(Long customerId) {
        try {
            log.info("====== 开始处理客户标签变更，客户ID: {} ======", customerId);

            CrmCustomer customer = crmCustomerMapper.selectCrmCustomerById(customerId);
            if (customer == null) {
                log.warn("客户不存在，客户ID: {}", customerId);
                return;
            }
            log.info("客户信息: ID={}, 名称={}, 标签={}", customerId, customer.getCustomerName(), customer.getTags());

            WxSop sopQuery = new WxSop();
            sopQuery.setStatus(2L);
            sopQuery.setFilterType(0);
            List<WxSop> enabledSops = wxSopMapper.selectWxSopList(sopQuery);
            log.info("查询到 {} 个启用的标签筛选SOP", enabledSops != null ? enabledSops.size() : 0);

            if (enabledSops == null || enabledSops.isEmpty()) {
                log.info("没有启用的标签筛选SOP，无需处理");
                return;
            }

            for (WxSop sop : enabledSops) {
                processCustomerForSop(customer, sop);
            }

            log.info("====== 客户标签变更处理完成，客户ID: {} ======", customerId);
        } catch (Exception e) {
            log.error("处理客户标签变更时发生异常，客户ID: {}", customerId, e);
            throw e;
        }
    }




    /**
     * 处理单个客户在单个SOP中的营期管理
     *
     * @param customer 客户信息
     * @param sop SOP信息
     */
    public void processCustomerForSop(CrmCustomer customer, WxSop sop) {
        try {
            log.info("检查客户是否符合SOP条件 - 客户ID: {}, SOP ID: {}, SOP名称: {}",
                    customer.getCustomerId(), sop.getId(), sop.getName());

            boolean isMatch = checkCustomerMatchSopTags(customer, sop);
            log.info("客户是否符合SOP条件: {}", isMatch);


            List<WxSopUserInfo> existingInfos = querySopUserInfosByCustomer(sop.getId(), customer.getCustomerId());

            if (isMatch) {
                // 符合条件：如果不在营期中，则加入
                if (existingInfos == null || existingInfos.isEmpty()) {
                    log.info("客户符合条件且不在营期中，准备加入营期");
                    addCustomerToSop(customer, sop);
                } else {
                    log.info("客户已在营期中，无需重复加入");
                }
            } else {
                // 不符合条件：如果在营期中，则移出
                if (existingInfos != null && !existingInfos.isEmpty()) {
                    log.info("客户不符合条件但在营期中，准备移出营期，记录数: {}", existingInfos.size());
                    removeCustomerFromSop(customer, sop, existingInfos);
                } else {
                    log.info("客户不符合条件且不在营期中，无需处理");
                }
            }
        } catch (Exception e) {
            log.error("处理客户在SOP中的营期管理时发生异常，客户ID: {}, SOP ID: {}",
                    customer.getCustomerId(), sop.getId(), e);
        }
    }

    /**
     * 查询客户在指定SOP下的所有营期成员记录
     *
     * @param sopId SOP ID
     * @param customerId 客户ID
     * @return 营期成员记录列表
     */
    @DataSource(DataSourceType.SOP)
    public List<WxSopUserInfo> querySopUserInfosByCustomer(Long sopId, Long customerId) {
        WxSopUserInfo queryParam = new WxSopUserInfo();
        queryParam.setSopId(sopId);
        queryParam.setCustomerId(customerId);
        return wxSopUserInfoMapper.selectWxSopUserInfoList(queryParam);
    }

    /**
     * 检查客户是否符合SOP的标签筛选条件
     * 注意：客户tags字段与SOP的selectTags/excludeTags统一使用标签值（label）进行比对
     *
     * @param customer 客户信息
     * @param sop SOP信息
     * @return true-符合条件，false-不符合条件
     */
    private boolean checkCustomerMatchSopTags(CrmCustomer customer, WxSop sop) {
        String customerTags = customer.getTags();
        if (customerTags == null || customerTags.trim().isEmpty()) {
            log.info("客户标签为空");
            // 如果客户没有标签，但SOP要求有筛选标签，则不符合
            return sop.getSelectTags() == null || sop.getSelectTags().trim().isEmpty();
        }

        // 客户的标签列表（逗号分隔的标签值）- 需要将dict_label转换为dict_value
        String[] customerTagArray = customerTags.split(",");
        List<String> customerTagIdList = new ArrayList<>();
        for (String tagLabel : customerTagArray) {
            if (tagLabel != null && !tagLabel.trim().isEmpty()) {
                // 将标签名(dict_label)转换为标签ID(dict_value)
                String tagId = com.fs.common.utils.DictUtils.getDictValue("crm_customer_tag", tagLabel.trim());
                if (tagId != null && !tagId.isEmpty()) {
                    customerTagIdList.add(tagId);
                }
            }
        }
        log.info("客户标签ID列表: {}", customerTagIdList);

        // 检查必须包含的标签（selectTags）- 直接使用标签ID比对
        if (sop.getSelectTags() != null && !sop.getSelectTags().trim().isEmpty()) {
            String[] selectTags = sop.getSelectTags().split(",");
            for (String tag : selectTags) {
                if (tag != null && !tag.trim().isEmpty()) {
                    String trimmedTag = tag.trim();
                    if (!customerTagIdList.contains(trimmedTag)) {
                        log.info("客户缺少必需标签ID: {}", trimmedTag);
                        return false;
                    }
                }
            }
            log.info("客户包含所有必需标签");
        }

        // 检查排除的标签（excludeTags）- 直接使用标签ID比对
        if (sop.getExcludeTags() != null && !sop.getExcludeTags().trim().isEmpty()) {
            String[] excludeTags = sop.getExcludeTags().split(",");
            for (String tag : excludeTags) {
                if (tag != null && !tag.trim().isEmpty()) {
                    String trimmedTag = tag.trim();
                    if (customerTagIdList.contains(trimmedTag)) {
                        log.info("客户包含排除标签ID: {}", trimmedTag);
                        return false;
                    }
                }
            }
            log.info("客户不包含排除标签");
        }

        log.info("客户符合SOP标签筛选条件");
        return true;
    }

    /**
     * 将客户加入SOP营期
     *
     * @param customer 客户信息
     * @param sop SOP信息
     */
    @DataSource(DataSourceType.SOP)
    public void addCustomerToSop(CrmCustomer customer, WxSop sop) {
        try {
            WxFilterSopCustomersResult customerResult = new WxFilterSopCustomersResult();
            customerResult.setId(customer.getCustomerId().toString());
            customerResult.setName(customer.getCustomerName());
            if (sop.getAccountIds() != null && !sop.getAccountIds().isEmpty()) {
                String[] accountIds = sop.getAccountIds().split(",");
                if (accountIds.length > 0) {
                    customerResult.setAccountId(accountIds[0].trim());
                }
            }

            if (customerResult.getAccountId() == null) {
                log.warn("无法获取执行账号，跳过加入营期");
                return;
            }

            // 获取或创建营期
            Long sopUserId = getOrCreateWxSopUser(sop, customerResult);
            if (sopUserId == null) {
                log.warn("创建营期失败，跳过");
                return;
            }

            // 创建营期成员记录
            WxSopUserInfo wxSopUserInfo = new WxSopUserInfo();
            wxSopUserInfo.setSopId(sop.getId());
            wxSopUserInfo.setSopUserId(sopUserId);
            wxSopUserInfo.setCustomerId(customer.getCustomerId());
            wxSopUserInfo.setStatus(0); // 正常状态
            wxSopUserInfo.setTagNames(customer.getTags());

            int result = wxSopUserInfoMapper.insertWxSopUserInfo(wxSopUserInfo);
            log.info("成功将客户加入营期：客户ID={}, 营期ID={}, SOP ID={}, 插入结果={}",
                    customer.getCustomerId(), sopUserId, sop.getId(), result);
        } catch (Exception e) {
            log.error("将客户加入SOP营期时发生异常", e);
        }
    }

    /**
     * 将客户从SOP营期中移出
     *
     * @param customer 客户信息
     * @param sop SOP信息
     * @param existingInfos 已存在的营期成员记录
     */
    @DataSource(DataSourceType.SOP)
    public void removeCustomerFromSop(CrmCustomer customer, WxSop sop, List<WxSopUserInfo> existingInfos) {
        try {
            for (WxSopUserInfo info : existingInfos) {
                int result = wxSopUserInfoMapper.deleteWxSopUserInfoById(info.getId());
                log.info("成功将客户从营期中移出：客户ID={}, 营期成员记录ID={}, SOP ID={}, 删除结果={}",
                        customer.getCustomerId(), info.getId(), sop.getId(), result);
            }
        } catch (Exception e) {
            log.error("将客户从SOP营期中移出时发生异常", e);
        }
    }
}
