package com.hz.pm.api.projectdeclared.converter;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.ningdatech.file.service.FileService;
import com.hz.pm.api.common.model.constant.BizConst;
import com.hz.pm.api.projectlib.model.enumeration.ProjectTypeEnum;
import com.hz.pm.api.projectlib.model.enumeration.ProjectTypeNewEnum;
import com.hz.pm.api.projectlib.model.entity.Project;
import com.hz.pm.api.projectlib.model.entity.ProjectApplication;
import com.hz.pm.api.provincial.model.dto.FileDTO;
import com.hz.pm.api.provincial.model.dto.ProvincialApplicationDTO;
import com.hz.pm.api.provincial.model.dto.ProvincialProjectDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

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

/**
 * @Classname ApplicationConverter
 * @Description
 * @Date 2023/3/13 17:38
 * @Author PoffyZhang
 */
@Slf4j
public class ApplicationConverter {

    public static ProvincialProjectDTO convertProject(Project projectInfo, List<ProjectApplication> applications,
                                                      FileService fileService, String active) {
        return ProvincialProjectDTO.builder()
                //暂时先写死
                .operationManageUnit(StringUtils.isBlank(active) || BizConst.DEV.equals(active) ?
                        "GO_a1479720291640b4982158fe3035a2d0" : projectInfo.getHigherSuperOrgCode())
                .digitalReform(String.valueOf(projectInfo.getBizDomain()))
                .regionCode(projectInfo.getAreaCode())
                .regionName(projectInfo.getArea())
                .projectName(projectInfo.getProjectName())
                .projectId(projectInfo.getProjectCode())
                .projectType(convertProjectType(projectInfo.getProjectType()))
                .totalMoney(projectInfo.getDeclareAmount())
                .yearBudget(projectInfo.getAnnualPlanAmount())
                .budgetFrom(checkAddBudget(projectInfo.getDeclareHaveAmount()
                        , projectInfo.getDeclareGovOwnFinanceAmount(),
                        projectInfo.getDeclareGovSuperiorFinanceAmount(),
                        projectInfo.getDeclareBankLendingAmount(),
                        projectInfo.getDeclareOtherAmount()))
                .year(String.valueOf(projectInfo.getProjectYear()))
                .financialCode(projectInfo.getFinancialCode())
                .developCode(projectInfo.getDevelopCode())
                .beginTime(projectInfo.getBeginTime())
                .endTime(projectInfo.getEndTime())
                .buildBasis("立项依据")
                .buildBasisFile(convertBasicFile(projectInfo.getBuildBasis(), fileService))
                .projectSummary(projectInfo.getProjectIntroduction())
                .responsibleMan(projectInfo.getResponsibleMan())
                .responsibleManPhone(projectInfo.getResponsibleManMobile())
                .contactName(projectInfo.getContactName())
                .contactPhone(projectInfo.getContactPhone())
                .buildUnit(projectInfo.getBuildOrgName())
                .buildUnitCode(StringUtils.isBlank(active) || BizConst.DEV.equals(active) ?
                        "GO_a1479720291640b4982158fe3035a2d0" : projectInfo.getBuildOrgCode())
                .superUnit(projectInfo.getSuperOrg())
                .superUnitCode(StringUtils.isBlank(active) || BizConst.DEV.equals(active) ?
                        "GO_a1479720291640b4982158fe3035a2d0" : projectInfo.getSuperOrgCode())
                .projectEstimateFile(convertFile(projectInfo.getCalculationTotalInvestmentFile(), fileService))
                .unitThreePlan(convertFile(projectInfo.getMainResponsibilitiesApplicantFile(), fileService))
                .otherFile(convertFile(projectInfo.getPreliminaryPlanFile(), fileService))
                .projectRemark(projectInfo.getProjectRemarks())
                .includeApplication(projectInfo.getIncludeApplication())
                .isEffective(1)
                .projectApplyFile(convertFile(projectInfo.getProjectApplicationForm(), fileService))
                .researchReport(convertFile(projectInfo.getPreliminaryPlanFile(), fileService))
                .applicationInfo(convertApplications(applications, fileService))
                .build();
    }

