package com.sckw.manage.service;

import java.io.IOException;
import java.util.Date;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sckw.core.exception.SystemException;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.enums.CooperateStatusEnum;
import com.sckw.core.model.enums.SystemTypeEnum;
import com.sckw.core.model.page.PageHelperUtil;
import com.sckw.core.model.page.PageResult;
import com.sckw.core.utils.BeanUtils;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.StringUtils;
import com.sckw.core.web.constant.HttpStatus;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.excel.utils.EasyExcelUtil;
import com.sckw.manage.dao.KwmCooperateMapper;
import com.sckw.manage.dao.KwmCooperateTypeMapper;
import com.sckw.manage.model.dto.req.CooperateManageQueryReqDto;
import com.sckw.manage.model.dto.res.CooperateManageQueryResDto;
import com.sckw.manage.model.entity.KwmCooperate;
import com.sckw.manage.model.entity.KwmCooperateType;
import com.sckw.manage.model.vo.req.BindManagerReqVo;
import com.sckw.manage.model.vo.req.CooperateManageQueryReqVo;
import com.sckw.manage.model.vo.req.FindCooperateByEntReqVo;
import com.sckw.manage.model.vo.req.FindEntCooperateReqVo;
import com.sckw.manage.model.vo.res.*;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.EntCacheResDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @author czh
 * @desc 合作管理service
 * @date 2023/7/10
 */
@Slf4j
@Service
public class KwmCooperateManageService {

    @Autowired
    private KwmCooperateMapper kwmCooperateMapper;

    @Autowired
    private KwmCooperateTypeMapper kwmCooperateTypeMapper;

    @Autowired
    private CommonBusinessService commonBusinessService;

    @DubboReference(version = "2.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;


    /**
     * @param reqVo 分页入参
     * @return PageResult
     * @desc: 查询合作企业列表
     * @author: czh
     * @date: 2023/7/10
     */
    public PageResult queryByPage(CooperateManageQueryReqVo reqVo) {
        PageHelper.startPage(reqVo.getPage(), reqVo.getPageSize());
        List<CooperateManageQueryResVo> list = findList(buildQueryParam(reqVo));
        return PageHelperUtil.getPageResult(new PageInfo<>(list));
    }


    private List<CooperateManageQueryResVo> findList(CooperateManageQueryReqDto reqDto) {
        List<CooperateManageQueryResDto> list = kwmCooperateMapper.findManageList(reqDto);
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }

        return commonBusinessService.getCooperateManageQueryResVos(reqDto, list);
    }

    /**
     * @param reqVo 查询入参
     * @return CooperateManageQueryReqDto
     * @desc: 构建查全量入参
     * @author: czh
     * @date: 2023/7/11
     */
    private CooperateManageQueryReqDto buildQueryParam(CooperateManageQueryReqVo reqVo) {
        CooperateManageQueryReqDto cooperateManageQueryReqDto = new CooperateManageQueryReqDto();
        BeanUtils.copyProperties(reqVo, cooperateManageQueryReqDto);
        String cooperateTypes = reqVo.getCooperateTypes();
        if (StringUtils.isNotBlank(cooperateTypes)) {
            cooperateManageQueryReqDto.setCooperateTypes(Arrays.asList(cooperateTypes.split(Global.COMMA)));
        }


        //只允许查出申请中、已拒绝、已撤销的记录
        List<Integer> status = new ArrayList<>();
        if (Objects.isNull(reqVo.getStatus())) {
            status.add(CooperateStatusEnum.OK.getCode());
            status.add(CooperateStatusEnum.PASS.getCode());
        }

        if (Objects.nonNull(reqVo.getStatus()) && reqVo.getStatus().equals(CooperateStatusEnum.OK.getCode())) {
            status.add(CooperateStatusEnum.OK.getCode());
        }
        if (Objects.nonNull(reqVo.getStatus()) && reqVo.getStatus().equals(CooperateStatusEnum.PASS.getCode())) {
            status.add(CooperateStatusEnum.PASS.getCode());
        }
        cooperateManageQueryReqDto.setStatus(status);

        List<Long> ids = reqVo.getIds();
        if (!CollectionUtils.isEmpty(ids)) {
            cooperateManageQueryReqDto.setIds(ids);
        }


        Long entId = LoginUserHolder.getEntId();
        cooperateManageQueryReqDto.setCurrentEntId(entId);
        List<Long> currentEntIdList = new ArrayList<>();
        currentEntIdList.add(entId);
        Map<Long, List<EntCacheResDto>> longListMap = remoteSystemService.queryEntDeptCacheByIds(Collections.singletonList(entId));
        if (!longListMap.isEmpty()) {
            List<EntCacheResDto> entCacheResDtos = longListMap.get(entId);
            if (CollectionUtils.isNotEmpty(entCacheResDtos)) {
                currentEntIdList.addAll(entCacheResDtos.stream().map(EntCacheResDto::getId).toList());
            }
        }
        cooperateManageQueryReqDto.setCurrentEntIdList(currentEntIdList);

        return cooperateManageQueryReqDto;
    }


