package com.dsk.cscec.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.common.exception.ServiceException;
import com.dsk.common.utils.StringUtils;
import com.dsk.cscec.domain.AdvisoryBody;
import com.dsk.cscec.domain.AdvisoryBodyProject;
import com.dsk.cscec.domain.bo.EditAdvisoryBodyInfoBo;
import com.dsk.cscec.domain.bo.AdvisoryBodySearchBo;
import com.dsk.cscec.domain.vo.AdvisoryBodyExistVo;
import com.dsk.cscec.domain.vo.AdvisoryBodySearchVo;
import com.dsk.cscec.mapper.AdvisoryBodyMapper;
import com.dsk.cscec.mapper.AdvisoryBodyProjectMapper;
import com.dsk.cscec.service.AdvisoryBodyService;
import com.dsk.jsk.domain.EnterpriseInfoHeaderBody;
import com.dsk.system.utils.DskOpenApiUtil;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 咨询机构(SysAdvisoryBody)表服务实现类
 *
 * @author sxk
 * @since 2023-12-12 10:12:09
 */
@Service("advisoryBodyService")
public class AdvisoryBodyServiceImpl extends ServiceImpl<AdvisoryBodyMapper, AdvisoryBody> implements AdvisoryBodyService {
    @Resource
    private AdvisoryBodyMapper baseMapper;
    @Resource
    private DskOpenApiUtil dskOpenApiUtil;
    @Resource
    private AdvisoryBodyProjectMapper advisoryBodyProjectMapper;

    /**
     * 获取所有企业列表(咨询机构)数据
     *
     * @param advisoryBodySearchBo 查询实体
     * @param pageQuery            分页对象
     * @return 所有数据
     */
    @Override
    public TableDataInfo<AdvisoryBodySearchVo> queryAdvisoryBodyList(AdvisoryBodySearchBo advisoryBodySearchBo, PageQuery pageQuery) {
        //先按照分页要求从咨询机构表中查出分页数据
        QueryWrapper<AdvisoryBody> wrapper = Wrappers.query();
        wrapper.like(StringUtils.isNotBlank(advisoryBodySearchBo.getAdvisoryBodyName()), "advisory_body_name", advisoryBodySearchBo.getAdvisoryBodyName())
                .like(StringUtils.isNotBlank(advisoryBodySearchBo.getBusinessScope()), "business_scope", advisoryBodySearchBo.getBusinessScope());
        Page<AdvisoryBodySearchVo> page = baseMapper.selectPageAdvisoryBodyList(pageQuery.build(), wrapper);

        Date minLastCooperateDate = advisoryBodySearchBo.getMinLastCooperateDate();
        Date maxLastCooperateDate = advisoryBodySearchBo.getMaxLastCooperateDate();

        //根据咨询机构cid查询对应的企业信息
        List<AdvisoryBodySearchVo> advisoryBodySearchVoList = page.getRecords();

        Iterator<AdvisoryBodySearchVo> iterator = advisoryBodySearchVoList.iterator();
        while (iterator.hasNext()) {
            AdvisoryBodySearchVo advisoryBodySearchVo = iterator.next();
            EnterpriseInfoHeaderBody infoHeaderBody = new EnterpriseInfoHeaderBody();
            //有Cid的才去建设库查数据
            if (ObjectUtil.isNotNull(advisoryBodySearchVo.getAdvisoryBodyCid())) {
                infoHeaderBody.setCompanyId(Math.toIntExact(advisoryBodySearchVo.getAdvisoryBodyCid()));
            } else {
                continue;
            }
            Map<String, Object> companyMap = dskOpenApiUtil.requestBody("/api/jsk/enterprise/infoHeader", BeanUtil.beanToMap(infoHeaderBody, false, false));
            Map companyData = MapUtils.getMap(companyMap, "data", null);

            //填充查询最近一次合作时间与信息记录人
            List<AdvisoryBodyProject> advisoryBodyProjectList = advisoryBodyProjectMapper.selectList(new LambdaQueryWrapper<AdvisoryBodyProject>()
                    .select(AdvisoryBodyProject::getCreateTime, AdvisoryBodyProject::getCreateBy)
                    .eq(AdvisoryBodyProject::getAdvisoryBodyCid, advisoryBodySearchVo.getAdvisoryBodyCid())
                    .orderByDesc(AdvisoryBodyProject::getCreateTime));
            Date lastCooperateDate = null;
            if (ObjectUtil.isNotNull(advisoryBodyProjectList) && !advisoryBodyProjectList.isEmpty()) {
                //暂时取记录生成作为最近一次合作时间
                //TODO:AdvisoryBodyProject表中保留了cooperate_time字段,应当取该字段作为最近一次合作时间,但产品并未给存入这个字段的需求
                lastCooperateDate = advisoryBodyProjectList.get(0).getCreateTime();
                advisoryBodySearchVo.setLastCooperateTime(lastCooperateDate);
                advisoryBodySearchVo.setInfoRecorder(advisoryBodyProjectList.get(0).getCreateBy());
            }

            //筛选最近一次合作时间
            if (ObjectUtil.isNotNull(lastCooperateDate)
                    && ObjectUtil.isNotNull(minLastCooperateDate)
                    && ObjectUtil.isNotNull(maxLastCooperateDate)) {
                if (DateUtil.isExpired(minLastCooperateDate, maxLastCooperateDate, lastCooperateDate)) {
                    iterator.remove();
                    continue;
                }
            }

            //经营范围
            advisoryBodySearchVo.setBusinessStatus(MapUtils.getString(companyData, "businessStatus", ""));
            //法人
            advisoryBodySearchVo.setCorporatePerson(MapUtils.getString(companyData, "corporatePerson", ""));
            //注册资本
            advisoryBodySearchVo.setRegCapital(MapUtils.getString(companyData, "regCapital", ""));
            //拼接地区
            String provinceName = MapUtils.getString(companyData, "provinceName", "");
            String cityName = MapUtils.getString(companyData, "cityName", "");
            String districtName = MapUtils.getString(companyData, "districtName", "");
            advisoryBodySearchVo.setRegArea(provinceName + "-" + cityName + "-" + districtName);
            //成立日期
            advisoryBodySearchVo.setRegisteredDate(MapUtils.getString(companyData, "registeredDate", ""));
            //经营范围
            advisoryBodySearchVo.setBusinessScope(MapUtils.getString(companyData, "businessScope", ""));
            //合作项目数量
            advisoryBodySearchVo.setCooperateProjectCount(advisoryBodyProjectMapper.selectCount(new LambdaQueryWrapper<AdvisoryBodyProject>()
                    .eq(AdvisoryBodyProject::getAdvisoryBodyCid, advisoryBodySearchVo.getAdvisoryBodyCid())));
        }

        return TableDataInfo.build(page);
    }

