package com.jeeplus.test.cw.projectReport.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeeplus.aop.logging.annotation.ApiLog;
import com.jeeplus.common.redis.RedisUtils;
import com.jeeplus.common.utils.ResponseUtil;
import com.jeeplus.core.excel.ExcelOptions;
import com.jeeplus.core.excel.ExportMode;
import com.jeeplus.core.excel.utils.EasyPoiUtil;
import com.jeeplus.flowable.service.FlowTaskService;
import com.jeeplus.sys.constant.enums.LogTypeEnum;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.sys.utils.DictUtils;
import com.jeeplus.sys.utils.UserUtils;
import com.jeeplus.test.cw.invoice.service.dto.CwFinanceInvoiceDTO;
import com.jeeplus.test.cw.projectReport.domain.CwProjectReport;
import com.jeeplus.test.cw.projectReport.domain.CwProjectReportData;
import com.jeeplus.test.cw.projectReport.domain.CwProjectReportSignature;
import com.jeeplus.test.cw.projectReport.mapper.ProjectReportWorkAttachmentMapper;
import com.jeeplus.test.cw.projectReport.service.CwProjectReportService;
import com.jeeplus.test.cw.projectReport.service.dto.CwProjectReportSignatureDTO;
import com.jeeplus.test.cw.projectReport.service.dto.ProjectReportWorkAttachmentDTO;
import com.jeeplus.test.cw.workClientInfo.service.dto.CwWorkClientBaseDTO;
import com.jeeplus.test.oss.domain.WorkAttachment;
import com.jeeplus.test.program.configuration.projectList.domain.ProgramProjectListInfo;
import com.jeeplus.test.signature.utils.SignaturePostUtil;
import com.jeeplus.test.utils.FreemarkerUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author: 王强
 * @create: 2022-11-16 14:15
 **/
@RestController
@Api("财务报告信息")
@RequestMapping(value = "/cwProjectReport")
public class CwProjectReportController {

    @Resource
    private CwProjectReportService projectReportService;
    @Autowired
    private RedisUtils redisUtils;
    @Resource
    private ProjectReportWorkAttachmentMapper attachmentMapper;
    @Autowired
    private FlowTaskService flowTaskService;
    @Autowired
    private TaskService taskService;

    /**
     * 保存财务报告信息-流程
     * @param reportData
     * @return
     */
    @ApiLog(value = "保存财务报告信息-流程", type = LogTypeEnum.SAVE)
    @PreAuthorize("hasAnyAuthority('cwProjectReport:add','cwProjectReport:edit')")
    @PostMapping("saveForm")
    public ResponseEntity saveForm(@Valid @RequestBody CwProjectReportData reportData) throws Exception {
        String id = projectReportService.saveForm(reportData);
        return ResponseUtil.newInstance().add("businessTable", "cw_project_report").add("businessId", id).ok ("操作成功");
    }

    /**
     * 签章附件保存
     * @return
     */
    @ApiLog(value = "签章附件保存", type = LogTypeEnum.SAVE)
    @PostMapping("saveSignFiles")
    public ResponseEntity saveSignFiles(@RequestBody CwProjectReportData reportData) {
        UserDTO userDTO = UserUtils.getCurrentUserDTO();
        if (CollectionUtil.isEmpty(reportData.getCwFileInfoList())) {
            reportData.setCwFileInfoList(new ArrayList<>());
        }
        projectReportService.updateSignatureFiles(reportData.getCwFileInfoList(),userDTO,reportData.getId());
        return ResponseEntity.ok("操作成功");
    }