    private static Integer convertProjectType(String projectType) {
        if(StringUtils.isBlank(projectType)){
            return null;
        }

        if(Lists.newArrayList(ProjectTypeNewEnum.FIRST_BUILD.getCode(),
                ProjectTypeNewEnum.SJ_BUILD.getCode(),ProjectTypeNewEnum.SZ_BUILD.getCode()).contains(projectType)){
            return ProjectTypeEnum.BUILD.getCode();
        }else if(Lists.newArrayList(ProjectTypeNewEnum.NEW_OPERA.getCode(),
                ProjectTypeNewEnum.XU_OPERA.getCode()).contains(projectType)){
            return ProjectTypeEnum.DEV_OPS.getCode();
        }
        return null;
    }

    private static String checkAddBudget(BigDecimal declareHaveAmount, BigDecimal declareGovOwnFinanceAmount,
                                         BigDecimal declareGovSuperiorFinanceAmount, BigDecimal declareBankLendingAmount,
                                         BigDecimal otherAmount) {
        StringBuilder sb = new StringBuilder();

        if (Objects.nonNull(declareHaveAmount) && declareHaveAmount.compareTo(BigDecimal.ZERO) > 0) {
            sb.append("自有资金,");
        }
        if (Objects.nonNull(declareGovOwnFinanceAmount) && declareGovOwnFinanceAmount.compareTo(BigDecimal.ZERO) > 0) {
            sb.append("政府投资-本级财政资金,");
        }
        if (Objects.nonNull(declareGovSuperiorFinanceAmount) && declareGovSuperiorFinanceAmount.compareTo(BigDecimal.ZERO) > 0) {
            sb.append("政府投资-上级财政资金,");
        }
        if (Objects.nonNull(declareBankLendingAmount) && declareBankLendingAmount.compareTo(BigDecimal.ZERO) > 0) {
            sb.append("银行贷款,");
        }
        if (Objects.nonNull(otherAmount) && otherAmount.compareTo(BigDecimal.ZERO) > 0) {
            sb.append("其他资金");
        }
        return sb.toString();
    }

    //放入项目 app
    private static List<ProvincialApplicationDTO> convertApplications(List<ProjectApplication> applications,
                                                                      FileService fileService) {
        if (CollUtil.isEmpty(applications)) {
            return Collections.emptyList();
        }
        return applications.stream().map(app -> convertApp(app, fileService)).collect(Collectors.toList());
    }

    private static ProvincialApplicationDTO convertApp(ProjectApplication projectApplication, FileService fileService) {
        return ProvincialApplicationDTO.builder()
                .clouds(convertCloud(projectApplication))
                .isFirst(projectApplication.getIsFirst())
                .applicationName((projectApplication.getApplicationName()))
                .applicationCode(StringUtils.isNotBlank(projectApplication.getAppCode()) ?
                        projectApplication.getAppCode() : projectApplication.getRelatedExistsApplicationCode())
                .relatedExistsApplication(projectApplication.getRelatedExistsApplication())
                .applicationType(2)
                .buildLevel(projectApplication.getBuildLevel())
                .isUniteBuild(projectApplication.getIsUniteBuild())
                .unionBuildKind(projectApplication.getUnionBuildKind())
                .applicationSummary(projectApplication.getApplicationSummary())
                .applicationRemark(projectApplication.getApplicationRemark())
                .isFiveDomain(projectApplication.getIsDigitalModification())
                .fiveDomain(projectApplication.getDigitalModification())
                .bizDomain(projectApplication.getBizDomain())
                .isBizCooperate(projectApplication.getIsBizCooperate())
                .userRange(projectApplication.getUsesRangeRemark())
                .useGovCloud(projectApplication.getUseGovCloud())
                .nationalITSpec(projectApplication.getNationalItSpec())
                .netEnv(String.valueOf(projectApplication.getNetEnv()))
                .secrecyGrade(projectApplication.getSecrecyGrade())
                .passwordGrade(projectApplication.getPasswordGrade())
                .accountAppName(projectApplication.getAccountAppName())
                .brainAccountAppName(projectApplication.getDomainBrainAccount())
                .useCommonData(projectApplication.getUseCommonData())
                .dataName(projectApplication.getDataName())
                .commonComponents(projectApplication.getCommonComponents())
                .useCommonComponent(projectApplication.getUseCommonComponent())
                .isProduceCommonComponent(projectApplication.getProduceCommonComponent())
                .produceCommonComponent(projectApplication.getProduceCommonComponents())
                .publishSide(projectApplication.getPublishSide())
                .isS2(projectApplication.getIsAccountAppName())
                .accountAppName(projectApplication.getAccountAppName())
                .applicationEstimateFile(convertFile(projectApplication.getApplicationEstimateFile(), fileService))
                .cooperativeUnit(projectApplication.getBizCooperateInfo())
                .build();
    }

