package com.fs.aiob.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fs.aicall.params.AiobImportPhoneParam;
import com.fs.aicall.utils.AiobApiUtils;
import com.fs.aicall.utils.AiobPhoneEncryption;
import com.fs.aicall.vo.AiobCalleData;
import com.fs.aicall.vo.AiobImportPhoneVo;
import com.fs.aicall.vo.AiobTaskData;
import com.fs.aiob.domain.AiobBaiduEncryption;
import com.fs.aiob.domain.AiobBaiduTask;
import com.fs.aiob.mapper.AiobBaiduTaskMapper;
import com.fs.aiob.service.IAiobBaiduEncryptionService;
import com.fs.aiob.service.IAiobBaiduTaskService;
import com.fs.common.core.domain.BaseEntityTow;
import com.fs.common.exception.base.BaseException;
import com.fs.common.service.ISmsService;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.PubFun;
import com.fs.common.utils.StringUtils;
import com.fs.company.domain.CompanySmsTemp;
import com.fs.company.domain.CompanyVoiceRoboticCallees;
import com.fs.company.domain.CompanyVoiceRoboticWx;
import com.fs.company.domain.CompanyWxClient;
import com.fs.company.mapper.CompanyVoiceRoboticCalleesMapper;
import com.fs.company.mapper.CompanyVoiceRoboticWxMapper;
import com.fs.company.service.ICompanySmsTempService;
import com.fs.company.service.ICompanyVoiceRoboticCalleesService;
import com.fs.company.service.ICompanyVoiceRoboticWxService;
import com.fs.company.service.impl.CompanyWxClientServiceImpl;
import com.fs.crm.domain.CrmCustomer;
import com.fs.crm.mapper.CrmCustomerMapper;
import com.fs.common.param.SmsSendParam;
import com.fs.crm.service.impl.CrmCustomerServiceImpl;
import com.fs.his.config.AddWxConfig;
import com.fs.qw.domain.QwWorkLink;
import com.fs.qw.service.IQwWorkLinkService;
import com.fs.system.mapper.SysDictDataMapper;
import com.fs.system.service.ISysConfigService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 百度AI外呼任务Service业务层处理
 * 
 * @author fs
 * @date 2025-03-20
 */
@Slf4j
@Service
@AllArgsConstructor
public class AiobBaiduTaskServiceImpl extends ServiceImpl<AiobBaiduTaskMapper, AiobBaiduTask> implements IAiobBaiduTaskService {


    private final AiobApiUtils aiobApiUtils;
    private final IAiobBaiduEncryptionService aiobBaiduEncryptionService;
    private final CrmCustomerServiceImpl crmCustomerService;
    private final CompanyVoiceRoboticCalleesMapper companyVoiceRoboticCalleesMapper;
    private final ICompanyVoiceRoboticCalleesService companyVoiceRoboticCalleesService;
    private final CrmCustomerMapper crmCustomerMapper;
    private final ICompanyVoiceRoboticWxService companyVoiceRoboticWxService;
    private final CompanyWxClientServiceImpl companyWxClientServiceImpl;
    private final ISysConfigService configService;
    private final SysDictDataMapper sysDictDataMapper;
    private final CompanyVoiceRoboticWxMapper companyVoiceRoboticWxMapper;
    private final IQwWorkLinkService qwWorkLinkService;
    private final ISmsService smsService;
    private final ICompanySmsTempService smsTempService;

    /**
     * 查询百度AI外呼任务
     * 
     * @param id 百度AI外呼任务主键
     * @return 百度AI外呼任务
     */
    @Override
    public AiobBaiduTask selectAiobBaiduTaskById(Long id)
    {
        return baseMapper.selectAiobBaiduTaskById(id);
    }

    /**
     * 查询百度AI外呼任务列表
     * 
     * @param aiobBaiduTask 百度AI外呼任务
     * @return 百度AI外呼任务
     */
    @Override
    public List<AiobBaiduTask> selectAiobBaiduTaskList(AiobBaiduTask aiobBaiduTask)
    {
        return baseMapper.selectAiobBaiduTaskList(aiobBaiduTask);
    }