    /**
     * @param entId 企业id
     * @return QueryDetailResVo
     * @desc: 查询详情
     * @author: czh
     * @date: 2023/7/10
     */
    public QueryDetailResVo queryDetail(Long entId) {
        EntCacheResDto entCacheResDto = remoteSystemService.queryEntCacheById(entId);
        if (Objects.isNull(entCacheResDto)) {
            return null;
        }
        QueryDetailResVo queryDetailResVo = new QueryDetailResVo();
        BeanUtils.copyProperties(entCacheResDto, queryDetailResVo);
        return queryDetailResVo;
    }

    /**
     * @param reqVo 用户id
     * @desc: 设置客户经理
     * @author: czh
     * @date: 2023/7/10
     */
    public void bindManager(BindManagerReqVo reqVo) throws SystemException {
        commonBusinessService.bingManager(reqVo.getUserId(), reqVo.getId());
    }

    /**
     * @param ids 主键id
     * @desc: 解除合同
     * @author: czh
     * @date: 2023/7/11
     */
    @Transactional(rollbackFor = {})
    public void dissolve(String ids, Integer type) {
        //todo 判断是否可以解除（若和所选企业有未完结的业务单据（销售订单/采购订单、托运订单/承运订单、对账单、结算单），不支持解除合作）
        //提示：您与所选企业存在未完结业务，当前无法删除！
        List<KwmCooperate> kwmCooperates = kwmCooperateMapper.selectBatchIds(Arrays.asList(ids.split(Global.COMMA)));
        if (CollectionUtils.isEmpty(kwmCooperates)) {
            throw new SystemException(HttpStatus.QUERY_FAIL_CODE, HttpStatus.COOPERATE_NOT_EXISTS);
        }
        Long userId = LoginUserHolder.getUserId();
        Date date = new Date();
        kwmCooperates.forEach(item -> {
            //运营端可以操作任意状态，企业端只能操作合作中的数据
            if (SystemTypeEnum.MANAGE.getCode().equals(LoginUserHolder.getSystemType())) {
                if (!item.getStatus().equals(CooperateStatusEnum.OK.getCode()) && type.equals(CooperateStatusEnum.PASS.getCode())) {
                    throw new SystemException(HttpStatus.CRUD_FAIL_CODE, HttpStatus.MSG_012);
                }

                if (!item.getStatus().equals(CooperateStatusEnum.PASS.getCode()) && type.equals(CooperateStatusEnum.OK.getCode())) {
                    throw new SystemException(HttpStatus.CRUD_FAIL_CODE, HttpStatus.MSG_012);
                }
            }

            item.setStatus(type);
            item.setUpdateBy(userId);
            item.setUpdateTime(date);
            if (kwmCooperateMapper.updateById(item) <= 0) {
                throw new SystemException(HttpStatus.CRUD_FAIL_CODE, HttpStatus.UPDATE_FAIL);
            }
        });

    }

    /**
     * @param status 操作状态
     * @return boolean
     * @desc: 校验用户操作状态
     * @author: czh
     * @date: 2023/7/11
     */
    private boolean checkUserPermission(int status) {
        return status != CooperateStatusEnum.OK.getCode() && !LoginUserHolder.getSystemType().equals(SystemTypeEnum.MANAGE.getCode());
    }