    /**
     * 校验咨询机构是否存在
     *
     * @param advisoryBodyName 咨询机构名称
     * @return 校验结果
     */
    @Override
    public AdvisoryBodyExistVo checkAdvisoryBodyExist(String advisoryBodyName) {
        //先从咨询机构表查询是否存在,存在则直接返回
        AdvisoryBody advisoryBody = baseMapper.selectOne(new LambdaQueryWrapper<AdvisoryBody>()
                .eq(AdvisoryBody::getAdvisoryBodyName, advisoryBodyName));
        if (ObjectUtil.isNotNull(advisoryBody)) {
            //咨询机构表中有记录,则设置为非新咨询机构
            AdvisoryBodyExistVo advisoryBodyExistVo = BeanUtil.toBean(advisoryBody, AdvisoryBodyExistVo.class);
            //是否为新资讯机构
            advisoryBodyExistVo.setIsNewAdvisoryBody(false);
            return advisoryBodyExistVo;
        } else {
            Map<String, Object> params = new HashMap<>();
            params.put("keyword", advisoryBodyName);
            Map jskData = MapUtils.getMap(dskOpenApiUtil.requestBody("/nationzj/enterprice/index", params), "data", null);
            //防止没有数据而导致强转错误,所以先判断下total
            if (MapUtils.getInteger(jskData, "total", 0) > 0) {
                List<Map<String, Object>> data = (List<Map<String, Object>>) jskData.get("list");
                for (Map<String, Object> companyData : data) {
                    //企业名称完全匹配上,则直接返回给前端
                    String companyName = StringUtils.removeRed(MapUtils.getString(companyData, "name", "NotExist"));
                    if (advisoryBodyName.equals(companyName)) {
                        AdvisoryBodyExistVo advisoryBodyExistVo = new AdvisoryBodyExistVo();
                        //jskEid就是cid
                        Long jskEid = MapUtils.getLong(companyData, "jskEid");
                        advisoryBodyExistVo.setAdvisoryBodyCid(Math.toIntExact(jskEid));
                        //企业名称
                        advisoryBodyExistVo.setAdvisoryBodyName(companyName);
                        //统一社会信用代码
                        advisoryBodyExistVo.setCreditCode(MapUtils.getString(companyData, "creditCode"));
                        //法人信息
                        advisoryBodyExistVo.setLegalPerson(MapUtils.getString(companyData, "legalPerson"));
                        //经营范围
                        advisoryBodyExistVo.setBusinessScope(MapUtils.getString(companyData, "businessScope"));

                        EnterpriseInfoHeaderBody infoHeaderBody = new EnterpriseInfoHeaderBody();
                        infoHeaderBody.setCompanyId(Math.toIntExact(jskEid));
                        Map<String, Object> companyMap = dskOpenApiUtil.requestBody("/api/jsk/enterprise/infoHeader", BeanUtil.beanToMap(infoHeaderBody, false, false));
                        Map companyData1 = MapUtils.getMap(companyMap, "data", null);
                        if (ObjectUtil.isNotNull(companyData1)) {
                            //登记状态
                            advisoryBodyExistVo.setBusinessStatus(MapUtils.getString(companyData1, "businessStatus", ""));
                            //成立日期
                            advisoryBodyExistVo.setRegDate(DateUtil.parse(MapUtils.getString(companyData1, "registeredDate", ""),"yyyy-MM-dd"));
                            //注册地址
                            advisoryBodyExistVo.setRegAddress(MapUtils.getString(companyData1, "addressDetail", ""));
                            //注册资本
                            advisoryBodyExistVo.setRegCapital(MapUtils.getString(companyData1, "regCapital", ""));
                            //是否为新资讯机构
                            advisoryBodyExistVo.setIsNewAdvisoryBody(true);
                        }
                        return advisoryBodyExistVo;
                    }
                }
                //查不到则抛异常
                throw new ServiceException("咨询机构不存在或结果不唯一,请输入完整咨询机构企业名称");
            }
            throw new ServiceException("咨询机构不存在");
        }
    }