    /**
     * 新增百度AI外呼任务
     * 
     * @param aiobBaiduTask 百度AI外呼任务
     * @return 结果
     */
    @Override
    public int insertAiobBaiduTask(AiobBaiduTask aiobBaiduTask){
        List<CrmCustomer> customerList;
        if(StringUtils.isNotEmpty(aiobBaiduTask.getUserIds())){
            customerList = crmCustomerService.selectCrmCustomerListByIds(String.join(",", aiobBaiduTask.getUserIds()));
        }else{
            customerList = new ArrayList<>();
        }
//        if(customerList.isEmpty()){
//            throw new BaseException("拨打电话不能为空");
//        }
        aiobBaiduTask.setCreateTime(DateUtils.getNowDate());
        // 创建任务
        aiobApiUtils.createTask(aiobBaiduTask);
        int insert = baseMapper.insert(aiobBaiduTask);
        // 保存外呼电话列表
        List<CompanyVoiceRoboticCallees> calleesList = customerList.stream().map(e -> {
            CompanyVoiceRoboticCallees entity = new CompanyVoiceRoboticCallees();
            entity.setUserId(e.getCustomerId());
            entity.setType(1);
            entity.setUserName(e.getCustomerName());
            entity.setPhone(e.getMobile());
            entity.setRoboticId(aiobBaiduTask.getId());
            return entity;
        }).collect(Collectors.toList());
        companyVoiceRoboticCalleesMapper.deleteByRoboticId(aiobBaiduTask.getId());
        if(!calleesList.isEmpty()){
            companyVoiceRoboticCalleesMapper.insertCompanyVoiceRoboticCalleesList(calleesList);
        }
        List<AiobBaiduEncryption> list = aiobBaiduEncryptionService.list();
        if(list.isEmpty()){
            throw new BaseException("密码加密不能为空");
        }
        AiobBaiduEncryption aiobBaiduEncryption = list.get(0);
        if(!calleesList.isEmpty()){
            AiobImportPhoneParam phoneVo = new AiobImportPhoneParam();
            phoneVo.setTaskId(aiobBaiduTask.getTaskId());
            phoneVo.setSecretType(1);
            phoneVo.setSecretId(aiobBaiduEncryption.getSecretId());
            phoneVo.setCustomerInfoList(calleesList.stream().map(e -> {
                AiobImportPhoneParam.CustomerInfoList info = new AiobImportPhoneParam.CustomerInfoList();
                info.setExtJson(e.getId().toString());
                info.setMobile(AiobPhoneEncryption.encryptAES(e.getPhone(), aiobBaiduEncryption.getSecretKey()));
                return info;
            }).collect(Collectors.toList()));
            Map<String, CompanyVoiceRoboticCallees> calleesMap = PubFun.listToMapByGroupObject(calleesList, e -> e.getId().toString());
            List<AiobImportPhoneVo> importPhoneVos = aiobApiUtils.importPhone(phoneVo);
            importPhoneVos.forEach(e -> {
                CompanyVoiceRoboticCallees callees = calleesMap.get(e.getExtJson());
                callees.setTaskMemberId(e.getTaskMemberId());
                callees.setImportStatus(e.getStatus());
                callees.setReason(e.getReason());
            });
            companyVoiceRoboticCalleesService.updateBatchById(calleesList);
        }
        addQw(aiobBaiduTask);
        if(aiobBaiduTask.getType() == 2){
            dispenseQw(aiobBaiduTask.getId());
//            new Thread(() -> dispenseQw(aiobBaiduTask.getId())).start();
        }
        return insert;
    }
    private void addQw(AiobBaiduTask task) {
        List<CompanyVoiceRoboticWx> collect;
        if(task.getType() == 1){
            // 设置加微微信列表
            collect = task.getQwUserList().stream().map(e -> {
                CompanyVoiceRoboticWx entity = new CompanyVoiceRoboticWx();
                entity.setAddType(task.getType());
                entity.setIntention(e.getIntention());
                entity.setAccountId(e.getCompanyUserId());
                entity.setWxDialogId(e.getWxDialogId());
                return entity;
            }).collect(Collectors.toList());
        }else{
            collect = task.getWorkUrl().stream().map(e -> {
                CompanyVoiceRoboticWx entity = new CompanyVoiceRoboticWx();
                entity.setAddType(task.getType());
                entity.setIntention(e);
                return entity;
            }).collect(Collectors.toList());
        }
        collect.forEach(e -> {
            e.setRoboticId(task.getId());
            e.setType(1);
        });
        companyVoiceRoboticWxService.saveBatch(collect);
    }

    /**
     * 修改百度AI外呼任务
     * 
     * @param aiobBaiduTask 百度AI外呼任务
     * @return 结果
     */
    @Override
    public int updateAiobBaiduTask(AiobBaiduTask aiobBaiduTask)
    {
        aiobBaiduTask.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateAiobBaiduTask(aiobBaiduTask);
    }

