package com.ningdatech.pmapi.projectlib.manage;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.pmapi.common.constant.CommonConst;
import com.ningdatech.pmapi.common.model.entity.ExcelExportWriter;
import com.ningdatech.pmapi.common.util.ExcelDownUtil;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum;
import com.ningdatech.pmapi.projectlib.handle.ProcessExecuteChainHandle;
import com.ningdatech.pmapi.projectlib.helper.ProjectHelper;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectRenewalFundDeclaration;
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq;
import com.ningdatech.pmapi.projectlib.model.vo.AnnualAmountVO;
import com.ningdatech.pmapi.projectlib.model.vo.ProcessDetailVO;
import com.ningdatech.pmapi.projectlib.model.vo.ProjectDetailVO;
import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO;
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService;
import com.ningdatech.pmapi.projectlib.service.IProjectRenewalFundDeclarationService;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * <p>
 * ProjectLibManage
 * </p>
 *
 * @author WendyYang
 * @since 14:19 2023/2/1
 */
@Component
@RequiredArgsConstructor
public class ProjectLibManage {

    private final IProjectService projectService;
    private final IProjectApplicationService applicationService;
    private final IProjectRenewalFundDeclarationService renewalFundDeclarationService;
    private final ProcessExecuteChainHandle processExecuteHandle;

    public PageVo<ProjectLibListItemVO> projectLibList(ProjectListReq req) {
        LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req);
        Page<Project> page = projectService.page(req.page(), query);
        long total;
        if ((total = page.getTotal()) == 0) {
            return PageVo.empty();
        }
        List<ProjectLibListItemVO> records = CollUtils.convert(page.getRecords(), w -> {
            ProjectLibListItemVO item = new ProjectLibListItemVO();
            item.setId(w.getId());
            item.setProjectName(w.getProjectName());
            item.setCreateOn(w.getCreateOn());
            item.setDeclaredAmount(w.getDeclareAmount());
            item.setStage(w.getStage());
            item.setStatus(w.getStatus());
            item.setProjectType(w.getProjectType());
            item.setProjectYear(w.getProjectYear());
            item.setBuildOrg(w.getBuildOrgName());
            item.setBizDomain(w.getBizDomain());
            item.setProcessStatus(w.getProcessStatus());
            item.setInstCode(w.getInstCode());
            return item;
        });
        return PageVo.of(records, total);
    }

    public List<Project> projectList(ProjectListReq req) {
        LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req);
        return projectService.list(query);
    }

    /**
     * @param projectId 项目详情
     * @return com.ningdatech.pmapi.projectlib.model.entity.vo.ProjectDetailVO
     * @author ZPF
     * @since 2023/02/11 11:15
     */
    public ProjectDetailVO getProjectDetail(Long projectId) {
        // 查询项目申报信息
        Project projectInfo = projectService.getById(projectId);
        if (Objects.isNull(projectInfo)) {
            return null;
        }
        ProjectDetailVO vo = new ProjectDetailVO();
        BeanUtils.copyProperties(projectInfo, vo);
        vo.buildDynamicForm(projectInfo.getDynamicForm());
        // 查询应用
        List<ProjectApplication> applications = applicationService.list(Wrappers.lambdaQuery(ProjectApplication.class)
                .eq(ProjectApplication::getProjectId, vo.getId()));
        Optional.ofNullable(applications).ifPresent(apps ->
                vo.setProjectApplications(CollUtils.convert(apps,
                        ProjectHelper::convertVO)
                ));

        //查询年度投资金额 要是已验收的项目
        if (ProjectStatusEnum.ACCEPTED.getCode().equals(projectInfo.getStatus())) {
            List<AnnualAmountVO> annualAmounts = Lists.newArrayList();
            annualAmounts.add(AnnualAmountVO.builder()
                    .projectId(projectInfo.getId())
                    .projectYear(projectInfo.getProjectYear())
                    .annualAmount(projectInfo.getAnnualPlanAmount())
                    .build());
            List<ProjectRenewalFundDeclaration> renewalDeclarations = renewalFundDeclarationService.list(Wrappers.lambdaQuery(ProjectRenewalFundDeclaration.class)
                    .eq(ProjectRenewalFundDeclaration::getProjectId, vo.getId())
                    .orderByAsc(ProjectRenewalFundDeclaration::getProjectYear));
            Optional.ofNullable(renewalDeclarations).ifPresent(declarations ->
                    declarations.forEach(declaration -> {
                        annualAmounts.add(AnnualAmountVO.builder()
                                .projectId(projectInfo.getId())
                                .projectYear(declaration.getProjectYear())
                                .annualAmount(declaration.getAnnualPaymentAmount())
                                .build());
                    })
            );
            vo.setAnnualAccumulateAmountList(annualAmounts);
        }
        return vo;
    }

    public List<ProcessDetailVO> processScheduleDetail(Long projectId) {
        List<ProcessDetailVO> processDetailVOS = new ArrayList<>();
        return processExecuteHandle.handle(projectId, processDetailVOS);
    }

    public void exportList(ProjectListReq param, HttpServletResponse response) {
        param.setPageNumber(CommonConst.EXPORT_PAGE_NUMBER);
        param.setPageSize(CommonConst.EXPORT_PAGE_SIZE);
        LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param);
        List<Project> projects = projectService.list(query);

        ExcelExportWriter excelExportWriter = new ExcelExportWriter();

        String fileName = "项目库列表";
        excelExportWriter.setFileName(fileName);

        List<String> sheetsNames = new ArrayList<>();
        sheetsNames.add(fileName);
        // 表体行数据集合
        List<List<String>> exportDatas = ExcelDownUtil.getExportDatas(param.getExportOptionList(), projects);
        // sheet列表集合
        List<List<List<String>>> sheets = new ArrayList<>();
        sheets.add(exportDatas);
        excelExportWriter.setHeads(sheets);
        excelExportWriter.setDatas(exportDatas);
        excelExportWriter.setSheets(sheetsNames);
        excelExportWriter.setHeadPropertyClass(List.class);
        excelExportWriter.setHeadPropertyFlag(Boolean.FALSE);
        ExcelDownUtil.excelExportFile(response, excelExportWriter);
    }
}