    /**
     * @param ids 主键
     * @desc: 删除合同
     * @author: czh
     * @date: 2023/7/11
     */
    public void delete(String ids) {
        List<KwmCooperate> kwmCooperates = kwmCooperateMapper.selectBatchIds(Arrays.asList(ids.split(Global.COMMA)));
        Long userId = LoginUserHolder.getUserId();
        Date date = new Date();
        kwmCooperates.forEach(item -> {
            //运营端可以操作任意状态，企业端只能操作合作中的数据
            if (item.getStatus() != CooperateStatusEnum.PASS.getCode()) {
                throw new SystemException(HttpStatus.CRUD_FAIL_CODE, HttpStatus.MSG_013);
            }

            item.setDelFlag(Global.YES);
            item.setUpdateBy(userId);
            item.setUpdateTime(date);
            if (kwmCooperateMapper.updateById(item) <= 0) {
                throw new SystemException(HttpStatus.CRUD_FAIL_CODE, HttpStatus.UPDATE_FAIL);
            }
        });
    }

    /**
     * @param reqVo 查询入参
     * @desc: 导出
     * @author: czh
     * @date: 2023/7/11
     */
    public void export(CooperateManageQueryReqVo reqVo) throws SystemException {
        List<CooperateManageQueryResVo> list = commonBusinessService.findList(buildQueryParam(reqVo));
        try {
            EasyExcelUtil.writeSingleExcel("合作管理.xlsx", "sheet1", list, CooperateManageQueryResVo.class);
        } catch (IOException e) {
            log.error("导出失败:", e);
            throw new SystemException(HttpStatus.CODE_10301, HttpStatus.MSG_014);
        }
    }

    /**
     * @param reqVo 查询入参
     * @return HttpResult
     * @desc: 分组查询
     * @author: czh
     * @date: 2023/7/17
     */
    public List<FindListGroupResVo> findListGroup(CooperateManageQueryReqVo reqVo) {
        //初始化分组返参
        List<FindListGroupResVo> result = commonBusinessService.init();
        List<CooperateManageQueryResVo> list = findList(buildQueryParam(reqVo));
        if (CollectionUtils.isEmpty(list)) {
            return result;
        }

        //填充分组数据
        commonBusinessService.fillGroup(result, list);
        return result;
    }


    /**
     * @param reqVo 企业id
     * @return FindEntCooperateResVo
     * @desc: 查询企业的合作单位
     * @author: czh
     * @date: 2023/7/22
     */
    public List<FindEntCooperateResVo> findEntCooperate(FindEntCooperateReqVo reqVo) {
        Long id = reqVo.getId();
        Integer cooperateType = reqVo.getCooperateType();
        LambdaQueryWrapper<KwmCooperate> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(KwmCooperate::getDelFlag, Global.NO).
                eq(KwmCooperate::getStatus, CooperateStatusEnum.OK.getCode()).and(
                        wq -> wq.eq(KwmCooperate::getInviterEntId, id).or().
                                 eq(KwmCooperate::getInviteeEntId, id)
                );
        List<KwmCooperate> kwmCooperates = kwmCooperateMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(kwmCooperates)) {
            return null;
        }

        LambdaQueryWrapper<KwmCooperateType> kwmCooperateTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        kwmCooperateTypeLambdaQueryWrapper.in(KwmCooperateType::getCooperateId, kwmCooperates.stream().map(KwmCooperate::getId).toList());
        kwmCooperateTypeLambdaQueryWrapper.eq(KwmCooperateType::getDelFlag, Global.NO);
        kwmCooperateTypeLambdaQueryWrapper.eq(KwmCooperateType::getStatus, CooperateStatusEnum.OK.getCode());
        kwmCooperateTypeLambdaQueryWrapper.eq(KwmCooperateType::getType, cooperateType);
        List<KwmCooperateType> kwmCooperateTypes = kwmCooperateTypeMapper.selectList(kwmCooperateTypeLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(kwmCooperateTypes)) {
            return null;
        }