    /**
     * 批量删除百度AI外呼任务
     * 
     * @param ids 需要删除的百度AI外呼任务主键
     * @return 结果
     */
    @Override
    public int deleteAiobBaiduTaskByIds(Long[] ids){
        List<AiobBaiduTask> taskList = list(new QueryWrapper<AiobBaiduTask>().in("id", ids));
        if(taskList.stream().anyMatch(e -> e.getTaskStatus() == 2)){
            throw new BaseException("任务正在执行无法删除");
        }
        int i = baseMapper.deleteAiobBaiduTaskByIds(ids);
        aiobApiUtils.deleteTask(PubFun.listToNewList(taskList, AiobBaiduTask::getTaskId));
        return i;
    }

    /**
     * 删除百度AI外呼任务信息
     * 
     * @param id 百度AI外呼任务主键
     * @return 结果
     */
    @Override
    public int deleteAiobBaiduTaskById(Long id)
    {
        return baseMapper.deleteAiobBaiduTaskById(id);
    }

    @Override
    public void back(AiobCalleData vo) {
        log.info("进入外呼回调:{}", JSON.toJSONString(vo));
        // 接通
        if(vo.getEndType() == 1) pushDialogContent(vo);
        // 未接通
        if(vo.getEndType() == 0) pushBilling(vo);
        // 是否全部回调完毕
        CompanyVoiceRoboticCallees callee = getResultCalleeInfo(vo);
        AiobBaiduTask byId = getById(callee.getRoboticId());
        // 企微
        if(byId.getType() == 2){
            CrmCustomer crmCustomer = crmCustomerMapper.selectCrmCustomerById(callee.getUserId());
            SmsSendParam param = new SmsSendParam();
            param.setCustomerId(crmCustomer.getCustomerId());
            param.setTempCode("aiob-wok-link");
            param.setCompanyId(crmCustomer.getCompanyId());
            param.setCompanyUserId(crmCustomer.getCustomerUserId());
            param.setSmsType(2);
            param.setMobile(callee.getPhone());
            CompanySmsTemp temp=smsTempService.selectCompanySmsTempByCode(param.getTempCode());
            param.setContent(temp.getContent());
            CompanyWxClient one = companyWxClientServiceImpl.getOne(new QueryWrapper<CompanyWxClient>().eq("add_type", 2).eq("robotic_id", callee.getRoboticId()).eq("customer_id", callee.getUserId()));
            param.setWorkUrl(one.getWorkUrl());
            smsService.sendSms(param);
        }
        if(byId.getType() == 1){
            long count = companyVoiceRoboticCalleesMapper.countByRoboticIdNotUuid(callee.getRoboticId());
            if(count == 0){
                new Thread(() -> dispenseWx(callee.getRoboticId())).start();
            }
        }
    }

    @Override
    public void updateStatus(AiobTaskData vo) {
        if(vo.getTaskId() == null) return;
        AiobBaiduTask task = getOne(new QueryWrapper<AiobBaiduTask>().eq("task_id", vo.getTaskId()));
        if(task == null) return;
        task.setTaskStatus(vo.getTaskStatus());
        task.setUpdateReason(vo.getReason());
        updateById(task);
    }

    @Override
    public void changeStatus(String taskId, Integer status) {
        aiobApiUtils.changeStatus(taskId, status);
        AiobTaskData vo = new AiobTaskData();
        vo.setTaskId(Long.parseLong(taskId));
        vo.setTaskStatus(status);
        vo.setReason("等待任务状态同步中");
        updateStatus(vo);
    }

