package com.jeeplus.psimanage.collect.controller;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.common.excel.EasyExcelUtils;
import com.jeeplus.common.excel.ExcelOptions;
import com.jeeplus.common.excel.annotation.ExportMode;
import com.jeeplus.common.utils.ResponseUtil;
import com.jeeplus.flowable.feign.IFlowableApi;
import com.jeeplus.logging.annotation.ApiLog;
import com.jeeplus.logging.constant.enums.LogTypeEnum;
import com.jeeplus.psimanage.collect.domain.PsiCollectBasicsReturnHi;
import com.jeeplus.psimanage.collect.domain.PsiCollectDetailedRecord;
import com.jeeplus.psimanage.collect.mapper.PsiCollectDetailedRecordMapper;
import com.jeeplus.psimanage.collect.service.PsiCollectService;
import com.jeeplus.psimanage.collect.service.dto.*;
import com.jeeplus.sys.feign.IUserApi;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.flowable.bpmn.model.FlowNode;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: 王强
 * @create: 2023-01-03 16:18
 **/
@RestController
@Api(tags ="物资管理-领用申请")
@RequestMapping(value = "/psi/collect")
public class PsiCollectController {

    private static final String COLLECT_EXPORT_TEMPLATE = "dot/领用申请单.xlsx";

    @Resource
    private PsiCollectService psiCollectService;

    @Resource
    private PsiCollectDetailedRecordMapper psiCollectDetailedRecordMapper;