        //装对方企业的id
        List<Long> kwmCooperateIdList = kwmCooperateTypes.stream().map(KwmCooperateType::getCooperateId).toList();
        kwmCooperates = kwmCooperates.stream().filter(item -> kwmCooperateIdList.contains(item.getId())).toList();
        if (CollectionUtils.isEmpty(kwmCooperates)) {
            return null;
        }

        List<Long> targetEntIdList = new ArrayList<>();
        kwmCooperates.forEach(item -> {
            targetEntIdList.add(item.getInviterEntId().equals(id) ? item.getInviteeEntId() : item.getInviterEntId());
        });

        Map<Long, EntCacheResDto> entCacheResDtoMap = remoteSystemService.queryEntCacheMapByIds(targetEntIdList);
        if (Objects.isNull(entCacheResDtoMap)) {
            return null;
        }

        //装对方企业信息
        List<FindEntCooperateResVo> targetEntList = new ArrayList<>();
        kwmCooperates.forEach(item -> {
            FindEntCooperateResVo findEntCooperateResVo = new FindEntCooperateResVo();
            Long entId = item.getInviterEntId().equals(id) ? item.getInviteeEntId() : item.getInviterEntId();
            EntCacheResDto entCacheResDto = entCacheResDtoMap.get(entId);
            if (Objects.isNull(entCacheResDto)) {
                return;
            }
            findEntCooperateResVo.setEntId(entId);
            findEntCooperateResVo.setEntName(entCacheResDto.getFirmName());
            findEntCooperateResVo.setContactsId(item.getInviterEntId().equals(id) ? item.getInviteeContactsId() : item.getInviterContactsId());
            findEntCooperateResVo.setContacts(item.getInviterEntId().equals(id) ? item.getInviteeContacts() : item.getInviterContacts());
            findEntCooperateResVo.setPhone(item.getInviterEntId().equals(id) ? item.getInviteePhone() : item.getInviterPhone());
            targetEntList.add(findEntCooperateResVo);
        });

