package cn.superdesk.uniorder.dubbo.provider.operationCenter.customer;

import cn.hutool.core.date.DateUtil;
import cn.superdesk.data.extract.enums.opCenter.OpCenterBizPlatformEnum;
import cn.superdesk.uniorder.common.exception.UnifiedOrderRuntimeException;
import cn.superdesk.uniorder.common.exception.constants.ExceptionMsg;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.dao.entity.operationCenter.OperationCenterBusiness;
import cn.superdesk.uniorder.dao.entity.operationCenter.UnifiedCenterCustomer;
import cn.superdesk.uniorder.dao.entity.operationCenter.UnifiedCustomerOperatorOrg;
import cn.superdesk.uniorder.dto.param.operationCenter.base.OperationCenterParam;
import cn.superdesk.uniorder.dto.param.operationCenter.customer.OpCenterCustomerOperatorOrgParam;
import cn.superdesk.uniorder.dto.param.operationCenter.customer.OpCenterOperatorOrgParam;
import cn.superdesk.uniorder.dto.param.operationCenter.customer.OperationCenterCustomerParam;
import cn.superdesk.uniorder.dto.param.operationCenter.customer.OperationCenterCustomerSaveParam;
import cn.superdesk.uniorder.dto.param.organisation.SysOrgQueryParam;
import cn.superdesk.uniorder.dto.vo._function.select.SelectOptionOrg;
import cn.superdesk.uniorder.dto.vo.operationCenter.base.OperationCenterVo;
import cn.superdesk.uniorder.dto.vo.operationCenter.customer.OpCenterCustomerOperatorOrgVo;
import cn.superdesk.uniorder.dto.vo.operationCenter.customer.OperationCenterCustomerVo;
import cn.superdesk.uniorder.dto.vo.operationCenter.customer.OperationCenterPaymentCustomerVo;
import cn.superdesk.uniorder.dto.vo.sys.SysSelectVo;
import cn.superdesk.uniorder.dubbo.facade.operationCenter.customer.DubboOperationCenterCustomerService;
import cn.superdesk.uniorder.dubbo.facade.organisation.DubboSysOrganizationService;
import cn.superdesk.uniorder.service.operationCenter.OperationCenterBusinessService;
import cn.superdesk.uniorder.service.operationCenter.OperationCenterCustomerOperatorOrgService;
import cn.superdesk.uniorder.service.operationCenter.OperationCenterCustomerService;
import cn.superdesk.uniorder.service.organisation.SysOrganizationService;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson2.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author : zx
 * @Create : 2023/4/11 09:49
 * Description : 调操作mapper的service层
 */
@Slf4j
@Service(version = "1.0.0", retries = -1, timeout = 10000)
public class DubboOperationCenterCustomerServiceImpl implements DubboOperationCenterCustomerService {
    @Autowired
    private OperationCenterCustomerService operationCenterCustomerService;
    @Autowired
    private OperationCenterCustomerOperatorOrgService operationCenterCustomerOperatorOrgService;

    @Autowired
    private SysOrganizationService sysOrganizationService;

    @Autowired
    private  OperationCenterBusinessService operationCenterBusinessService;





