package com.dsk.cscec.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
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.utils.StringUtils;
import com.dsk.cscec.constant.QueryConstants;
import com.dsk.cscec.domain.AdvisoryBody;
import com.dsk.cscec.domain.AdvisoryBodyProject;
import com.dsk.cscec.domain.DProject;
import com.dsk.cscec.domain.bo.CooperateProjectDetailSearchBo;
import com.dsk.cscec.domain.bo.ProjectDetailBo;
import com.dsk.cscec.domain.bo.ProjectSearchBo;
import com.dsk.cscec.domain.vo.CooperateProjectDetailSearchVo;
import com.dsk.cscec.domain.vo.ProjectDetailVo;
import com.dsk.cscec.domain.vo.ProjectSearchVo;
import com.dsk.cscec.mapper.AdvisoryBodyMapper;
import com.dsk.cscec.mapper.AdvisoryBodyProjectMapper;
import com.dsk.cscec.mapper.DProjectMapper;
import com.dsk.cscec.service.IDProjectService;
import com.dsk.jsk.domain.EnterpriseInfoHeaderBody;
import com.dsk.system.utils.DskOpenApiUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 咨询机构管理
 *
 * @author sxk
 * @since 2023-12-10 15:34:51
 */
@Slf4j
@Service("dProjectService")
public class IDProjectServiceImpl extends ServiceImpl<DProjectMapper, DProject> implements IDProjectService {
    @Resource
    private DProjectMapper baseMapper;
    @Resource
    private AdvisoryBodyMapper advisoryBodyMapper;
    @Resource
    private AdvisoryBodyProjectMapper advisoryBodyProjectMapper;
    @Resource
    private DskOpenApiUtil dskOpenApiUtil;

    /**
     * 获取所有项目列表数据
     *
     * @param projectSearchBo 查询实体
     * @param pageQuery       分页对象
     * @return 所有数据
     */
    @Override
    public TableDataInfo<ProjectSearchVo> queryProjectList(ProjectSearchBo projectSearchBo, PageQuery pageQuery) {
        String advisoryBodyName = projectSearchBo.getAdvisoryBodyName();
        List<Long> projectKeys = null;
        if (StringUtils.isNotBlank(advisoryBodyName)) {
            //根据咨询机构名称查询咨询机构Cids
            List<Long> advisoryBodyCids = advisoryBodyMapper.selectAdvisoryBodyCidsByName(advisoryBodyName);
            //根据咨询机构Cids查询项目Keys
            List<Long> projectKeys1 = advisoryBodyProjectMapper.selectProjectKeysByAdvisoryBodyCids(advisoryBodyCids);
            if (projectKeys1.isEmpty()) {
                return TableDataInfo.build();
            }
            projectKeys = projectKeys1;
        }

        Page<ProjectSearchVo> page = baseMapper.selectPageProjectList(pageQuery.build(), this.buildProjectQueryWrapper(projectSearchBo, projectKeys));

        for (ProjectSearchVo projectSearchVo : page.getRecords()) {
            //补充咨询机构信息
            projectSearchVo.setAdvisoryBody(this.getAdvisoryBodyByProjectKey(projectSearchVo.getProjectKey()));

            //关键字标红
            if (StringUtils.isNotBlank(projectSearchBo.getProjectName())) {
                projectSearchVo.setProjectName(StringUtils.markInRed(projectSearchVo.getProjectName(), projectSearchBo.getProjectName()));
            }
        }
        return TableDataInfo.build(page);
    }