        //装对方企业的主体单位
//        Map<Long, List<EntCacheResDto>> longListMap = remoteSystemService.queryEntDeptCacheByIds(targetEntIdList);
//        List<Long> longs = targetEntList.stream().map(FindEntCooperateResVo::getEntId).toList();
//        longs.forEach(item -> {
//            List<EntCacheResDto> entCacheResDtos1 = longListMap.get(item);
//            if (CollectionUtils.isEmpty(entCacheResDtos1)) {
//                return;
//            }
//            entCacheResDtos1.forEach(x -> {
//                FindEntCooperateResVo findEntCooperateResVo = new FindEntCooperateResVo();
//                findEntCooperateResVo.setEntId(x.getId());
//                findEntCooperateResVo.setEntName(x.getFirmName());
//                targetEntList.add(findEntCooperateResVo);
//            });
//        });
        return targetEntList;
    }


    /**
     * @param reqVo 企业id
     * @return FindCooperateByEntResVo
     * @desc: 根据企业查合作信息
     * @author: czh
     * @date: 2023/8/1
     */
    public List<FindCooperateByEntResVo> findCooperateByEnt(FindCooperateByEntReqVo reqVo) {
        List<KwmCooperate> kwmCooperates = kwmCooperateMapper.findCooperateByEnt(reqVo);
        if (CollectionUtils.isEmpty(kwmCooperates)) {
            return Collections.emptyList();
        }

        //获取合作属性
        List<Long> cooperateIdList = kwmCooperates.stream().map(KwmCooperate::getId).toList();
        LambdaQueryWrapper<KwmCooperateType> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(KwmCooperateType::getCooperateId, cooperateIdList);
        wrapper.eq(KwmCooperateType::getDelFlag, Global.NO);
        List<KwmCooperateType> kwmCooperateTypes = kwmCooperateTypeMapper.selectList(wrapper);
        Map<Long, List<KwmCooperateType>> collect = new HashMap<>();
        if (CollectionUtils.isNotEmpty(kwmCooperateTypes)) {
            collect = kwmCooperateTypes.stream().collect(Collectors.groupingBy(KwmCooperateType::getCooperateId));
        }

        //获取所有企业信息
        List<Long> allEntIdList = new ArrayList<>();
        kwmCooperates.forEach(item -> {
            allEntIdList.add(item.getEntId());
            allEntIdList.add(item.getInviterEntId());
            allEntIdList.add(item.getInviteeEntId());
        });
        List<EntCacheResDto> entCacheResDtos = remoteSystemService.queryEntCacheByIds(allEntIdList);
        Map<Long, EntCacheResDto> entMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(entCacheResDtos)) {
            entMap = entCacheResDtos.stream().collect(Collectors.toMap(EntCacheResDto::getId, e -> e, (n, o) -> n));
        }

        List<FindCooperateByEntResVo> list = new ArrayList<>();
        Long currentEntId = LoginUserHolder.getEntId();
        for (KwmCooperate kwmCooperate : kwmCooperates) {
            FindCooperateByEntResVo findCooperateByEntResVo = new FindCooperateByEntResVo();
            findCooperateByEntResVo.setId(kwmCooperate.getId());


            //设置合作属性
            List<KwmCooperateType> kwmCooperateTypes1 = collect.get(kwmCooperate.getId());
            if (CollectionUtils.isNotEmpty(kwmCooperateTypes1)) {
                findCooperateByEntResVo.setCooperateTypes(String.join(Global.COMMA, kwmCooperateTypes1.stream().map(KwmCooperateType::getType).map(String::valueOf).toList()));
            }

            //设置发起企业
            EntCacheResDto entCacheResDto = entMap.get(kwmCooperate.getEntId());
            findCooperateByEntResVo.setInitiateEntId(kwmCooperate.getEntId());
            if (Objects.nonNull(entCacheResDto)) {
                findCooperateByEntResVo.setInitiateEntName(entCacheResDto.getFirmName());
            }

            EntCacheResDto inviterEntCacheResDto = entMap.get(kwmCooperate.getInviterEntId());
            EntCacheResDto inviteeEntCacheResDto = entMap.get(kwmCooperate.getInviteeEntId());
            String inviterEntName = Objects.isNull(inviterEntCacheResDto) ? null : inviterEntCacheResDto.getFirmName();
            String inviteeEntName = Objects.isNull(inviteeEntCacheResDto) ? null : inviteeEntCacheResDto.getFirmName();

            //设置我方和对方企业信息、联系人
            if (currentEntId.equals(kwmCooperate.getEntId())) {
                findCooperateByEntResVo.setEntId(kwmCooperate.getInviterEntId());
                findCooperateByEntResVo.setEntName(inviterEntName);
                findCooperateByEntResVo.setContactsId(kwmCooperate.getInviterContactsId());
                findCooperateByEntResVo.setContacts(kwmCooperate.getInviterContacts());
                findCooperateByEntResVo.setPhone(kwmCooperate.getInviterPhone());
                findCooperateByEntResVo.setTargetEntId(kwmCooperate.getInviteeEntId());
                findCooperateByEntResVo.setTargetEntName(inviteeEntName);
                findCooperateByEntResVo.setTargetContactsId(kwmCooperate.getInviteeContactsId());
                findCooperateByEntResVo.setTargetContacts(kwmCooperate.getInviteeContacts());
                findCooperateByEntResVo.setTargetPhone(kwmCooperate.getInviteePhone());
            } else {
                findCooperateByEntResVo.setEntId(kwmCooperate.getInviteeEntId());
                findCooperateByEntResVo.setEntName(inviteeEntName);
                findCooperateByEntResVo.setContactsId(kwmCooperate.getInviteeContactsId());
                findCooperateByEntResVo.setContacts(kwmCooperate.getInviteeContacts());
                findCooperateByEntResVo.setPhone(kwmCooperate.getInviteePhone());
                findCooperateByEntResVo.setTargetEntId(kwmCooperate.getInviterEntId());
                findCooperateByEntResVo.setTargetEntName(inviterEntName);
                findCooperateByEntResVo.setTargetContactsId(kwmCooperate.getInviterContactsId());
                findCooperateByEntResVo.setTargetContacts(kwmCooperate.getInviterContacts());
                findCooperateByEntResVo.setTargetPhone(kwmCooperate.getInviterPhone());
            }
            list.add(findCooperateByEntResVo);
        }
        return list;
    }

    public void restore(String ids, Integer type) {
        dissolve(ids, type);
    }
}
