package com.fs.company.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.domain.apiresult.Content;
import com.fs.aicall.domain.apiresult.Notify;
import com.fs.aicall.domain.apiresult.PushIIntentionResult;
import com.fs.aicall.domain.param.CalleeDomain;
import com.fs.aicall.domain.param.CalltaskcreateaiCustomizeDomain;
import com.fs.aicall.domain.result.CalltaskcreateaiCustomizeResult;
import com.fs.aicall.service.AiCallService;
import com.fs.common.annotation.DataScope;
import com.fs.common.core.domain.entity.SysDictData;
import com.fs.common.core.domain.model.LoginUser;
import com.fs.common.exception.base.BaseException;
import com.fs.common.utils.PubFun;
import com.fs.common.utils.SecurityUtils;
import com.fs.common.utils.ServletUtils;
import com.fs.common.utils.StringUtils;
import com.fs.company.domain.*;
import com.fs.company.mapper.CompanyVoiceRoboticCalleesMapper;
import com.fs.company.mapper.CompanyVoiceRoboticMapper;
import com.fs.company.mapper.CompanyVoiceRoboticWxMapper;
import com.fs.company.service.ICompanyVoiceRoboticService;
import com.fs.company.vo.AddWxClientVo;
import com.fs.company.vo.CompanyVoiceRoboticQwUserListVo;
import com.fs.company.vo.RoboticWxAccountVo;
import com.fs.company.vo.RoboticWxVo;
import com.fs.crm.domain.CrmCustomer;
import com.fs.crm.mapper.CrmCustomerMapper;
import com.fs.crm.service.impl.CrmCustomerServiceImpl;
import com.fs.his.config.AddWxConfig;
import com.fs.system.mapper.SysDictDataMapper;
import com.fs.system.service.ISysConfigService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 机器人外呼任务Service业务层处理
 *
 * @author fs
 * @date 2024-12-04
 */
