package com.ningdatech.pmapi.projectlib.manage;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.basic.util.NdDateUtils;
import com.ningdatech.pmapi.common.constant.CommonConst;
import com.ningdatech.pmapi.common.util.ExcelDownUtil;
import com.ningdatech.pmapi.common.util.ExcelExportStyle;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectRenewalApprovalStatusEnum;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum;
import com.ningdatech.pmapi.projectlib.model.dto.ProjectRenewalExportDTO;
import com.ningdatech.pmapi.projectlib.model.dto.ProjectRenewalFundDeclarationDTO;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectRenewalFundDeclaration;
import com.ningdatech.pmapi.projectlib.model.po.ProjectRenewalFundDeclarationPO;
import com.ningdatech.pmapi.projectlib.model.req.ProjectRenewalAuditReq;
import com.ningdatech.pmapi.projectlib.model.req.ProjectRenewalListReq;
import com.ningdatech.pmapi.projectlib.model.vo.ProjectRenewalFundDeclarationVO;
import com.ningdatech.pmapi.projectlib.service.IProjectRenewalFundDeclarationService;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.wflow.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * ProjectRenewalFundManage
 * </p>
 *
 * @author ZPF
 * @since 14:19 2023/2/15
 */
@Component
@RequiredArgsConstructor
public class ProjectRenewalFundManage {

    private final IProjectRenewalFundDeclarationService projectRenewalFundDeclarationService;

    private final IProjectService projectService;

    /**
     * 项目续建资金库列表 分页
     * @param req
     * @return
     */
    public PageVo<ProjectRenewalFundDeclarationVO> list(ProjectRenewalListReq req) {
        Page<ProjectRenewalFundDeclarationPO> page = req.page();
        projectRenewalFundDeclarationService.pageSql(page, req);
        long total;
        if ((total = page.getTotal()) == 0) {
            return PageVo.empty();
        }
        List<ProjectRenewalFundDeclarationVO> records = CollUtils.convert(page.getRecords(), w -> {
            ProjectRenewalFundDeclarationVO item = new ProjectRenewalFundDeclarationVO();
            BeanUtils.copyProperties(w,item);
            return item;
        });
        return PageVo.of(records, total);
    }

    /**
     * @param id
     * @author ZPF
     * @since 2023/02/15 11:15
     */
    public ProjectRenewalFundDeclarationVO detail(Long id) {
        // 查询项目申报信息
        ProjectRenewalFundDeclaration renewal = projectRenewalFundDeclarationService.getById(id);
        if(Objects.isNull(renewal)){
            return null;
        }
        ProjectRenewalFundDeclarationVO vo = new ProjectRenewalFundDeclarationVO();
        BeanUtils.copyProperties(renewal, vo);
        // 查询项目信息
        Project project = projectService.getById(renewal.getProjectId());
        if(Objects.isNull(project)){
            return vo;
        }
        vo.setApprovalAmount(project.getApprovalAmount());
        vo.setProjectName(project.getProjectName());
        vo.setProjectType(project.getProjectType());
        vo.setStage(project.getStage());
        vo.setStatus(project.getStatus());
        vo.setBuildOrgName(project.getBuildOrgName());
        return vo;
    }

    /**
     * 申报
     * @param dto
     * @return
     */
    public Long declared(ProjectRenewalFundDeclarationDTO dto) {
        //要判断 项目id 是否 以及状态是 已验收
        Long projectId = dto.getProjectId();
        Project project = projectService.getById(projectId);
        VUtils.isTrue(Objects.isNull(project)).throwMessage(String.format("关联的项目【%s】不存在 提交失败!",projectId));
        VUtils.isTrue(!ProjectStatusEnum.ACCEPTED.getCode().equals(project.getStatus()) ||
                        !ProjectStatusEnum.ARCHIVED.getCode().equals(project.getStage()))
                .throwMessage("提交失败 该项目不是 已验收状态或者已归档阶段");
        ProjectRenewalFundDeclaration declaration = new ProjectRenewalFundDeclaration();
        //如果是重新申报
        if(Objects.nonNull(dto.getId())){
            ProjectRenewalFundDeclaration oldDeclaration = projectRenewalFundDeclarationService.getById(dto.getId());
            VUtils.isTrue(Objects.isNull(oldDeclaration)).throwMessage(String.format("重新申报失败 【%s】 该申报不存在!",dto.getId()));
            BeanUtils.copyProperties(oldDeclaration,declaration);
        }
        BeanUtils.copyProperties(dto,declaration);
        declaration.setCreateOn(LocalDateTime.now());
        declaration.setUpdateOn(LocalDateTime.now());
        declaration.setApprovalStatus(ProjectRenewalApprovalStatusEnum.PENDING.name());
        if(!projectRenewalFundDeclarationService.saveOrUpdate(declaration)){
            throw new BusinessException(String.format("申报失败 【%s】",dto.getId()));
        }
        return declaration.getId();
    }