    public void pushDialogContent(AiobCalleData vo){
        String intention = "无";
        String tagName = "意向等级";
        if(vo.getTagExtractInfo() != null && !vo.getTagExtractInfo().isEmpty() && vo.getTagExtractInfo().containsKey(tagName) && vo.getTagExtractInfo().get(tagName) != null){
            intention = vo.getTagExtractInfo().get(tagName).toString();
        }
        CompanyVoiceRoboticCallees callee = getResultCalleeInfo(vo);
        callee.setUuid(vo.getSessionId());
        callee.setIntention(intention);
        if(vo.getRecord() != null && !vo.getRecord().isEmpty()){
            callee.setJson(JSON.toJSONString(vo.getRecord()));
        }
        callee.setResult(1);
        companyVoiceRoboticCalleesMapper.updateById(callee);
        CrmCustomer crmCustomer = crmCustomerMapper.selectCrmCustomerById(callee.getUserId());
        crmCustomer.setIntention(intention);
        crmCustomerMapper.updateById(crmCustomer);
    }
    public void pushBilling(AiobCalleData vo){
        CompanyVoiceRoboticCallees callee = getResultCalleeInfo(vo);
        callee.setResult(1);
        companyVoiceRoboticCalleesMapper.updateById(callee);
    }
    public CompanyVoiceRoboticCallees getResultCalleeInfo(AiobCalleData vo){
        if(StringUtils.isEmpty(vo.getExtJson())){
            log.error("回调错误,未找到拨打手机号记录:{}", vo);
            throw new BaseException("回调错误");
        }
        CompanyVoiceRoboticCallees callee = companyVoiceRoboticCalleesMapper.selectCompanyVoiceRoboticCalleesById(Long.parseLong(vo.getExtJson()));
        if(callee == null){
            log.error("回调错误,未找到拨打手机号记录:{}", vo);
            throw new BaseException("回调错误");
        }
        return callee;
    }