@Slf4j
@Service
@AllArgsConstructor
public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRoboticMapper, CompanyVoiceRobotic> implements ICompanyVoiceRoboticService {

    private final CompanyVoiceRoboticMapper companyVoiceRoboticMapper;
    private final AiCallService aiCallService;
    private final CrmCustomerServiceImpl crmCustomerService;
    private final CompanyVoiceRoboticCalleesMapper companyVoiceRoboticCalleesMapper;

    private final CompanyVoiceRoboticCalleesServiceImpl companyVoiceRoboticCalleesService;

    private final CompanyVoiceRoboticWxMapper companyVoiceRoboticWxMapper;

    private final CompanyVoiceRoboticWxServiceImpl companyVoiceRoboticWxService;

    private final CrmCustomerMapper crmCustomerMapper;

    private final CompanyWxClientServiceImpl companyWxClientServiceImpl;

    private final ISysConfigService configService;

    private final SysDictDataMapper sysDictDataMapper;

    /**
     * 查询机器人外呼任务
     *
     * @param id 机器人外呼任务ID
     * @return 机器人外呼任务
     */
    @Override
    public CompanyVoiceRobotic selectCompanyVoiceRoboticById(Long id){
        CompanyVoiceRobotic companyVoiceRobotic = companyVoiceRoboticMapper.selectCompanyVoiceRoboticById(id);
        List<CompanyVoiceRoboticCallees> calleesList = companyVoiceRoboticCalleesMapper.selectByRoboticId(companyVoiceRobotic.getId());
        companyVoiceRobotic.setUserIds(calleesList.stream().map(e -> e.getUserId().toString()).collect(Collectors.toList()));
        return companyVoiceRobotic;
    }

    /**
     * 查询机器人外呼任务列表
     *
     * @param companyVoiceRobotic 机器人外呼任务
     * @return 机器人外呼任务
     */
    @Override
    public List<CompanyVoiceRobotic> selectCompanyVoiceRoboticList(CompanyVoiceRobotic companyVoiceRobotic){
        return companyVoiceRoboticMapper.selectCompanyVoiceRoboticList(companyVoiceRobotic);
    }
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<CompanyVoiceRobotic> selectCompanyVoiceRoboticListCompany(CompanyVoiceRobotic companyVoiceRobotic){
        return companyVoiceRoboticMapper.selectCompanyVoiceRoboticListCompany(companyVoiceRobotic);
    }

    /**
     * 新增机器人外呼任务
     *
     * @param companyVoiceRobotic 机器人外呼任务
     * @return 结果
     */
    @Override
    public int insertCompanyVoiceRobotic(CompanyVoiceRobotic companyVoiceRobotic){
        List<CrmCustomer> customerList = crmCustomerService.selectCrmCustomerListByIds(String.join(",", companyVoiceRobotic.getUserIds()));
        if(customerList.isEmpty()){
            throw new BaseException("拨打电话不能为空");
        }
        // 构建三方接口请求数据
        CalltaskcreateaiCustomizeDomain param = new CalltaskcreateaiCustomizeDomain();
        param.setRobot(companyVoiceRobotic.getRobot());
        param.setDialogID(companyVoiceRobotic.getDialogId());
        param.setMode(companyVoiceRobotic.getMode());
        int i = companyVoiceRoboticMapper.insertCompanyVoiceRobotic(companyVoiceRobotic);
        // 保存外呼电话列表
        List<CompanyVoiceRoboticCallees> calleesList = customerList.stream().map(e -> {
            CompanyVoiceRoboticCallees entity = new CompanyVoiceRoboticCallees();
            entity.setUserId(e.getCustomerId());
            entity.setUserName(e.getCustomerName());
            entity.setPhone(e.getMobile());
            entity.setRoboticId(companyVoiceRobotic.getId());
            return entity;
        }).collect(Collectors.toList());
        companyVoiceRoboticCalleesMapper.deleteByRoboticId(companyVoiceRobotic.getId());
        companyVoiceRoboticCalleesMapper.insertCompanyVoiceRoboticCalleesList(calleesList);
        // 外呼电话列表
        List<CalleeDomain> mobileList = calleesList.stream().map(e -> CalleeDomain.builder().number(e.getPhone()).userData(e.getId().toString()).build()).collect(Collectors.toList());
        param.setCallees(mobileList);

        param.setTaskName(companyVoiceRobotic.getName());
        param.setMultiplier(companyVoiceRobotic.getMultiplier());
        param.setAutoRecall(companyVoiceRobotic.getAutoRecall());
        param.setRecallTimes(companyVoiceRobotic.getRecallTimes());
        if(StringUtils.isNotEmpty(companyVoiceRobotic.getWeekDay1())){
            param.setWeekday1(Arrays.asList(companyVoiceRobotic.getWeekDay1().split(",")));
        }
        if(StringUtils.isNotEmpty(companyVoiceRobotic.getStartTime1())){
            param.setStartTime1(companyVoiceRobotic.getStartTime1() + ":00");
        }
        if(StringUtils.isNotEmpty(companyVoiceRobotic.getEndTime1())){
            param.setEndTime1(companyVoiceRobotic.getEndTime1() + ":00");
        }
        // 请求外呼接口
        CalltaskcreateaiCustomizeResult result = aiCallService.calltaskcreateaiCustomize(param);
        // 设置返回数据
        companyVoiceRobotic.setTaskId(result.getTaskID());
        companyVoiceRobotic.setTaskName(result.getTaskName());
        companyVoiceRoboticMapper.updateById(companyVoiceRobotic);
        // 设置加微微信列表
        List<RoboticWxVo> qwUserList = companyVoiceRobotic.getQwUserList();
        List<CompanyVoiceRoboticWx> collect = qwUserList.stream().map(e -> {
            CompanyVoiceRoboticWx entity = new CompanyVoiceRoboticWx();
            entity.setIntention(e.getIntention());
            entity.setRoboticId(companyVoiceRobotic.getId());
            entity.setAccountId(e.getCompanyUserId());
            entity.setWxDialogId(e.getWxDialogId());
            return entity;
        }).collect(Collectors.toList());
        companyVoiceRoboticWxService.saveBatch(collect);
        return i;
    }

    /**
     * 修改机器人外呼任务
     *
     * @param companyVoiceRobotic 机器人外呼任务
     * @return 结果
     */
    @Override
    public int updateCompanyVoiceRobotic(CompanyVoiceRobotic companyVoiceRobotic)
    {
        return companyVoiceRoboticMapper.updateCompanyVoiceRobotic(companyVoiceRobotic);
    }

    /**
     * 批量删除机器人外呼任务
     *
     * @param ids 需要删除的机器人外呼任务ID
     * @return 结果
     */
    @Override
    public int deleteCompanyVoiceRoboticByIds(Long[] ids)
    {
        return companyVoiceRoboticMapper.deleteCompanyVoiceRoboticByIds(ids);
    }

    /**
     * 删除机器人外呼任务信息
     *
     * @param id 机器人外呼任务ID
     * @return 结果
     */
    @Override
    public int deleteCompanyVoiceRoboticById(Long id)
    {
        return companyVoiceRoboticMapper.deleteCompanyVoiceRoboticById(id);
    }

    @Override
    public List<CompanyVoiceRoboticQwUserListVo> qwUserList() {
        return companyVoiceRoboticMapper.qwUserList();
    }

    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<CompanyVoiceRoboticQwUserListVo> qwUserListCompany(CompanyVoiceRobotic companyVoiceRobotic) {
        return companyVoiceRoboticMapper.qwUserListCompany(companyVoiceRobotic);
    }

    @Override
    public void callerResult(PushIIntentionResult result) {
        log.info("进入外呼回调:{}", JSON.toJSONString(result));
        Notify notify = result.getNotify();
        if(notify == null) return;
        if("pushDialogContent".equals(notify.getType())) pushDialogContent(result);
        if("billing".equals(notify.getType())) pushBilling(result);
        // 是否全部回调完毕
        CompanyVoiceRoboticCallees callee = getResultCalleeInfo(notify);
        long count = companyVoiceRoboticCalleesMapper.countByRoboticIdNotUuid(callee.getRoboticId());
        if(count == 0){
            new Thread(() -> dispenseWx(callee.getRoboticId())).start();
        }
    }

    public void pushDialogContent(PushIIntentionResult result){
        Notify notify = result.getNotify();
        SysDictData insData = sysDictDataMapper.selectDictDataByTypeAndValue("customer_intention_level", notify.getIntention());
        String intention = "无";
        if(insData != null){
            intention = insData.getDictLabel();
        }
        CompanyVoiceRoboticCallees callee = getResultCalleeInfo(notify);
        callee.setUuid(notify.getUuid());
        callee.setIntention(intention);
        if(notify.getContentList() != null && !notify.getContentList().isEmpty()){
            callee.setJson(JSON.toJSONString(notify.getContentList()));
        }
        callee.setResult(1);
        companyVoiceRoboticCalleesMapper.updateById(callee);
        CrmCustomer crmCustomer = crmCustomerMapper.selectCrmCustomerById(callee.getUserId());
        crmCustomer.setIntention(intention);
        crmCustomerMapper.updateById(crmCustomer);
    }
    public void pushBilling(PushIIntentionResult result){
        Notify notify = result.getNotify();
        CompanyVoiceRoboticCallees callee = getResultCalleeInfo(notify);
        callee.setResult(1);
        companyVoiceRoboticCalleesMapper.updateById(callee);
    }
    public CompanyVoiceRoboticCallees getResultCalleeInfo(Notify notify){
        CompanyVoiceRoboticCallees callee = companyVoiceRoboticCalleesMapper.selectCompanyVoiceRoboticCalleesById(Long.parseLong(notify.getUserData()));
        if(callee == null){
            log.error("回调错误,未找到拨打手机号记录:{}", notify);
            throw new BaseException("回调错误");
        }
        return callee;
    }

    @Override
    public void test(Long id) {
        List<String> list = Arrays.asList("A", "B", "C", "D", "E", "F");
        List<CompanyVoiceRoboticCallees> calleesList = companyVoiceRoboticCalleesMapper.selectByRoboticId(id);
        Map<Long, CompanyVoiceRoboticCallees> callMap = PubFun.listToMapByGroupObject(calleesList, CompanyVoiceRoboticCallees::getUserId);

        List<CrmCustomer> customerList = crmCustomerMapper.selectList(new QueryWrapper<CrmCustomer>().in("customer_id", PubFun.listToNewList(calleesList, CompanyVoiceRoboticCallees::getUserId)));
        customerList.forEach(e -> {
            CompanyVoiceRoboticCallees companyVoiceRoboticCallees = callMap.get(e.getCustomerId());
            Collections.shuffle(list);
            e.setIntention(list.get(0));
            companyVoiceRoboticCallees.setIntention(e.getIntention());
            companyVoiceRoboticCallees.setUuid(IdUtil.randomUUID());
        });
        companyVoiceRoboticCalleesService.updateBatchById(calleesList);
        crmCustomerService.updateBatchById(customerList);

    }

    @Override
    public void dispenseWx(Long roboticId){
        String json=configService.selectConfigByKey("add.wx");
        AddWxConfig bean = JSONUtil.toBean(json, AddWxConfig.class);
        Integer addWxNum = bean.getDayAddNum();
        // 任务详情
//        CompanyVoiceRobotic robotic = getById(roboticId);
        // 拨打电话列表
        List<CompanyVoiceRoboticCallees> calleesList = companyVoiceRoboticCalleesMapper.selectByRoboticId(roboticId);
        if(calleesList.isEmpty()) return;
        calleesList = calleesList.stream().filter(e -> StringUtils.isNotEmpty(e.getIntention())).collect(Collectors.toList());
        if(calleesList.isEmpty()) return;
        // 分配任务列表
        List<CompanyVoiceRoboticWx> roboticWxList = companyVoiceRoboticWxMapper.selectByRoboticId(roboticId);
        // 客户列表
        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 -> {
                CompanyWxClient companyWxClient = new CompanyWxClient();
                // 绑定销售
                bindCompany(companyWxClient, wxList, addWxNum);
                // 任务ID
                companyWxClient.setRoboticId(roboticId);
                // 客户名称
                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());
        companyVoiceRoboticWxService.updateBatchById(roboticWxList);
        companyWxClientServiceImpl.saveBatch(collect);
    }

    @Override
    public void addCompany(AddWxClientVo vo) {
        String json=configService.selectConfigByKey("add.wx");
        AddWxConfig bean = JSONUtil.toBean(json, AddWxConfig.class);
        Integer addWxNum = bean.getDayAddNum();
        // 任务详情
        List<RoboticWxAccountVo> qwUserList = vo.getQwUserList();
        List<CompanyVoiceRoboticWx> collect = qwUserList.stream().map(e -> {
            CompanyVoiceRoboticWx entity = new CompanyVoiceRoboticWx();
            entity.setIntention(e.getIntention());
            entity.setRoboticId(vo.getRoboticId());
            entity.setAccountId(e.getAccountId());
            entity.setWxDialogId(e.getWxDialogId());
            entity.setNum(0);
            return entity;
        }).collect(Collectors.toList());
        companyVoiceRoboticWxService.saveBatch(collect);
        List<CompanyWxClient> list = companyWxClientServiceImpl.list(new QueryWrapper<CompanyWxClient>().eq("robotic_id", vo.getRoboticId()).isNull("account_id").isNotNull("intention"));
        if(list.isEmpty()) return;
        Map<String, List<CompanyVoiceRoboticWx>> qwMap = PubFun.listToMapByGroupList(collect, CompanyVoiceRoboticWx::getIntention);
        Map<String, List<CompanyWxClient>> wxMap = PubFun.listToMapByGroupList(list, CompanyWxClient::getIntention);
        wxMap.entrySet().stream().filter(e -> qwMap.containsKey(e.getKey())).forEach(map -> {
            String k = map.getKey();
            List<CompanyWxClient> v = map.getValue();
            // 对应销售账号列表
            List<CompanyVoiceRoboticWx> wxList = qwMap.get(k);
            // 组装任务数据
            v.forEach(e -> bindCompany(e, wxList, addWxNum));
        });
        companyVoiceRoboticWxService.updateBatchById(collect);
        companyWxClientServiceImpl.updateBatchById(list);
    }


    // 绑定销售
    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());
        }
    }
}