    /**
     * 续建项目审核
     * @param param
     * @return
     */
    public Long audit(ProjectRenewalAuditReq param) {
        Long projectRenewalId = param.getProjectRenewalId();
        ProjectRenewalFundDeclaration projectRenewal = projectRenewalFundDeclarationService.getById(projectRenewalId);
        if (Boolean.TRUE.equals(param.getResult())){
            projectRenewal.setApprovalStatus(ProjectRenewalApprovalStatusEnum.PASS.name());
        }else {
            String auditOpinion = param.getAuditOpinion();
            if (StrUtil.isBlank(auditOpinion)){
                throw new BizException("审核意见不能为空");
            }
            projectRenewal.setAuditOpinion(auditOpinion);
            projectRenewal.setApprovalStatus(ProjectRenewalApprovalStatusEnum.NOT_PASS.name());
        }
        projectRenewal.setUpdateOn(LocalDateTime.now());
        projectRenewalFundDeclarationService.updateById(projectRenewal);
        return projectRenewal.getId();
    }

    /**
     * 续建项目删除
     * @param projectRenewalId
     * @return
     */
    public Long delete(Long projectRenewalId) {
        ProjectRenewalFundDeclaration projectRenewal = projectRenewalFundDeclarationService.getById(projectRenewalId);
        projectRenewal.setDeleted(true);
        projectRenewal.setUpdateOn(LocalDateTime.now());
        projectRenewalFundDeclarationService.updateById(projectRenewal);
        return projectRenewal.getId();
    }

    public void exportList(HttpServletResponse response, ProjectRenewalListReq param) {

        param.setPageNumber(CommonConst.EXPORT_PAGE_NUMBER);
        param.setPageSize(CommonConst.EXPORT_PAGE_SIZE);
        Page<ProjectRenewalFundDeclarationPO> page = param.page();
        projectRenewalFundDeclarationService.pageSql(page, param);
        List<ProjectRenewalFundDeclarationPO> records = page.getRecords();

        List<ProjectRenewalExportDTO> collect = records.stream().map(r -> {
            ProjectRenewalExportDTO exportDTO = new ProjectRenewalExportDTO();
            BeanUtils.copyProperties(r, exportDTO);
            exportDTO.setProjectTypeName(ProjectTypeEnum.getDesc(r.getProjectType()));
            if (ProjectRenewalApprovalStatusEnum.PENDING.name().equals(r.getApprovalStatus())) {
                exportDTO.setApprovalStatusName(ProjectRenewalApprovalStatusEnum.PENDING.getDesc());
            } else if (ProjectRenewalApprovalStatusEnum.PASS.name().equals(r.getApprovalStatus())) {
                exportDTO.setApprovalStatusName(ProjectRenewalApprovalStatusEnum.PASS.getDesc());
            } else if (ProjectRenewalApprovalStatusEnum.NOT_PASS.name().equals(r.getApprovalStatus())) {
                exportDTO.setApprovalStatusName(ProjectRenewalApprovalStatusEnum.NOT_PASS.getDesc());
            }
            String createOnStr = NdDateUtils.format(r.getCreateOn(), "yyyy-MM-dd HH:mm");
            exportDTO.setCreateOn(createOnStr);
            return exportDTO;
        }).collect(Collectors.toList());


        String fileName = "续建项目资金库列表";
        ExcelDownUtil.setFileName(fileName,response);
        //数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), ProjectRenewalExportDTO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
