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.DProject;
import com.dsk.cscec.domain.AdvisoryBody;
import com.dsk.cscec.domain.bo.AdvisoryBodySearchBo;
import com.dsk.cscec.domain.bo.CooperateProjectDetailSearchBo;
import com.dsk.cscec.domain.bo.ProjectSearchBo;
import com.dsk.cscec.domain.vo.AdvisoryBodySearchVo;
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.DProjectMapper;
import com.dsk.cscec.mapper.AdvisoryBodyMapper;
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.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 咨询机构管理
 *
 * @author makejava
 * @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 DskOpenApiUtil dskOpenApiUtil;

    /**
     * 获取所有项目列表数据
     *
     * @param projectSearchBo 查询实体
     * @param pageQuery       分页对象
     * @return 所有数据
     */
    @Override
    public TableDataInfo<ProjectSearchVo> queryProjectList(ProjectSearchBo projectSearchBo, PageQuery pageQuery) {
        //根据咨询机构名称查询对应的项目IDs
        String advisoryBodyName = projectSearchBo.getAdvisoryBodyName();
        List<Long> projectIds = new ArrayList<>();
        if (StringUtils.isNotBlank(advisoryBodyName)) {
            for (AdvisoryBody advisoryBody : advisoryBodyMapper.selectList(new LambdaQueryWrapper<AdvisoryBody>()
                    .like(AdvisoryBody::getAdvisoryBodyName, advisoryBodyName))) {
                if (ObjectUtil.isNotNull(advisoryBody.getProjectKey())) {
                    projectIds.add(advisoryBody.getProjectKey());
                }
            }
        }

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

        //补充咨询机构信息
        for (ProjectSearchVo projectSearchVo : page.getRecords()) {
            AdvisoryBody advisoryBody = this.getAdvisoryBodyByProjectKey(projectSearchVo.getProjectKey());
            if (ObjectUtil.isNotNull(advisoryBody)) {
                projectSearchVo.setAdvisoryBody(advisoryBody);
            }
        }
        return TableDataInfo.build(page);
    }

    private Wrapper<DProject> buildProjectQueryWrapper(ProjectSearchBo projectSearchBo, List<Long> projectIds) {
        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(!projectIds.isEmpty(), "p.project_id", projectIds)
                //业主单位
                .like(StringUtils.isNotBlank(projectSearchBo.getOwnerUnit()), "p.owner_name", projectSearchBo.getOwnerUnit())
                //项目创建时间(字段去的合同签约日期)
                .between(ObjectUtil.isNotNull(projectSearchBo.getProjectStartTime()) && ObjectUtil.isNotNull(projectSearchBo.getProjectEndTime()),
                        "p.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;
    }

    /**
     * 根据项目ID查询咨询机构
     *
     * @param projectKey 项目主键
     * @return 咨询机构
     */
    private AdvisoryBody getAdvisoryBodyByProjectKey(Long projectKey) {
        return advisoryBodyMapper.selectOne(new LambdaQueryWrapper<AdvisoryBody>()
                .eq(AdvisoryBody::getProjectKey, projectKey));
    }

    /**
     * 获取所有企业列表(咨询机构)数据
     *
     * @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())
                .between(ObjectUtil.isNotNull(advisoryBodySearchBo.getMinLastCooperateDate()) && ObjectUtil.isNotNull(advisoryBodySearchBo.getMaxLastCooperateDate()),
                        "create_time",
                        advisoryBodySearchBo.getMinLastCooperateDate(),
                        advisoryBodySearchBo.getMaxLastCooperateDate())
                .like(StringUtils.isNotBlank(advisoryBodySearchBo.getBusinessScope()), "business_scope", advisoryBodySearchBo.getBusinessScope());
        Page<AdvisoryBodySearchVo> page = advisoryBodyMapper.selectPageAdvisoryBodyList(pageQuery.build(), wrapper);
        //根据咨询机构cid查询对应的企业信息
        for (AdvisoryBodySearchVo advisoryBodySearchVo : page.getRecords()) {
            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);
            //最近一次合作时间
            advisoryBodySearchVo.setLastCooperateTime(advisoryBodyMapper.selectLastCooperateTime(advisoryBodySearchVo.getAdvisoryBodyId()));
            advisoryBodySearchVo.setBusinessStatus(MapUtils.getString(companyData, "businessStatus", ""));
            advisoryBodySearchVo.setCorporatePerson(MapUtils.getString(companyData, "corporatePerson", ""));
            String provinceName = MapUtils.getString(companyData, "provinceName", "");
            String cityName = MapUtils.getString(companyData, "cityName", "");
            String districtName = MapUtils.getString(companyData, "districtName", "");
            advisoryBodySearchVo.setRegCapital(provinceName + "-" + cityName + "-" + districtName);
            advisoryBodySearchVo.setRegArea(MapUtils.getString(companyData, "regArea", ""));
            advisoryBodySearchVo.setRegisteredDate(MapUtils.getString(companyData, "registeredDate", ""));
            advisoryBodySearchVo.setBusinessScope(MapUtils.getString(companyData, "businessScope", ""));
            //合作项目数量
            advisoryBodySearchVo.setCooperateProjectCount(advisoryBodyMapper.selectCount(new LambdaQueryWrapper<AdvisoryBody>()
                    .eq(AdvisoryBody::getAdvisoryBodyId, advisoryBodySearchVo.getAdvisoryBodyId())));
        }
        return TableDataInfo.build(page);
    }

    /**
     * 获取合作项目明细
     *
     * @param cooperateProjectDetailSearchBo 查询实体
     * @param pageQuery                      分页对象
     * @return 所有数据
     */
    @Override
    public TableDataInfo<CooperateProjectDetailSearchVo> queryCooperateProjectDetailList(CooperateProjectDetailSearchBo cooperateProjectDetailSearchBo, PageQuery pageQuery) {
        //先根据咨询机构ID查出所有该咨询机构下的记录
        List<AdvisoryBody> advisoryBodyList = advisoryBodyMapper.selectList(new LambdaQueryWrapper<AdvisoryBody>()
                .eq(AdvisoryBody::getAdvisoryBodyId, cooperateProjectDetailSearchBo.getAdvisoryBodyId()));

        //提取所有项目主键
        ArrayList<Long> projectKeyList = new ArrayList<>();
        for (AdvisoryBody advisoryBody : advisoryBodyList) {
            projectKeyList.add(advisoryBody.getProjectKey());
        }

        //再根据记录终改的项目主键查询项目详情
        QueryWrapper<DProject> wrapper = Wrappers.query();
        wrapper
                //项目主键
                .in(!projectKeyList.isEmpty(), "project_key", projectKeyList)
                //项目名称
                .like(StringUtils.isNotBlank(cooperateProjectDetailSearchBo.getProjectName()), "project_name", cooperateProjectDetailSearchBo.getProjectName())
                //项目承接类型
                .in(!cooperateProjectDetailSearchBo.getIsinvestproject().isEmpty(), "isinvestproject", cooperateProjectDetailSearchBo.getIsinvestproject())
                //工程基础大类
                .in(!cooperateProjectDetailSearchBo.getProjectType1().isEmpty(), "project_type1", cooperateProjectDetailSearchBo.getProjectType1())
                //工程类别明细
                .in(!cooperateProjectDetailSearchBo.getProjectType().isEmpty(), "project_type", cooperateProjectDetailSearchBo.getProjectType())
                //项目地区
                .in(!cooperateProjectDetailSearchBo.getProvinceName().isEmpty(), "province_name", cooperateProjectDetailSearchBo.getProvinceName())
                .or()
                .in(!cooperateProjectDetailSearchBo.getCityName().isEmpty(), "city_name", cooperateProjectDetailSearchBo.getCityName());
        Page<CooperateProjectDetailSearchVo> page = baseMapper.selectPageCooperateProjectDetailList(pageQuery.build(), wrapper);

        //填充结算天数
        for (CooperateProjectDetailSearchVo cooperateProjectDetailSearchVo : page.getRecords()) {
            for (AdvisoryBody advisoryBody : advisoryBodyList) {
                if (Objects.equals(advisoryBody.getProjectKey(), cooperateProjectDetailSearchVo.getProjectKey())) {
                    long betweenDays = DateUtil.between(advisoryBody.getSettleStartTime(), advisoryBody.getSettleFinishTime(), DateUnit.DAY);
                    cooperateProjectDetailSearchVo.setSettlementDays(betweenDays);
                }
            }
        }
        return TableDataInfo.build(page);
    }

    /**
     * 根据项目主键查询项目详情
     *
     * @param projectKey 项目主键
     * @return 项目详情
     */
    @Override
    public ProjectDetailVo queryProjectDetail(Long projectKey) {
        //查询项目明细
        DProject dProject = baseMapper.selectOne(new LambdaQueryWrapper<DProject>()
                .eq(DProject::getProjectKey, projectKey));
        ProjectDetailVo projectDetailVo = BeanUtil.toBean(dProject, ProjectDetailVo.class);
        //查询咨询机构信息
        AdvisoryBody advisoryBody = advisoryBodyMapper.selectOne(new LambdaQueryWrapper<AdvisoryBody>().eq(AdvisoryBody::getProjectKey, projectKey));
        //填充咨询机构名称
        projectDetailVo.setAdvisoryBodyName(advisoryBody.getAdvisoryBodyName());
        return projectDetailVo;
    }

    @Override
    public AdvisoryBody queryAdvisoryBodyDetail(Long advisoryBodyId) {
        return null;
    }
}