    /**
     * 编辑咨询机构结算信息
     * 包含:
     * 新增咨询机构(advisory_body表)
     * 新增/更新咨询机构与项目关联信息(advisory_body_project表)
     *
     * @param editInfoBo 编辑信息
     * @return 编辑结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer editAdvisoryBody(EditAdvisoryBodyInfoBo editInfoBo) {
        long advisoryBodyId = IdUtil.getSnowflakeNextId();
        //如果是新增咨询机构,则新增记录到咨询机构表
        if (editInfoBo.getIsNewAdvisoryBody()) {
            AdvisoryBody newAdvisoryBody = BeanUtil.toBean(editInfoBo, AdvisoryBody.class);
            newAdvisoryBody.setAdvisoryBodyId(advisoryBodyId);
            //考虑到咨询机构经营范围是列表中的一个查询条件,因此需要单独存入表中
            //但考虑到经营范围又来自建设库,进而衍生出数据一致性问题,因此在项目中做了定时任务同步数据
            //故无需担心数据一致性问题
            baseMapper.insert(newAdvisoryBody);

            //校验咨询机构与项目关联表中是否有记录,无则新增,有则修改
            return checkAdvisoryBodyProjectInfoAndEdit(editInfoBo, advisoryBodyId);
        } else {
            //如果不是新增咨询机构,则校验咨询机构与项目关联表中是否有记录,无则新增,有则修改
            return checkAdvisoryBodyProjectInfoAndEdit(editInfoBo, advisoryBodyId);
        }
    }

    /**
     * 校验咨询机构与项目关联表中是否有记录,无则新增,有则修改
     */
    private Integer checkAdvisoryBodyProjectInfoAndEdit(EditAdvisoryBodyInfoBo editInfoBo, Long advisoryBodyId) {
        AdvisoryBodyProject advisoryBodyProject = advisoryBodyProjectMapper.selectById(editInfoBo.getProjectKey());
        if (ObjectUtil.isNotNull(advisoryBodyProject)) {
            //修改咨询机构与项目关联信息
            AdvisoryBodyProject updateAdvisoryBodyProject = BeanUtil.toBean(editInfoBo, AdvisoryBodyProject.class);
            updateAdvisoryBodyProject.setProjectKey(editInfoBo.getProjectKey());
            if (editInfoBo.getIsNewAdvisoryBody()) {
                //新增的咨询机构不会咨询机构ID,需要到咨询机构表中查询
                AdvisoryBody advisoryBody = baseMapper.selectOne(new LambdaQueryWrapper<AdvisoryBody>()
                        .eq(AdvisoryBody::getAdvisoryBodyCid, editInfoBo.getAdvisoryBodyCid()));
                updateAdvisoryBodyProject.setAdvisoryBodyId(advisoryBody.getAdvisoryBodyId());
            } else {
                updateAdvisoryBodyProject.setAdvisoryBodyId(advisoryBodyProject.getAdvisoryBodyId());
            }
            return advisoryBodyProjectMapper.updateById(updateAdvisoryBodyProject);
        } else {
            //新增咨询机构与项目关联信息
            AdvisoryBodyProject addAdvisoryBodyProject = BeanUtil.toBean(editInfoBo, AdvisoryBodyProject.class);
            addAdvisoryBodyProject.setAdvisoryBodyId(advisoryBodyId);
            return advisoryBodyProjectMapper.insert(addAdvisoryBodyProject);
        }
    }

    /**
     * 每小时更新一次咨询机构经营范围
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAdvisoryBodyBusinessScope() {
        EnterpriseInfoHeaderBody infoHeaderBody = new EnterpriseInfoHeaderBody();
        for (AdvisoryBody advisoryBody : baseMapper.selectList(null)) {
            infoHeaderBody.setCompanyId(Math.toIntExact(advisoryBody.getAdvisoryBodyCid()));
            Map<String, Object> companyMap = dskOpenApiUtil.requestBody("/api/jsk/enterprise/infoHeader", BeanUtil.beanToMap(infoHeaderBody, false, false));
            Map companyData = MapUtils.getMap(companyMap, "data", null);
            String businessScope = MapUtils.getString(companyData, "businessScope", "empty");
            if (!"empty".equals(businessScope)) {
                advisoryBody.setBusinessScope(businessScope);
                baseMapper.updateById(advisoryBody);
            }
        }
    }
}