    private Wrapper<DProject> buildProjectQueryWrapper(ProjectSearchBo projectSearchBo, List<Long> projectKeys) {
        QueryWrapper<DProject> wrapper = Wrappers.query();
        //咨询机构的项目数据取中建一局集团第二建筑有限公司和他的下级组织
        wrapper
                //承包单位ID
                .eq("p.contract_org_id", QueryConstants.LEVEL1_COMPANY_ID)
                //承包单位主键(字段叫主键,但并不是主键)
                .eq("p.contract_org_name", QueryConstants.LEVEL1_COMPANY_NAME)
                //项目名称
                .like(StringUtils.isNotBlank(projectSearchBo.getProjectName()), "p.project_name", projectSearchBo.getProjectName())
                //根据咨询机构名称查出来对应的项目ID
                .in(ObjectUtil.isNotNull(projectKeys) && !projectKeys.isEmpty(), "p.project_key", projectKeys)
                //业主单位
                .like(StringUtils.isNotBlank(projectSearchBo.getOwnerUnit()), "p.owner_name", projectSearchBo.getOwnerUnit())
                //项目创建时间(字段去的合同签约日期)
                .between(ObjectUtil.isNotNull(projectSearchBo.getProjectStartTime()) && ObjectUtil.isNotNull(projectSearchBo.getProjectEndTime()),
                        "p.contract_sign_date",
                        projectSearchBo.getProjectStartTime(),
                        projectSearchBo.getProjectEndTime())
                //项目承接类型下拉选项
                .eq(StringUtils.isNotBlank(projectSearchBo.getProjectUndertakeType()), "p.isinvestproject", projectSearchBo.getProjectUndertakeType())
                //工程基础大类下拉选项
                .eq(StringUtils.isNotBlank(projectSearchBo.getEngineeringFoundationCategory()), "p.project_type1", projectSearchBo.getEngineeringFoundationCategory())
                //工程类别明细
                .eq(StringUtils.isNotBlank(projectSearchBo.getEngineeringCategoryDetail()), "p.project_type", projectSearchBo.getEngineeringCategoryDetail())
                //合同金额
                .between(ObjectUtil.isNotNull(projectSearchBo.getMinContractAmount()) && ObjectUtil.isNotNull(projectSearchBo.getMaxContractAmount()),
                        "p.contract_orig_value",
                        projectSearchBo.getMinContractAmount(),
                        projectSearchBo.getMaxContractAmount())
                .orderByDesc("p.contract_sign_date");
        return wrapper;
    }

    /**
     * 根据项目主键查询咨询机构
     *
     * @param projectKey 项目主键
     * @return 咨询机构
     */
    private AdvisoryBody getAdvisoryBodyByProjectKey(Long projectKey) {
        return advisoryBodyMapper.queryAdvisoryBodyByProjectKey(projectKey);
    }