    @Override
    public R<List<OperationCenterCustomerVo>> getOperationCenterCustomerList(OperationCenterCustomerParam param) {
        PageHelper.startPage(param.getPageNumber(), param.getPageSize());
        List<OperationCenterCustomerVo> operationCenterCustomerVoList = operationCenterCustomerService.getOperationCenterCustomerList(param);
        PageInfo<OperationCenterCustomerVo> page = new PageInfo<>(operationCenterCustomerVoList);

        return new R<List<OperationCenterCustomerVo>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), operationCenterCustomerVoList);
    }

    /**
     * 新增，修改客户信息
     *
     * @param param
     * @return
     */
    @Override
    public R<String> saveOperationCenterCustomer(OperationCenterCustomerSaveParam param, Long userId) {
        if (null == userId) {
            log.info("新增或修改userId，不能为空！");
            return new R("500", "新增或修改userId，不能为空！！", false);
        }
        //排除自己
        UnifiedCenterCustomer customerTemp = operationCenterCustomerService.selectCustomerByCustomerName(param.getCustomerName(), param.getId());
        if (null != customerTemp) {
            return new R("500", "客户名称已存在！", false);
        }

        if (null != param.getBusinessId()) {
            OperationCenterBusiness entity = operationCenterBusinessService.findById(param.getBusinessId());
            param.setBusinessName(entity.getUserName());
        }

        //通过id判断是新增 或者修改
        if (null == param.getId()) {
            UnifiedCenterCustomer customer = new UnifiedCenterCustomer();
            BeanUtils.copyProperties(param, customer);
            customer.setCreateUserId(userId);
            customer.setCreateTime(new Date());
            customer.setUpdateUserId(userId);
            customer.setUpdateTime(new Date());
            //生成客户编号 生成规则“C+80+当天月日（无年）+5位随机数” (10000
            int random = (int) (new Random().nextDouble() * (99999 - 10000 + 1)) + 10000;
            customer.setCustomerSn("C80" + DateUtil.format(new Date(), "MMdd") + random);
            operationCenterCustomerService.insertSelective(customer);
        } else {
            UnifiedCenterCustomer customer = operationCenterCustomerService.findById(param.getId());
            BeanUtils.copyProperties(param, customer);
            customer.setUpdateUserId(userId);
            customer.setUpdateTime(new Date());
            operationCenterCustomerService.updateByPrimaryKeySelective(customer);
            log.info("修改客户信息" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + "  用户ID为：" + userId);
        }


        return new R<>("成功");
    }

    @Override
    public OperationCenterCustomerVo getOperationCenterCustomerById(Long id) {
        OperationCenterCustomerParam param = new OperationCenterCustomerParam();
        param.setId(id);
        List<OperationCenterCustomerVo> operationCenterCustomerVoList = operationCenterCustomerService.getOperationCenterCustomerList(param);
        if (CollectionUtils.isNotEmpty(operationCenterCustomerVoList)) {
            return operationCenterCustomerVoList.get(0);
        }
        return new OperationCenterCustomerVo();
    }

    @Override
    public R<String> deleteOperationCenterCustomerById(Long id) {
        operationCenterCustomerService.deleteObj(id);
        return new R<>("成功");
    }

    @Override
    public R<List<OperationCenterVo>> selectAllCustomerIdAndName() {
        List<OperationCenterVo> operationCenterVos = operationCenterCustomerService.selectAllCustomerIdAndName();
        return new R<>(operationCenterVos);
    }

    @Override
    public R<List<OperationCenterPaymentCustomerVo>> findAll(OperationCenterCustomerParam param) {
        List<OperationCenterPaymentCustomerVo> voList = operationCenterCustomerService.findAllCustomer(param);
        return new R<>(voList);
    }

    @Override
    public R<String> linkOperatorAndOrg(OpCenterCustomerOperatorOrgParam param, Long userId) {
        // 校验
        if (null == userId) {
            return new R<>("500", "未解析到该用户，请重新登录！", false);
        }

        UnifiedCenterCustomer entity = operationCenterCustomerService.findById(param.getCustomerId());
        if (null == entity) {
            return new R<>("500", "未查询到该客户！！", false);
        }
        /**
         * 当关联关系 运营商为空时，即客户没有配置关联，删除关联关系数据，并修改数据权限 为未配置
         */
        if (CollectionUtils.isEmpty(param.getOpCenterOperatorOrgList())) {
            //先将之前客户数据删除
            operationCenterCustomerOperatorOrgService.deleteByCustomerId(param.getCustomerId(), userId);

            //修改 客户主体 未配置
            entity.setIsDataPermission((byte) 0);
            entity.setUpdateUserId(userId);
            entity.setUpdateTime(new Date());
            operationCenterCustomerService.updateByPrimaryKeySelective(entity);
            return new R<>("保存成功");
        }

        List<UnifiedCustomerOperatorOrg> centerCustomerOperatorOrgList = new ArrayList<>();

        List<Long> orgList = new ArrayList<>();

        Set<Long> operatorIdList = new HashSet<>();

        for (OpCenterOperatorOrgParam opCenterOperatorOrgVo : param.getOpCenterOperatorOrgList()) {
            /**
             * 两种情况：是否关联所有项目 0 否 1-是
             * 一种：关联运营商-部分项目
             * 另一种：关联运营商-全部项目
             */

            //将运营商id 放到set中 去重
            operatorIdList.add(opCenterOperatorOrgVo.getId());

            //关联部分项目  --orgIdList不能传空
            if (0 == opCenterOperatorOrgVo.getIsLinkAllOrg()
                    && StringUtils.isNotBlank(opCenterOperatorOrgVo.getOrgIdList())) {
                //逐条校验-规则
                //将关联的项目id->615,1,2
                String[] orgIdList = opCenterOperatorOrgVo.getOrgIdList().split(",");
                for (String orgId : orgIdList) {
                    UnifiedCustomerOperatorOrg centerCustomerOperatorOrg = new UnifiedCustomerOperatorOrg();
                    centerCustomerOperatorOrg.setCustomerId(param.getCustomerId());
                    centerCustomerOperatorOrg.setCreateTime(new Date());
                    centerCustomerOperatorOrg.setCreateUserId(userId);
                    centerCustomerOperatorOrg.setIsAllOrg(opCenterOperatorOrgVo.getIsLinkAllOrg().byteValue());
                    centerCustomerOperatorOrg.setOperatorId(opCenterOperatorOrgVo.getId());
                    centerCustomerOperatorOrg.setOrgId(Long.parseLong(orgId));
                    centerCustomerOperatorOrgList.add(centerCustomerOperatorOrg);


                    //将所有项目放到集合中
                    orgList.add(Long.parseLong(orgId));
                }





                //关联全部项目
            } else if (1 == opCenterOperatorOrgVo.getIsLinkAllOrg()) {

                    UnifiedCustomerOperatorOrg centerCustomerOperatorOrg = new UnifiedCustomerOperatorOrg();
                    centerCustomerOperatorOrg.setCustomerId(param.getCustomerId());
                    centerCustomerOperatorOrg.setCreateTime(new Date());
                    centerCustomerOperatorOrg.setCreateUserId(userId);
                    centerCustomerOperatorOrg.setIsAllOrg((byte)1);
                    centerCustomerOperatorOrg.setOperatorId(opCenterOperatorOrgVo.getId());

                    centerCustomerOperatorOrgList.add(centerCustomerOperatorOrg);


                SysOrgQueryParam params = new SysOrgQueryParam();
                params.setBizPlatformCode(opCenterOperatorOrgVo.getBizPlatformCode());
                params.setCompId(opCenterOperatorOrgVo.getOperatorsId().toString());
                List<SysSelectVo> selectOptionOrgs = sysOrganizationService.selectOrgListByPlatform(params);
                //查询项目


                List<Long> orgs = selectOptionOrgs.stream().map(x -> x.getId()).collect(Collectors.toList());


                //将所有项目放到集合中
                orgList.addAll(orgs);



            } else {
                log.info("===关联项目参数存在问题+++++---opCenterOperatorOrgVo: {}", JSON.toJSONString(opCenterOperatorOrgVo));
                return new R<>("500", "一个项目只能关联一个同类型客户", false);
            }




        }

        //将orgList 集合去重
        orgList = orgList.stream().distinct().collect(Collectors.toList());


        log.info("orgList--{},operatorIdList--{}", JSON.toJSONString(orgList),JSON.toJSONString(operatorIdList));


        /** 排除自己
         * 一个项目只能关联一个同类型客户
         * 查询客户关联-项目 --先将根据id查询运营商管理关系
         */
        Map<String, Object> conditions = new HashMap<>();
        conditions.put("type", param.getType());
        conditions.put("orgList", orgList);
        conditions.put("operatorIdList", operatorIdList);
        conditions.put("noExcluding", param.getCustomerId());//排除自己
        conditions.put("limit", 1);
        List<OpCenterCustomerOperatorOrgVo> operatorOrgList = operationCenterCustomerService.getLinkOperatorAndOrg(conditions);
        if (CollectionUtils.isNotEmpty(operatorOrgList)) {
            //存在 一个项目 同类型--客户
            log.info("一个项目只能关联一个同类型客户+++++---result: {}", JSON.toJSONString(operatorOrgList));
            return new R<>("500", "一个项目只能关联一个同类型客户:"
                    +(operatorOrgList.get(0).getIsAllOrg()==1?
                    operatorOrgList.get(0).getOperatorName()+"；该运营商在 "+operatorOrgList.get(0).getCustomerName()+" 客户已关联全部项目，请检查"+operatorOrgList.get(0).getCustomerName()+"客户关联情况！"
                    :operatorOrgList.get(0).getOrgName()+"；该项目已被 "+operatorOrgList.get(0).getCustomerName()+" 客户关联，请选择其他项目或者取消 "+operatorOrgList.get(0).getCustomerName()+" 客户对该项目的关联！"),
                    false);
        }




        //先将之前客户数据删除
        operationCenterCustomerOperatorOrgService.deleteByCustomerId(param.getCustomerId(), userId);
        //再添加 关联关系
        operationCenterCustomerOperatorOrgService.insertBatch(centerCustomerOperatorOrgList);
        //修改 客户主体的
        entity.setIsDataPermission((byte) 1);
        entity.setUpdateUserId(userId);
        entity.setUpdateTime(new Date());
        operationCenterCustomerService.updateByPrimaryKeySelective(entity);

        return new R<>("成功");
    }

    @Override
    public R<OpCenterCustomerOperatorOrgParam> linkOperatorAndOrgByCustomerId(String customerId) throws UnifiedOrderRuntimeException {
        OpCenterCustomerOperatorOrgParam customerOperatorOrgVo = new OpCenterCustomerOperatorOrgParam();
        Map<String, Object> conditions = new HashMap<>();
        conditions.put("customerId", customerId);
        List<OpCenterCustomerOperatorOrgVo> operatorOrgList = operationCenterCustomerService.getLinkOperatorAndOrg(conditions);
        if (CollectionUtils.isEmpty(operatorOrgList)) {
            UnifiedCenterCustomer entity = operationCenterCustomerService.findById(Long.valueOf(customerId));
            OpCenterCustomerOperatorOrgParam vo = new OpCenterCustomerOperatorOrgParam();
            vo.setCustomerId(entity.getId());
            vo.setCustomerName(entity.getCustomerName());
            vo.setType((int)entity.getType());
            return new R<>(vo);
        }

        customerOperatorOrgVo.setCustomerId(operatorOrgList.get(0).getCustomerId());
        customerOperatorOrgVo.setCustomerName(operatorOrgList.get(0).getCustomerName());
        customerOperatorOrgVo.setType(operatorOrgList.get(0).getType());

        // 未关联运营商
        if (CollectionUtils.isNotEmpty(operatorOrgList)
                && null == operatorOrgList.get(0).getOperatorId()) {
            return new R<>(customerOperatorOrgVo);
        }


        List<OpCenterOperatorOrgParam> opCenterOperatorOrgList = new ArrayList<>();


        //将集合按照运营商id进行分组
        Map<Long, List<OpCenterCustomerOperatorOrgVo>> map = operatorOrgList.stream().collect(Collectors.groupingBy(x -> x.getOperatorId()));

        Long initOperatorId = null;
        for (OpCenterCustomerOperatorOrgVo vo : operatorOrgList) {
            if (initOperatorId == vo.getOperatorId()) {
                continue;
            }
            //当关联全部项目
            if (1 == vo.getIsAllOrg()) {
                OpCenterOperatorOrgParam operatorOrg = new OpCenterOperatorOrgParam();
                operatorOrg.setId(vo.getOperatorId());
                operatorOrg.setOperatorsId(vo.getBizOperatorId());
                operatorOrg.setName(vo.getOperatorName());
                operatorOrg.setBizPlatformName(vo.getBizPlatformName());
                operatorOrg.setBizPlatformCode(vo.getBizPlatformCode());
                operatorOrg.setOrgNameList("全部项目");
                operatorOrg.setIsLinkAllOrg(vo.getIsAllOrg());
                opCenterOperatorOrgList.add(operatorOrg);
                initOperatorId = vo.getOperatorId();
            }
            //当关联部分项目
            if (0 == vo.getIsAllOrg()) {
                String orgNameList = map.get(vo.getOperatorId()).stream().map(x -> x.getOrgName() != null ? x.getOrgName() : "").filter(x -> x != "").collect(Collectors.joining(","));
                String orgIdList=map.get(vo.getOperatorId()).stream().map(x -> x.getOrgId() != null ? x.getOrgId().toString() : "").filter(x -> x != "").collect(Collectors.joining(","));
                OpCenterOperatorOrgParam operatorOrg = new OpCenterOperatorOrgParam();
                operatorOrg.setId(vo.getOperatorId());
                operatorOrg.setOperatorsId(vo.getBizOperatorId());
                operatorOrg.setName(vo.getOperatorName());
                operatorOrg.setBizPlatformName(vo.getBizPlatformName());
                operatorOrg.setBizPlatformCode(vo.getBizPlatformCode());
                operatorOrg.setOrgNameList(orgNameList);
                operatorOrg.setOrgIdList(orgIdList);
                operatorOrg.setIsLinkAllOrg(vo.getIsAllOrg());

                opCenterOperatorOrgList.add(operatorOrg);
                initOperatorId = vo.getOperatorId();
            }

        }
        customerOperatorOrgVo.setOpCenterOperatorOrgList(opCenterOperatorOrgList);
        return new R<>(customerOperatorOrgVo);
    }



    @Override
    public R<List<SysSelectVo>> selectOrgList(OperationCenterParam param) {


        //根据项目
        Map<String, Object> conditions = new HashMap<>();
        conditions.put("customerId", param.getCustomerId());
        if (StringUtils.isNotBlank(param.getOperatorIds())) {
            conditions.put("operatorIds", param.getOperatorIds());
        }
        List<OpCenterCustomerOperatorOrgVo> operatorOrgList = operationCenterCustomerService.getLinkOperatorAndOrg(conditions);

        if (CollectionUtils.isEmpty(operatorOrgList)) {
            return new R<>(new ArrayList<>());
        }


        List<Long> orgIds = new ArrayList<>();
        SysOrgQueryParam paramQuery = new SysOrgQueryParam();
        //根据客户，运营商，查询项目
        //循环 查看该客户的权限-项目 判断如果 有一条关联全部项目
        for (OpCenterCustomerOperatorOrgVo vo : operatorOrgList) {
            if (vo.getIsAllOrg()==1) {
                // 全部项目--关联该运营商下的全部项目
                paramQuery.setCompId(vo.getBizOperatorId().toString());
                paramQuery.setBizPlatformCode(vo.getBizPlatformCode());
                List<SysSelectVo> sysOrgIdList = sysOrganizationService.selectOrgListByPlatform(paramQuery);
                orgIds.addAll(sysOrgIdList.stream().map(x -> x.getId()).collect(Collectors.toList()));

            }else {//部分项目

                orgIds.add(vo.getOrgId());
            }
        }

        if (CollectionUtils.isNotEmpty(orgIds)) {
            conditions.put("orgIds", orgIds);
            return new R<>(sysOrganizationService.selectOrgList(conditions));
        }

        return new R<>(new ArrayList<>());
    }


}