    /**
     * 查询财务项目信息列表
     * @param projectReportData
     * @param page
     * @return
     */
    @ApiLog("查询财务报告信息列表")
    @PreAuthorize("hasAuthority('cwProjectReport:list')")
    @GetMapping("list")
    public ResponseEntity<IPage<CwProjectReportData>> data(CwProjectReportData projectReportData, Page<CwProjectReportData> page) throws Exception {
        IPage<CwProjectReportData> result = new Page<CwProjectReportData>();
        result = projectReportService.findList (page,projectReportData);
        result.getRecords().stream().forEach(i -> {
            // 复核
            if (StringUtils.isNotBlank(i.getRevTaskId()) && StringUtils.isNotBlank(i.getReviewStatus())) {
                if ("2".equals(i.getReviewStatus())) { // “审核中”的数据要获取数据审核人
                    i.setAuditUserIdsRev(flowTaskService.getTaskAuditUsers(i.getRevTaskId()));  // 获取数据审核人
                }
            }
            // 签章
            if (StringUtils.isNotBlank(i.getSignatureType())) {
                // 电子章
                if ("1".equals(i.getSignatureType())) {
                    if (StringUtils.isNotBlank(i.getSignTaskId1()) && StringUtils.isNotBlank(i.getStatus1())) {
                        if ("2".equals(i.getStatus1())) { // “审核中”的数据要获取数据审核人
                            i.setAuditUserIdsSign1(flowTaskService.getTaskAuditUsers(i.getSignTaskId1()));  // 获取数据审核人
                        }
                    }
                }
                // 公章+执业章
                if ("2".equals(i.getSignatureType())) {
                    if (StringUtils.isNotBlank(i.getSignTaskId2()) && StringUtils.isNotBlank(i.getStatus2())) {
                        if ("2".equals(i.getStatus2())) { // “审核中”的数据要获取数据审核人
                            i.setAuditUserIdsSign2(flowTaskService.getTaskAuditUsers(i.getSignTaskId2()));  // 获取数据审核人
                        }
                    }
                }
                // 实体章
                if ("3".equals(i.getSignatureType())) {
                    if (StringUtils.isNotBlank(i.getSignTaskId3()) && StringUtils.isNotBlank(i.getStatus3())) {
                        if ("2".equals(i.getStatus3())) { // “审核中”的数据要获取数据审核人
                            i.setAuditUserIdsSign3(flowTaskService.getTaskAuditUsers(i.getSignTaskId3()));  // 获取数据审核人
                        }
                    }
                }
            }
        });
        return ResponseEntity.ok (result);
    }

    /**
     * 根据id修改状态值status
     * @param data
     * @return
     */
    @ApiOperation(value = "根据id修改状态值status")
    @PostMapping(value = "/updateStatusById")
    public ResponseEntity<String> updateStatusById(@RequestBody CwProjectReportData data) {
        String s = projectReportService.updateStatusById(data);
        return ResponseEntity.ok(s);
    }

    /**
     * 查询客户信息数据
     * @param id
     * @return
     */
    @ApiLog("查询财务报告数据")
    // @PreAuthorize ("hasAnyAuthority('cwProjectReport:view','cwProjectReport:add','cwProjectReport:edit')")
    @GetMapping("queryById")
    public ResponseEntity queryById(@RequestParam("id") String id) {
        CwProjectReportData projectReportData = projectReportService.queryById ( id );
        return ResponseEntity.ok (projectReportData);
    }

    /**
     * 下载报告审核单
     * @param response
     * @param id
     */
    @RequestMapping(value="downloadCwReportAuditTpl")
    @ResponseBody
    public void downloadCwReportAuditTpl(HttpServletResponse response,@RequestParam("id") String id)  {
        Map data = projectReportService.getAuditInfoMap(response, id );

        //模板对象
        Template template=null;
        //freemaker模板路径
        File path = new File(this.getClass().getResource("/").getPath()+"/freemarker");
        Configuration cfg = new Configuration();
        try {
            cfg.setDirectoryForTemplateLoading(path);
            //选择对应的ftl文件
            template = cfg.getTemplate("cwAudit.ftl","UTF-8");

            File docFile = new File("报告审核单.xls");
            FreemarkerUtil.generateFile(data,template,docFile);
            com.jeeplus.test.utils.ResponseUtil.docResponse("报告审核单.xls",docFile,response);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //获取tomcat的路径
            String tomcatFilePath=System.getProperty("catalina.home");
            //删除tomcat目录下的处理后的文件信息
            File tomcatFile = new File(tomcatFilePath+"/bin/"+"报告审核单.xls");
            if (tomcatFile.isFile()) {
                tomcatFile.delete();
            }
        }

    }

    /**
     * 删除业务提问
     * @param ids
     * @return
     */
    @ApiLog(value = "删除财务报告信息", type = LogTypeEnum.SAVE)
    @PreAuthorize ("hasAuthority('cwProjectReport:del')")
    @DeleteMapping("delete")
    public ResponseEntity delete(String ids) {
        return projectReportService.deleteByIds(ids);
    }

    /**
     * 查询客户信息列表
     * @param cwWorkClientBaseDTO
     * @param page
     * @return
     * @throws Exception
     */
    @ApiLog("查询客户信息列表")
    @PreAuthorize("hasAuthority('cwProjectReport:clineList')")
    @GetMapping("clineList")
    public ResponseEntity<IPage<CwWorkClientBaseDTO>> data(CwWorkClientBaseDTO cwWorkClientBaseDTO, Page<CwWorkClientBaseDTO> page,String projectId) throws Exception {
        IPage<CwWorkClientBaseDTO> result = new Page<CwWorkClientBaseDTO>();
        result = projectReportService.findClineList (page,cwWorkClientBaseDTO,projectId);
        return ResponseEntity.ok (result);
    }

