package com.ruoyi.project.business.service.task;


import cn.hutool.core.collection.CollectionUtil;
import com.ruoyi.project.business.domain.TbArea;
import com.ruoyi.project.business.domain.TcLead;
import com.ruoyi.project.business.domain.TcLeadHistory;
import com.ruoyi.project.business.enums.RoleEnum;
import com.ruoyi.project.business.enums.lead.LeadStatusEnum;
import com.ruoyi.project.business.service.ITbAreaService;
import com.ruoyi.project.business.service.ITcLeadHistoryService;
import com.ruoyi.project.business.service.ITcLeadService;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.ruoyi.project.business.enums.lead.LeadHisTypeEnum.ALLOCATION;

/**
 * @author fangk
 * @date 2024/4/24
 * @desc LeadTaskService 线索任务 service
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LeadTaskService {

    private final ITcLeadService tcLeadService;
    private final ISysUserService sysUserService;
    private final ITbAreaService tbAreaService;
    private final TransactionTemplate transactionTemplate;
    private final ITcLeadHistoryService tcLeadHistoryService;


    public void autoAssignLead() {

        /* 
        查询全部来自市场部并且未分配的线索:
         目前逻辑是，线索新增时，当新增用户的所属是总部，并且区域是全球时， 线索表的 owner 不设值,表示市场部的线索。
         否则设为当前用户的id，表示是用户的线索。
         */
        List<TcLead> tcLeads = tcLeadService.selectLeadsFromMarketAndUnassigned();
        if (CollectionUtil.isEmpty(tcLeads)) {
            log.info("市场部线索自动分配任务结束，没有需要分配的线索");
            return;
        }

        // 线索无法分配到全球，也就是至少在大区，权限字符至少有两个。此时倒数第二个一定是大区的权限字符即大区id
        List<Long> areaIds = tcLeads.stream().map(TcLead::getAreaId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<TbArea> areas = tbAreaService.selectAreaListByIds(areaIds);
        // 区域id -> 完整区域链路
        Map<Long, List<String>> area2FullAreaIds = areas.stream()
                .filter(item -> StringUtils.isNotBlank(item.getPermissionChar()))
                .collect(Collectors.toMap(
                        TbArea::getAreaId,
                        item -> Arrays.stream(item.getPermissionChar().split(","))
                                .filter(StringUtils::isNotBlank)
                                .collect(Collectors.toList()),
                        (k1, k2) -> k2));

        // 线索id -> 完整区域链路
        Map<Long, List<String>> lead2FullAreaIds = tcLeads.stream().collect(Collectors.toMap(TcLead::getLeadId, item -> area2FullAreaIds.get(item.getAreaId())));

        // 查询所有的 区域总监 用户
        List<SysUser> regionalDirectors = sysUserService.selectUserByRoleKeyAndAreaId(RoleEnum.AREA_SALES_DIRECTOR.getKey(), null);

        // 区域id -> 区总用户
        Map<Long, SysUser> areaId2RDId = new HashMap<>();
        for (SysUser user : regionalDirectors) {
            for (Long areaId : user.getAreaIdList()) {
                areaId2RDId.put(areaId, user);
            }
        }
        // 从线索对应的区域id集合中,找出对应的区总id
        lead2FullAreaIds.forEach((leadId, fullAreaIds) -> {
            for (String fullAreaId : fullAreaIds) {
                Long areaId = Long.parseLong(fullAreaId);
                if (areaId2RDId.containsKey(areaId)) {
                    SysUser user = areaId2RDId.get(areaId);
                    Long rdId = user.getUserId();
                    transactionTemplate.execute(status -> {
                        try {
                            // 更新线索
                            TcLead build = TcLead.builder()
                                    .leadId(leadId)
                                    .status(LeadStatusEnum.ALLOCATED.getCode())
                                    .owner(rdId)
                                    .permissionChar(user.getPermissionChar())
                                    .build();

                            build.setUpdateBy("1");
                            build.setRemark("市场部线索自动分配任务");

                            boolean r1 = tcLeadService.updateById(build);


                            // 插入履历
                            TcLeadHistory buildHis = TcLeadHistory.builder()
                                    .leadId(leadId)
                                    .oriUser(1L)
                                    .actionType(ALLOCATION.getCode())
                                    .getUser(rdId)
                                    .build();
                            buildHis.setCreateBy("1");
                            buildHis.setRemark("市场部线索自动分配任务");

                            boolean r2 = tcLeadHistoryService.save(buildHis);

                            if (r1 && r2) {
                                return true;
                            } else {
                                throw new RuntimeException("线索id：【" + leadId + "】分配给区总：【" + user.getUserName() + "】失败");
                            }
                        } catch (Exception e) {
                            status.setRollbackOnly();
                            log.error("线索：【{}】分配给区总：【{}】失败", leadId, rdId, e);
                        }
                        return false;
                    });
                    break;
                }
            }
        });

    }

}