    public void dispenseQw(Long roboticId){
        // 拨打电话列表
        List<CompanyVoiceRoboticCallees> calleesList = companyVoiceRoboticCalleesMapper.selectByRoboticId(roboticId);
        // 分配任务列表
        List<CompanyVoiceRoboticWx> roboticWxList = companyVoiceRoboticWxMapper.selectByRoboticId(roboticId);
        // 客户列表
        List<CrmCustomer> customerList = crmCustomerMapper.selectCrmCustomerListByIds(calleesList.stream().map(e -> e.getUserId().toString()).collect(Collectors.joining(",")));
        Map<Long, CrmCustomer> customerMap = PubFun.listToMapByGroupObject(customerList, CrmCustomer::getCustomerId);

        List<Long> workIds = PubFun.listToNewList(roboticWxList, e -> Long.parseLong(e.getIntention()));
        List<QwWorkLink> workLinkList = qwWorkLinkService.list(new QueryWrapper<QwWorkLink>().in("id", workIds));
        Map<Long, QwWorkLink> workLinkMap = PubFun.listToMapByGroupObject(workLinkList, BaseEntityTow::getId);

        AtomicInteger i = new AtomicInteger();
        List<CompanyWxClient> collect = calleesList.stream().map(e -> {
            int index = i.getAndIncrement();
            if(index == roboticWxList.size() - 1){
                i.set(0);
            }
            CompanyVoiceRoboticWx wx = roboticWxList.get(index);

            CrmCustomer customers = customerMap.get(e.getUserId());
            e.setDistribute(1);
            CompanyWxClient companyWxClient = new CompanyWxClient();

            wx.setNum(wx.getNum() + 1);
            companyWxClient.setRoboticWxId(wx.getId());
            // 任务ID
            companyWxClient.setRoboticId(roboticId);
            companyWxClient.setAddType(2);
            // 客户名称
            companyWxClient.setNickName(customers.getCustomerName());
            // 手机号
            companyWxClient.setPhone(customers.getMobile());
            // 微信号
            companyWxClient.setWxNo(customers.getWeixin());
            // 微信号
            companyWxClient.setCustomerId(customers.getCustomerId());

            companyWxClient.setIntention(wx.getIntention());

            return companyWxClient;
        }).collect(Collectors.toList());


//        List<CompanyWxClient> collect = roboticWxList.stream().map(e -> {
//            CompanyVoiceRoboticCallees companyVoiceRoboticCallees = calleesList.get(i.getAndIncrement());
//            CrmCustomer customers = customerMap.get(companyVoiceRoboticCallees.getUserId());
//            companyVoiceRoboticCallees.setDistribute(1);
//            CompanyWxClient companyWxClient = new CompanyWxClient();
//            // 任务ID
//            companyWxClient.setRoboticId(roboticId);
//            companyWxClient.setAddType(2);
//            // 客户名称
//            companyWxClient.setNickName(customers.getCustomerName());
//            // 手机号
//            companyWxClient.setPhone(customers.getMobile());
//            // 微信号
//            companyWxClient.setWxNo(customers.getWeixin());
//            // 微信号
//            companyWxClient.setCustomerId(customers.getCustomerId());
//
//            companyWxClient.setIntention(e.getIntention());
//
//            return companyWxClient;
//        }).collect(Collectors.toList());
        companyVoiceRoboticCalleesService.updateBatchById(calleesList);
        companyVoiceRoboticWxService.updateBatchById(roboticWxList);
        companyWxClientServiceImpl.saveBatch(collect);
//        collect.forEach(e -> {
//            QwWorkLink qwWorkLink = workLinkMap.get(Long.parseLong(e.getIntention()));
//            e.setWorkShortNo("QW-" + IdUtil.simpleUUID());
//            String url = qwWorkShortLinkService.addWxLink(qwWorkLink, e.getWorkShortNo());
//            e.setWorkUrl(url);
//        });
        companyWxClientServiceImpl.updateBatchById(collect);


    }
    public void dispenseWx(Long roboticId){
        String json=configService.selectConfigByKey("add.wx");
        AddWxConfig bean = JSONUtil.toBean(json, AddWxConfig.class);
        Integer addWxNum = bean.getDayAddNum();
        // 任务详情
        // 拨打电话列表
        List<CompanyVoiceRoboticCallees> calleesList = companyVoiceRoboticCalleesMapper.selectByRoboticId(roboticId);
        if(calleesList.isEmpty()) return;
        calleesList = calleesList.stream().filter(e -> StringUtils.isNotEmpty(e.getIntention()) && e.getDistribute() == 0).collect(Collectors.toList());
        if(calleesList.isEmpty()) return;
        Map<Long, CompanyVoiceRoboticCallees> calleesMap = PubFun.listToMapByGroupObject(calleesList, CompanyVoiceRoboticCallees::getUserId);
        // 分配任务列表
        List<CompanyVoiceRoboticWx> roboticWxList = companyVoiceRoboticWxMapper.selectByRoboticId(roboticId).stream().filter(e-> e.getAddNum() < addWxNum).collect(Collectors.toList());
        // 客户列表
        List<CrmCustomer> customerList = crmCustomerMapper.selectCrmCustomerListByIds(calleesList.stream().map(e -> e.getUserId().toString()).collect(Collectors.joining(",")));
        Map<String, List<CrmCustomer>> customerMap = PubFun.listToMapByGroupList(customerList, CrmCustomer::getIntention);
        Map<String, List<CompanyVoiceRoboticWx>> roboticWxMap = PubFun.listToMapByGroupList(roboticWxList, CompanyVoiceRoboticWx::getIntention);
        // 循环客户
        List<CompanyWxClient> collect = customerMap.entrySet().stream().filter(e -> roboticWxMap.containsKey(e.getKey())).flatMap(map -> {
            String k = map.getKey();
            List<CrmCustomer> v = map.getValue();
            // 对应销售账号列表
            List<CompanyVoiceRoboticWx> wxList = roboticWxMap.get(k);
            // 组装任务数据
            return v.stream().map(e -> {
                CompanyVoiceRoboticCallees companyVoiceRoboticCallees = calleesMap.get(e.getCustomerId());
                companyVoiceRoboticCallees.setDistribute(1);
                CompanyWxClient companyWxClient = new CompanyWxClient();
                // 绑定销售
                bindCompany(companyWxClient, wxList, addWxNum);
                // 任务ID
                companyWxClient.setRoboticId(roboticId);
                companyWxClient.setAddType(1);
                // 客户名称
                companyWxClient.setNickName(e.getCustomerName());
                // 手机号
                companyWxClient.setPhone(e.getMobile());
                // 微信号
                companyWxClient.setWxNo(e.getWeixin());
                // 微信号
                companyWxClient.setCustomerId(e.getCustomerId());
                // 意向
                companyWxClient.setIntention(e.getIntention());
                return companyWxClient;
            });
        }).collect(Collectors.toList());
        companyVoiceRoboticCalleesService.updateBatchById(calleesList);
        companyVoiceRoboticWxService.updateBatchById(roboticWxList);
        companyWxClientServiceImpl.saveBatch(collect);
    }
    // 绑定销售
    private static void bindCompany(CompanyWxClient client, List<CompanyVoiceRoboticWx> wxList, Integer addWxNum) {
        List<CompanyVoiceRoboticWx> wx = wxList.stream().filter(f -> f.getNum() < addWxNum).collect(Collectors.toList());
        // 绑定销售,添加值达到阈值后设置为空,等待下次绑定
        if (!wx.isEmpty()) {
            CompanyVoiceRoboticWx companyVoiceRoboticWx = wx.get(0);
            companyVoiceRoboticWx.setNum(companyVoiceRoboticWx.getNum() + 1);
            client.setDialogId(companyVoiceRoboticWx.getWxDialogId());
            client.setRoboticWxId(companyVoiceRoboticWx.getId());
        }
    }
}