    /**
     * 签章链接
     * @param cwProjectReportData
     * @return
     */
    @ApiLog(value = "签章链接", type = LogTypeEnum.SAVE)
    @PostMapping("saveFlowableParam")
    public ResponseEntity<String> saveFlowableParam(@Valid @RequestBody CwProjectReportData cwProjectReportData) {
        //查询报告文件信息（电子章）
//        List<WorkAttachment> fileList = attachmentMapper.selectWorkAttachmentByReportId(cwProjectReportData.getId());
        // 有电子章的附件时，走签章流程
//        if (CollectionUtil.isNotEmpty(fileList)) {
//            CwProjectReportData cwProjectReportDto = projectReportService.queryById(cwProjectReportData.getId());
//            // 获取签章页面url
//            String mobile = UserUtils.getCurrentUserDTO().getMobile();
//            String signatureContractUrl = SignaturePostUtil.getSignatureContractUrl(cwProjectReportDto.getSignatureContractId(), mobile);
//            // 将数据存储到redis中，key为contractId
//            cwProjectReportData.getCommitParamDTO().setVars(cwProjectReportDto);
//            redisUtils.set("cw_report_signature_" + cwProjectReportDto.getSignatureContractId(),cwProjectReportData.getCommitParamDTO());
//            redisUtils.expire("cw_report_signature_" + cwProjectReportDto.getSignatureContractId(),24, TimeUnit.HOURS);
//            return ResponseEntity.ok(signatureContractUrl);
//        } else {
//            // 没有电子章的附件时，走正常审核流程
//            // 流程审核通过
//            projectReportService.commitFlowable(cwProjectReportData);
//            return ResponseEntity.ok("操作成功");
//        }

        CwProjectReportData cwProjectReportDto = projectReportService.queryById(cwProjectReportData.getId());
        // 获取签章页面url
        String mobile = UserUtils.getCurrentUserDTO().getMobile();
        String signatureContractUrl = SignaturePostUtil.getSignatureContractUrl(cwProjectReportDto.getSignatureContractId(), mobile);
        // 将数据存储到redis中，key为contractId
        if("1".equals(cwProjectReportDto.getSignatureType())) {
            redisUtils.set("cw_report_signature_" + cwProjectReportDto.getSignatureContractId(),cwProjectReportDto.getSid1());
        }
        if("2".equals(cwProjectReportDto.getSignatureType())) {
            redisUtils.set("cw_report_signature_" + cwProjectReportDto.getSignatureContractId(),cwProjectReportDto.getSid2());
        }
        redisUtils.expire("cw_report_signature_" + cwProjectReportDto.getSignatureContractId(),24, TimeUnit.HOURS);
        return ResponseEntity.ok(signatureContractUrl);
    }

    /**
     * 签章流程送审
     * @param cwProjectReportData
     * @return
     */
    @ApiLog(value = "签章流程送审", type = LogTypeEnum.SAVE)
    @PostMapping("saveData")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<String> saveData(@Valid @RequestBody CwProjectReportData cwProjectReportData) {
        // 修改报告表的 “签字注师1” 和 “签字注师2”
        if (ObjectUtil.isNotEmpty(cwProjectReportData)) {
            CwProjectReport cwProjectReport = new CwProjectReport();
            cwProjectReport.setId(cwProjectReportData.getId());
            if (StringUtils.isNotBlank(cwProjectReportData.getSignatureAnnotator1())) {
                cwProjectReport.setSignatureAnnotator1(cwProjectReportData.getSignatureAnnotator1());
            }
            if (StringUtils.isNotBlank(cwProjectReportData.getSignatureAnnotator2())) {
                cwProjectReport.setSignatureAnnotator2(cwProjectReportData.getSignatureAnnotator2());
            }
            if (StringUtils.isNotBlank(cwProjectReportData.getIndustry())) {
                cwProjectReport.setIndustry(cwProjectReportData.getIndustry());
            }
            if (StringUtils.isNotBlank(cwProjectReportData.getBusinessObjects())) {
                cwProjectReport.setBusinessObjects(cwProjectReportData.getBusinessObjects());
            }
            projectReportService.updateAnnotatorById(cwProjectReport);
        }
        if ("3".equals(cwProjectReportData.getSignatureType())) {
            // 实体公章流程
            String signatureId = projectReportService.getSignature(cwProjectReportData);
            return ResponseUtil.newInstance().add("businessTable", "cw_project_report_signature").add("businessId", signatureId).ok ("操作成功");
        } else {
            //查询报告文件信息（电子章）
            List<WorkAttachment> fileList = attachmentMapper.selectWorkAttachmentByReportId(cwProjectReportData.getId());
            if (CollectionUtil.isNotEmpty(fileList)) {
                // 有电子章的附件时，走签章流程
                Map<String, Object> signatureContractId = projectReportService.createSignatureContractId(cwProjectReportData);
                boolean bool = (boolean)signatureContractId.get("success");
                if (bool) {
                    String signatureId = projectReportService.getSignature(cwProjectReportData);
                    return ResponseUtil.newInstance().add("businessTable", "cw_project_report_signature").add("businessId", signatureId).ok ("操作成功");
                }
                return ResponseEntity.badRequest().body((String) signatureContractId.get("message"));
            } else {
                // 没有电子章的附件时，走正常审核流程
                String signatureId = projectReportService.getSignature(cwProjectReportData);
                return ResponseUtil.newInstance().add("businessTable", "cw_project_report_signature").add("businessId", signatureId).ok ("操作成功");
            }
        }
    }