    /**
     * 获取合作项目明细
     *
     * @param cooperateProjectDetailSearchBo 查询实体
     * @param pageQuery                      分页对象
     * @return 所有数据
     */
    @Override
    public TableDataInfo<CooperateProjectDetailSearchVo> queryCooperateProjectDetailList(CooperateProjectDetailSearchBo cooperateProjectDetailSearchBo, PageQuery pageQuery) {
        //先根据咨询机构CID查出所有该咨询机构下的项目主键keys
        List<Long> projectKeys = advisoryBodyProjectMapper.selectProjectKeysByAdvisoryBodyCids(Collections.singletonList(cooperateProjectDetailSearchBo.getAdvisoryBodyCid()));
        if (projectKeys.isEmpty()) {
            return TableDataInfo.build();
        }
        //再根据记录终改的项目主键查询项目详情
        QueryWrapper<DProject> wrapper = Wrappers.query();
        wrapper
                //项目主键
                .in("project_key", projectKeys)
                //项目名称
                .like(StringUtils.isNotBlank(cooperateProjectDetailSearchBo.getProjectName()), "project_name", cooperateProjectDetailSearchBo.getProjectName())
                //项目承接类型
                .in(ObjectUtil.isNotNull(cooperateProjectDetailSearchBo.getIsinvestproject()), "isinvestproject", cooperateProjectDetailSearchBo.getIsinvestproject())
                //工程基础大类
                .in(ObjectUtil.isNotNull(cooperateProjectDetailSearchBo.getProjectType1()), "project_type1", cooperateProjectDetailSearchBo.getProjectType1())
                //工程类别明细
                .in(ObjectUtil.isNotNull(cooperateProjectDetailSearchBo.getProjectType()), "project_type", cooperateProjectDetailSearchBo.getProjectType())
                //项目地区
                .in(ObjectUtil.isNotNull(cooperateProjectDetailSearchBo.getProvinceName()), "province_name", cooperateProjectDetailSearchBo.getProvinceName())
                .or()
                .in(ObjectUtil.isNotNull(cooperateProjectDetailSearchBo.getCityName()), "city_name", cooperateProjectDetailSearchBo.getCityName());
        Page<CooperateProjectDetailSearchVo> page = baseMapper.selectPageCooperateProjectDetailList(pageQuery.build(), wrapper);

        for (CooperateProjectDetailSearchVo cooperateProjectDetailSearchVo : page.getRecords()) {
            AdvisoryBodyProject advisoryBodyProject = advisoryBodyProjectMapper.selectById(cooperateProjectDetailSearchVo.getProjectKey());
            //填充咨询机构与项目关联信息
            cooperateProjectDetailSearchVo.setAdvisoryBodyProject(advisoryBodyProject);
            //填充结算天数
            if (ObjectUtil.isNotNull(advisoryBodyProject)) {
                Date settleStartTime = advisoryBodyProject.getSettleStartTime();
                Date settleFinishTime = advisoryBodyProject.getSettleFinishTime();
                if (ObjectUtil.isNotNull(settleStartTime) && ObjectUtil.isNotNull(settleFinishTime)) {
                    cooperateProjectDetailSearchVo.setSettlementDays(DateUtil.between(settleStartTime, settleFinishTime, DateUnit.DAY));
                } else {
                    cooperateProjectDetailSearchVo.setSettlementDays(0L);
                }
            }

            //关键字标红
            if (StringUtils.isNotBlank(cooperateProjectDetailSearchBo.getProjectName())) {
                cooperateProjectDetailSearchVo.setProjectName(StringUtils.markInRed(cooperateProjectDetailSearchVo.getProjectName(), cooperateProjectDetailSearchBo.getProjectName()));
            }
        }
        return TableDataInfo.build(page);
    }

    /**
     * 根据项目主键查询项目详情
     *
     * @param projectDetailBo 查询实体
     * @return 项目详情
     */
    @Override
    public ProjectDetailVo queryProjectDetail(ProjectDetailBo projectDetailBo) {
        //查询项目明细
        DProject dProject = baseMapper.selectOne(new LambdaQueryWrapper<DProject>()
                .eq(DProject::getProjectKey, projectDetailBo.getProjectKey()));
        ProjectDetailVo projectDetailVo = BeanUtil.toBean(dProject, ProjectDetailVo.class);
        //查询咨询机构信息并填充
        projectDetailVo.setAdvisoryBody(advisoryBodyMapper.queryAdvisoryBodyByProjectKey(projectDetailBo.getProjectKey()));

        EnterpriseInfoHeaderBody infoHeaderBody = new EnterpriseInfoHeaderBody();
        infoHeaderBody.setCompanyId(Math.toIntExact(projectDetailBo.getAdvisoryBodyCid()));
        Map<String, Object> companyMap = dskOpenApiUtil.requestBody("/api/jsk/enterprise/infoHeader", BeanUtil.beanToMap(infoHeaderBody, false, false));
        Map companyData = MapUtils.getMap(companyMap, "data", null);
        //法人
        projectDetailVo.setCorporatePerson(MapUtils.getString(companyData, "corporatePerson", ""));
        //注册地址
        projectDetailVo.setRegAddress(MapUtils.getString(companyData, "addressDetail", ""));

        //查询项目信息并填充
        projectDetailVo.setAdvisoryBodyProject(advisoryBodyProjectMapper.selectById(projectDetailBo.getProjectKey()));
        return projectDetailVo;
    }
}