    private static String convertFile(String applicationEstimateFile, FileService fileService) {
        try {
            JSONArray jsonArrays = JSON.parseArray(applicationEstimateFile);
            List<FileDTO> files = jsonArrays.stream().map(json -> {
                JSONObject fileJson = (JSONObject) JSON.toJSON(json);
                Long fileId = fileJson.getLong("id");
                String fileName = fileJson.getString("originalFileName");
                Map<Long, String> fileMap = fileService.findUrlById(Arrays.asList(fileId));
                String url = fileMap.get(fileId);
                url = removeExpire(url);
                FileDTO file = new FileDTO();
                file.setFileId(String.valueOf(fileId));
                file.setFileName(fileName);
                file.setAccessUrl(url);
                return file;
            }).collect(Collectors.toList());
            return JSON.toJSONString(files);
        } catch (Exception e) {
            log.info("转换省局上传 文件出错 {}", e.getMessage());
        }
        return null;
    }

    /**
     * 去除掉 oss链接的超时时间
     *
     * @param url
     * @return
     */
    private static String removeExpire(String url) {
        if (StringUtils.isNotBlank(url)) {
            String s = "Expires";
            return url.replaceAll("&?" + s + "=[^&]*&", StringUtils.EMPTY);
        }
        return StringUtils.EMPTY;
    }

    //立项依据的文件格式不一样
    private static String convertBasicFile(String applicationEstimateFile, FileService fileService) {
        try {
            List<FileDTO> files = Lists.newArrayList();
            JSONArray jsonArrays = JSON.parseArray(applicationEstimateFile);
            jsonArrays.forEach(json -> {
                JSONObject fileJson = (JSONObject) JSON.toJSON(json);
                JSONArray fileList = fileJson.getJSONArray("fileList");
                fileList.forEach(f -> {
                    JSONObject fJson = (JSONObject) JSON.toJSON(f);
                    Long fileId = fJson.getLong("id");
                    String fileName = fJson.getString("originalFileName");
                    Map<Long, String> fileMap = fileService.findUrlById(Lists.newArrayList(fileId));
                    String url = fileMap.get(fileId);
                    url = removeExpire(url);
                    FileDTO file = new FileDTO();
                    file.setFileId(String.valueOf(fileId));
                    file.setFileName(fileName);
                    file.setAccessUrl(url);
                    files.add(file);
                });
            });
            return JSON.toJSONString(files);
        } catch (Exception e) {
            log.info("转换省局上传 basic文件出错 {}", e.getMessage());
        }
        return null;
    }

    private static List<ProvincialApplicationDTO.Cloud> convertCloud(ProjectApplication projectApplication) {
        return Lists.newArrayList(ProvincialApplicationDTO.Cloud.builder()
                .cloudType(projectApplication.getCloudsType())
                .cloudNums(projectApplication.getCloudsNumber())
                .cloudBasicSpec(projectApplication.getCloudsFoundationSpecifications())
                .cloudUseDescription(projectApplication.getCloudsDescription())
                .build());
    }

}