    /**
     * 根据签章表id查询报告数据
     * @param id
     * @return
     */
    @ApiLog("根据签章表id查询报告数据")
    @PreAuthorize ("hasAnyAuthority('cwProjectReport:view','cwProjectReport:add','cwProjectReport:edit')")
    @GetMapping("queryBySignatureId")
    public ResponseEntity queryBySignatureId(@RequestParam("id") String id) {
        CwProjectReportData projectReportData = projectReportService.queryBySignatureId ( id );
        return ResponseEntity.ok (projectReportData);
    }

    /**
     * 根据签章表id查询数据
     * @param id
     * @return
     */
    @ApiLog("根据签章表id查询数据")
    @PreAuthorize ("hasAnyAuthority('cwProjectReport:view','cwProjectReport:add','cwProjectReport:edit')")
    @GetMapping("findBySignatureId")
    public ResponseEntity findBySignatureId(@RequestParam("id") String id) {
        CwProjectReportSignature cwProjectReportSignature = projectReportService.findBySignatureId ( id );
        return ResponseEntity.ok (cwProjectReportSignature);
    }

    /**
     * 根据id修改签章表状态值status
     * @param data
     * @return
     */
    @ApiOperation(value = "根据id修改签章表状态值status")
    @PostMapping(value = "/updateSignatureStatusById")
    public ResponseEntity<String> updateSignatureStatusById(@RequestBody CwProjectReportSignatureDTO data) {
        String s = projectReportService.updateSignatureStatusById(data);
        return ResponseEntity.ok(s);
    }

    /**
     * 根据id修改签章表状态值status
     * @return
     */
    @ApiOperation(value = "根据id修改签章表状态值status")
    @PostMapping(value = "/aaa")
    public ResponseEntity<String> updateSignatureStatusById() {
        String s = "projectReportService.updateSignatureStatusById(data);";
        return ResponseEntity.ok(s);
    }



    /**
     * 导出分所报销数据
     * @param cwProjectReportData
     * @param page
     * @param response
     * @throws Exception
     */
    @ApiLog("导出报告数据信息")
    @GetMapping("export")
    @ApiOperation(value = "导出报告数据信息excel")
    public void exportFile(CwProjectReportData cwProjectReportData, Page <CwProjectReportData> page, ExcelOptions options, HttpServletResponse response) throws Exception {
        String fileName = options.getFilename ( );

        List<CwProjectReportData> result;
        if ( ExportMode.current.equals ( options.getMode ( ) ) ) {
            result = projectReportService.findList ( page, cwProjectReportData ).getRecords();
        } else if ( ExportMode.selected.equals ( options.getMode ( ) ) ) {
            result = projectReportService.findList ( page, cwProjectReportData ).getRecords().stream ( ).filter ( info ->
                    options.getSelectIds ( ).contains ( info.getId ( ) )
            ).collect ( Collectors.toList ( ) );
        } else {
            page.setSize ( -1 );
            page.setCurrent ( 0 );
            result = projectReportService.findList ( page, cwProjectReportData ).getRecords();
        }
        if(result.size()>0){
            for (CwProjectReportData info : result) {
//                if(StringUtils.isNotBlank(info.getStatus())){
//                    info.setStatus(DictUtils.getDictLabel(info.getStatus(), "cw_status", ""));
//                }
                if(StringUtils.isNotBlank(info.getReviewStatus())){
                    info.setReviewStatus(DictUtils.getDictLabel(info.getReviewStatus(), "cw_status", ""));
                }
                if ("1".equals(info.getSignatureType())) {
                    if(StringUtils.isNotBlank(info.getStatus1())){
                        info.setStatus1(DictUtils.getDictLabel(info.getStatus1(), "cw_status", ""));
                    }
                }
                if ("2".equals(info.getSignatureType())) {
                    if(StringUtils.isNotBlank(info.getStatus2())){
                        info.setStatus1(DictUtils.getDictLabel(info.getStatus2(), "cw_project_report_sign_status", ""));
                    }
                }
                if ("3".equals(info.getSignatureType())) {
                    if(StringUtils.isNotBlank(info.getStatus3())){
                        info.setStatus1(DictUtils.getDictLabel(info.getStatus3(), "cw_project_report_sign_status", ""));
                    }
                }

            }
        }
        EasyPoiUtil.exportExcel ( result, "报告信息",  options.getSheetName ( ), CwProjectReportData.class, fileName, response );
    }