    /**
     * 根据id修改状态status
     */
    @ApiOperation(value = "根据id修改状态status")
    @PostMapping(value = "updateStatusById")
    public void updateStatusById(@RequestBody PsiCollectDto dto) {
        psiCollectService.updateStatusById(dto);
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @ApiOperation(value = "删除")
    @GetMapping("/remove")
    public ResponseEntity<String> remove(@RequestParam String id){
        String s = psiCollectService.remove(id);
        return ResponseEntity.ok(s);
    }

    /**
     * 新增/修改
     * @param dto
     * @return
     */
    @ApiOperation(value = "新增、修改")
    @PostMapping("/save")
    public ResponseEntity<String> save(@RequestBody PsiCollectDto dto) throws Exception{
        String s = psiCollectService.save(dto);
        return ResponseUtil.newInstance().add("businessTable", "psi_management_collect_basics").add("businessId", s).ok ("操作成功");
    }

    /**
     * 查询
     * @param id
     * @return
     */
    @ApiOperation(value = "查询")
    @GetMapping("/findById")
    public ResponseEntity<PsiCollectDto> findById(@RequestParam String id) throws Exception{
        PsiCollectDto dto = psiCollectService.findById(id);
        return ResponseEntity.ok(dto);
    }

    /**
     * 列表查询
     * @param dto
     * @return
     */
    @ApiOperation(value = "列表查询")
    @GetMapping("/list")
    public ResponseEntity<IPage<PsiCollectDto>> list(Page<PsiCollectDto> page, PsiCollectDto dto) throws Exception{
        IPage<PsiCollectDto> iPage = psiCollectService.list(page, dto);
        return ResponseEntity.ok(iPage);
    }

    @ApiLog(value = "导出领用数据", type = LogTypeEnum.EXPORT)
    @ApiOperation(value = "导出领用数据")
    @GetMapping("/exportFile")
    public void exportFile(Page<PsiCollectDto> page, PsiCollectDto dto, ExcelOptions options, HttpServletResponse response) throws Exception{
        String fileName = StringUtils.isBlank(options.getFilename()) ? "领用申请单" : options.getFilename();
        String sheetName = options.getSheetName();
        List<PsiCollectExportDto> result;
        if (ExportMode.current.equals(options.getMode())) {
            result = psiCollectService.exportRecordList(page, dto);
        } else if (ExportMode.selected.equals(options.getMode())) {
            result = psiCollectService.exportRecordList(page, dto).stream().filter(item ->
                    options.getSelectIds().contains(item.getId())
            ).collect(Collectors.toList());
        } else {
            page.setSize(-1);
            page.setCurrent(0);
            result = psiCollectService.exportRecordList(page, dto);
        }
        EasyExcelUtils.newInstance().exportExcel(result, sheetName, PsiCollectExportDto.class, fileName, null, response);
    }

    @ApiLog(value = "导出单条领用数据单", type = LogTypeEnum.EXPORT)
    @ApiOperation(value = "导出单条领用数据单")
    @GetMapping("/exportFileByTemplate")
    public void exportFileByTemplate(PsiCollectDto dto, ExcelOptions options, HttpServletResponse response) throws Exception{
        String fileName = options.getFilename();
        //获取领用数据
        PsiCollectDto byId = psiCollectService.exportFileByTemplate(dto);
        List<PsiCollectExportTemplateDto> result = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<PsiCollectDetailedRecord> recordList = byId.getRecordList();
        recordList.forEach(record -> {
            PsiCollectExportTemplateDto exportDto = new PsiCollectExportTemplateDto();
            exportDto.setId(byId.getId());
            exportDto.setCollectNo(byId.getCollectNo());
            exportDto.setRecipientAgent(record.getRecipientAgent());
            exportDto.setRecipientOffice(record.getRecipientOffice());
            exportDto.setCollectType(record.getCollectType());
            exportDto.setGoodsName(record.getGoodsName());
            exportDto.setCollectNumber(psiCollectService.formatExportNumber(record.getCollectNumber()));
            exportDto.setCompany(record.getCompany());
            exportDto.setDetailRemarks(record.getRemarks());
            exportDto.setCollectDate(byId.getCollectDate() == null ? "" : dateFormat.format(byId.getCollectDate()));
            result.add(exportDto);
        });
        //获取流程审核信息
        Map map = SpringUtil.getBean(IFlowableApi.class).historicTaskList2(byId.getProcInsId());
        Map<String, Object> data = new HashMap<>();
        //领用单基本信息
        data.put("collectDate", byId.getCollectDate() == null ? "" : dateFormat.format(byId.getCollectDate()));
        data.put("collectNo", byId.getCollectNo());
        data.put("handledByName", StringUtils.isNotBlank(byId.getHandledByName()) ? byId.getHandledByName() : byId.getHandledBy());
        data.put("handledByOfficeName", byId.getHandledByOfficeName());
        data.put("remarks", byId.getRemarks());
        //审批信息
        if(map != null){
            String status = String.valueOf(map.get("status"));
            String firstAuditName = String.valueOf(map.get("firstAuditName"));
            String auditTime = String.valueOf(map.get("auditTime"));
            if(status.equals("同意")){
                data.put("status","已同意");
            }else{
                data.put("status","");
            }
            data.put("auditUser",firstAuditName);
            data.put("auditTime",auditTime);
        }
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        ClassPathResource templateResource = new ClassPathResource(COLLECT_EXPORT_TEMPLATE);
        if (!templateResource.exists()) {
            throw new FileNotFoundException("Excel模板不存在：" + COLLECT_EXPORT_TEMPLATE);
        }

        try (InputStream templateInputStream = templateResource.getInputStream()) {
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
                    .withTemplate(templateInputStream)
                    .build();
            try {
                WriteSheet writeSheet = EasyExcel.writerSheet().build();
                FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
                excelWriter.fill(data, writeSheet);
                //列表信息
                excelWriter.fill(new FillWrapper("collectList", result), fillConfig, writeSheet);
            } finally {
                excelWriter.finish();
            }
        }
    }

    /**
     * 商品入库信息列表查询
     * @param dto
     * @return
     */
    @ApiOperation(value = "获取领用单图片模板数据")
    @GetMapping("/templateImageData")
    public ResponseEntity<PsiCollectTemplateImageDto> templateImageData(PsiCollectDto dto) throws Exception{
        PsiCollectDto byId = psiCollectService.exportFileByTemplate(dto);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        PsiCollectTemplateImageDto templateData = new PsiCollectTemplateImageDto();
        templateData.setCollectDate(byId.getCollectDate() == null ? "" : dateFormat.format(byId.getCollectDate()));
        templateData.setCollectNo(byId.getCollectNo());
        templateData.setHandledByName(StringUtils.isNotBlank(byId.getHandledByName()) ? byId.getHandledByName() : byId.getHandledBy());
        templateData.setHandledByOfficeName(byId.getHandledByOfficeName());
        templateData.setRemarks(byId.getRemarks());

        List<PsiCollectDetailedRecord> recordList = byId.getRecordList();
        if (recordList != null) {
            recordList.forEach(record -> {
                PsiCollectExportTemplateDto exportDto = new PsiCollectExportTemplateDto();
                exportDto.setId(byId.getId());
                exportDto.setCollectNo(byId.getCollectNo());
                exportDto.setRecipientAgent(record.getRecipientAgent());
                exportDto.setRecipientOffice(record.getRecipientOffice());
                exportDto.setCollectType(record.getCollectType());
                exportDto.setGoodsName(record.getGoodsName());
                exportDto.setCollectNumber(psiCollectService.formatExportNumber(record.getCollectNumber()));
                exportDto.setCompany(record.getCompany());
                exportDto.setDetailRemarks(record.getRemarks());
                exportDto.setCollectDate(templateData.getCollectDate());
                templateData.getCollectList().add(exportDto);
            });
        }

        Map map = SpringUtil.getBean(IFlowableApi.class).historicTaskList2(byId.getProcInsId());
        if (map != null) {
            String message = String.valueOf(map.get("message"));
            templateData.setStatusMessage(StringUtils.isNotBlank(message) ? message : "已同意");
            templateData.setAuditUser(safeString(map.get("firstAuditName")));
            templateData.setAuditTime(safeString(map.get("auditTime")));
        } else {
            templateData.setStatusMessage("已同意");
            templateData.setAuditUser("");
            templateData.setAuditTime("");
        }
        return ResponseEntity.ok(templateData);
    }

    private String safeString(Object value) {
        return value == null || "null".equals(String.valueOf(value)) ? "" : String.valueOf(value);
    }

    @ApiOperation(value = "\u5546\u54c1\u5165\u5e93\u4fe1\u606f\u5217\u8868\u67e5\u8be2")
    @GetMapping("/wareHouseList")
    public ResponseEntity<IPage<PsiWareHouseSummaryDto>> wareHouseList(Page<PsiWareHouseSummaryDto> page, PsiWareHouseSummaryDto dto) throws Exception{
        IPage<PsiWareHouseSummaryDto> iPage = psiCollectService.wareHouseList(page, dto);
        return ResponseEntity.ok(iPage);
    }

    /**
     * 创建领用退回流程表数据
     * @param dto
     * @return
     */
    @ApiOperation(value = "创建领用退回流程表数据")
    @PostMapping("/createReturnData")
    public ResponseEntity<Map<String,String>> createReturnData(@RequestBody PsiCollectDto dto) throws Exception{
        String returnId = psiCollectService.createReturnData(dto.getId());
        Map<String,String> res = new HashMap<String,String>();
        res.put("returnId", returnId);
        return ResponseEntity.ok(res);
    }

    /**
     * 领用-退回  发起
     * @param dto
     * @return
     */
    @ApiOperation(value = "领用-退回  发起")
    @PostMapping("/saveReturn")
    public ResponseEntity saveReturn(@RequestBody PsiCollectDto dto) throws Exception{
        String businessId = psiCollectService.saveReturn(dto);
        if (StringUtils.isNotBlank(businessId)) {
            return ResponseUtil.newInstance().add("businessTable", "psi_management_collect_basics_return").add("businessId", businessId).ok ("操作成功");
        } else {
            return ResponseEntity.badRequest().body("操作失败");
        }
    }

    /**
     * 领用-退回  同意
     * @param dto
     * @return
     */
    @ApiOperation(value = "领用-退回  同意")
    @PostMapping("/saveReturnAgree")
    public ResponseEntity saveReturnAgree(@RequestBody PsiCollectDto dto) throws Exception{
        String s = psiCollectService.saveReturnAgree(dto);
        return ResponseUtil.newInstance().add("businessTable", "psi_management_collect_basics_return").add("businessId", s).ok ("操作成功");
    }

    /**
     * 领用-退回流程修改状态
     * @param dto
     * @return
     */
    @ApiOperation(value = "领用-退回流程修改状态")
    @PostMapping("/updateStatusByIdReturn")
    public ResponseEntity updateStatusByIdReturn(@RequestBody PsiCollectDto dto) throws Exception{
        psiCollectService.updateStatusByIdReturn(dto.getId(), dto.getStatus());
        return ResponseEntity.ok("修改完成");
    }

    /**
     * 查询
     * @param returnId
     * @return
     */
    @ApiOperation(value = "查询")
    @GetMapping("/findByReturnId")
    public ResponseEntity<PsiCollectDto> findByReturnId(@RequestParam String returnId) throws Exception{
        PsiCollectDto dto = psiCollectService.findByReturnId(returnId);
        return ResponseEntity.ok(dto);
    }

    /**
     * 取消领用退回
     * @param dto
     * @return
     */
    @ApiOperation(value = "取消领用退回")
    @PostMapping("/returnRequest")
    public ResponseEntity returnRequest(@RequestBody PsiCollectDto dto) throws Exception{
        psiCollectService.returnRequest(dto.getId());
        return ResponseEntity.ok("操作完成");
    }

    /**
     * 根据领用表id查询其全部历史修改数据
     * @return
     */
    @ApiOperation(value = "根据领用表id查询其全部历史修改数据")
    @GetMapping("/findHiById")
    public ResponseEntity findHiById(@RequestParam String collectId) {
        List<PsiCollectBasicsReturnHi> hiById = psiCollectService.findHiById(collectId);
        return ResponseEntity.ok(hiById);
    }

    /**
     * 根据历史表id查询历史表数据
     * @param id
     * @return
     */
    @ApiOperation(value = "根据历史表id查询历史表数据")
    @GetMapping("/findHiByHiId")
    public ResponseEntity findHiByHiId(@RequestParam String id) throws Exception {
        PsiCollectDto hi = psiCollectService.findHiByHiId(id);
        return ResponseEntity.ok(hi);
    }

    /**
     * 根据领用表id查询最近的一个修改历史
     * @param collectId
     * @return
     */
    @ApiOperation(value = "根据领用表id查询最近的一个修改历史")
    @GetMapping("/findLastHiByid")
    public ResponseEntity findLastHiByid(@RequestParam String collectId) {
        PsiCollectDto hi = psiCollectService.findLastHiByid(collectId);
        return ResponseEntity.ok(hi);
    }

    @ApiOperation(value = "用户树形")
    @GetMapping(value = "/userTree")
    public ResponseEntity<List<TreeUserDto>> userTree(@RequestParam String name) {
        List<TreeUserDto> list = psiCollectService.userTree(name);
        return ResponseEntity.ok(list);
    }
}