    /**
     * 根据报告签章id查询签章审核节点信息
     * @param id
     * @return
     */
    @ApiLog("根据报告签章id查询签章审核节点信息")
    @GetMapping("getAuditNodeByReportId")
    public ResponseEntity getAuditNodeByReportId(@RequestParam("id") String id) {
        Map<String, Object> auditNodeByReportId = projectReportService.getAuditNodeByReportId(id);
        return ResponseEntity.ok (auditNodeByReportId);
    }



    /**
     * 根据报告签章id查询签章审核节点信息
     * @param id
     * @return
     */
    @ApiLog("根据报告签章id查询签章审核节点信息")
    @GetMapping("getSignatureTypeById")
    public ResponseEntity getSignatureTypeById(@RequestParam("id") String id,@RequestParam("signatureType") String signatureType) {
        Map<String, Object> signatureTypeById = projectReportService.getSignatureTypeById(id, signatureType);
        return ResponseEntity.ok (signatureTypeById);
    }

    /**
     * 根据客户id查询关联报告
     * @param clientId
     * @param cwProjectReport
     * @return
     * @throws Exception
     */
    @GetMapping("getIdByClientId")
    @ApiOperation(value = "根据客户id查询关联报告")
    public ResponseEntity<List<CwProjectReport>> getIdByClientId(String clientId, CwProjectReport cwProjectReport) throws Exception {
        List<CwProjectReport> cwProjectReportList = projectReportService.getIdByClientId(clientId, cwProjectReport);
        return ResponseEntity.ok(cwProjectReportList);
    }

    /**
     * 根据项目id查询关联报告
     * @param projectId
     * @param cwProjectReport
     * @return
     * @throws Exception
     */
    @GetMapping("getIdByProjectId")
    @ApiOperation(value = "根据项目id查询关联报告")
    public ResponseEntity<List<CwProjectReport>> getIdByProjectId(String projectId, CwProjectReport cwProjectReport) throws Exception {
        List<CwProjectReport> cwProjectReportList = projectReportService.getIdByProjectId(projectId, cwProjectReport);
        return ResponseEntity.ok(cwProjectReportList);
    }

    /**
     * 根据合同id查询关联报告
     * @param contractId
     * @param cwProjectReport
     * @return
     * @throws Exception
     */
    @GetMapping("getIdByContractId")
    @ApiOperation(value = "根据合同id查询关联报告")
    public ResponseEntity<List<CwProjectReport>> getIdByContractId(String contractId, CwProjectReport cwProjectReport) throws Exception {
        List<CwProjectReport> cwProjectReportList = projectReportService.getIdByContractId(contractId, cwProjectReport);
        return ResponseEntity.ok(cwProjectReportList);
    }

    /**
     * 生成报告归档信息
     * @param reportId
     * @return
     * @throws Exception
     */
    @GetMapping("saveReportArchive")
    @ApiOperation(value = "生成报告归档信息")
    public ResponseEntity saveReportArchive(String reportId) throws Exception {
        projectReportService.saveReportArchive(reportId);
        return ResponseEntity.ok("操作成功");
    }

    /**
     * 撤回签章
     * @param reportId
     * @return
     * @throws Exception
     */
    @GetMapping("rebackSign")
    @ApiOperation(value = "撤回签章")
    public ResponseEntity rebackSign(String reportId) throws Exception {
        projectReportService.rebackSign(reportId);
        return ResponseEntity.ok("操作成功");
    }
}
