package com.ruoyi.project.pssr.controller;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.ExcelUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.listener.pssr.ConfirmTaskCreateListener;
import com.ruoyi.project.pssr.domain.*;
import com.ruoyi.project.pssr.mapper.TPssrMaterialMapper;
import com.ruoyi.project.pssr.service.*;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.service.ISysUserService;
import org.activiti.engine.*;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

/**
 * 原料Controller
 *
 * @author ssy
 * @date 2024-09-18
 */
@RestController
@RequestMapping("/pssr/material")
public class TPssrMaterialController extends BaseController {
    @Autowired
    private ITPssrFileService tPssrFileService;

    @Autowired
    private ITPssrTurndownService tPssrTurndownService;
    @Autowired
    private ITPssrMaterialService tPssrMaterialService;

    @Autowired
    private ITPssrApproveService tPssrApproveService;

    @Autowired
    private ITPssrSubcontentService tPssrSubcontentService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private HistoryService historyService;
    @Resource
    private TPssrMaterialMapper tPssrMaterialMapper;

    @Autowired
    private ISysUserService sysUserService;
    private String forShort = "yfl";

    @Autowired
    private ITPssrMaterialRawService tPssrMaterialRawService;


    /**
     * 查询原料列表
     */
    @PreAuthorize("@ss.hasPermi('pssr:material:list')")
    @GetMapping("/list")
    public TableDataInfo list(TPssrMaterial tPssrMaterial) {
        try {
            TPssrApprove approve = tPssrApproveService.selectTPssrApproveBySubId(tPssrMaterial.getSubId());
            if (approve != null) {
                ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
                TaskService taskService = processEngine.getTaskService();
                Task task = processEngine.getTaskService()//获取任务service
                        .createTaskQuery()//创建查询对象
                        .taskAssignee(getUserId().toString())
                        .processInstanceId(approve.getProcessId()).singleResult();
                if (task != null) {
                    if (task.getName().equals("确认人1")){
                        tPssrMaterial.setConfirm1(getUserId().toString());
                    }else if (task.getName().equals("确认人2")){
                       tPssrMaterial.setConfirm2(getUserId().toString());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("待办确认人查询报错：{}",e.getMessage());
        }
        startPage();
        List<TPssrMaterial> list = tPssrMaterialService.selectTPssrMaterialList(tPssrMaterial);
        list.forEach(item -> {
            
            List<TPssrFile> tPssrFiles = tPssrFileService.selectTPssrFileListByItem(item.getSubId(), item.getId(), forShort);
            item.setFileList(tPssrFiles);
            item.setFileNum((long) tPssrFiles.size());
            if (item.getApproveStatus() != 2)
                item.setReason(tPssrTurndownService.selectTPssrTurndownByItem(item.getSubId(), item.getId(), "yfl"));
        });
        return getDataTable(list);
    }

    /**
     * 导出原料列表
     */
    @PreAuthorize("@ss.hasPermi('pssr:material:export')")
    @Log(title = "原料", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(TPssrMaterial tPssrMaterial) {
        List<TPssrMaterial> list1 = tPssrMaterialService.selectTPssrMaterialList(tPssrMaterial);
        TPssrMaterialRaw materialRaw = new TPssrMaterialRaw();
        materialRaw.setSubId(tPssrMaterial.getSubId());
        List<TPssrMaterialRaw> list2 = tPssrMaterialRawService.selectTPssrMaterialRawList(materialRaw);
        if (list1.size() != 0 && list2.size() != 0) {
            return AjaxResult.success(exportTmpl(list1, list2));
        } else {
            return AjaxResult.error("暂无可导出数据");
        }
    }

    public String exportTmpl(List<TPssrMaterial> list1, List<TPssrMaterialRaw> list2) {
        OutputStream out = null;
        String filename = null;
        try {
            String tempUrl = "static/word/pssr/yfl.xlsx"; // 模板文件
            InputStream is = null;
            is = Thread.currentThread().getContextClassLoader().getResourceAsStream(tempUrl);
            XSSFWorkbook wb = null;
            wb = new XSSFWorkbook(is);
            XSSFSheet sheet = wb.getSheetAt(0);

            // Cracker commissioning material quantity
            // 填充数据
            int rowIndex = 3;
            int num = 1;
            Row originalRow = sheet.getRow(3);
            Cell originalcell = originalRow.getCell(0);
            CellStyle originalStyle = originalcell.getCellStyle();
            CellStyle originalStyleCopy = wb.createCellStyle();
            originalStyleCopy.cloneStyleFrom(originalStyle);
            originalStyleCopy.setAlignment(HorizontalAlignment.LEFT);
            for (TPssrMaterial t : list1) {
                Row row = sheet.createRow(rowIndex);
                row.setHeight((short) 800);
                row.createCell(0).setCellValue(num);
                row.createCell(1).setCellValue(t.getUtilityQuantity());
                row.createCell(2).setCellValue(t.getQuantity());
                row.createCell(3).setCellValue(t.getUnit());
                row.createCell(4).setCellValue(t.getRemarks());
                //渲染样式
                for (int i = 0; i < 5; i++) {
                    row.getCell(i).setCellStyle(originalStyle);
                }
                num++;
                rowIndex++;
            }

            // Raw materials
            // 标题
            Row row = sheet.getRow(1);
            Cell cell = row.getCell(0);
            CellStyle style = cell.getCellStyle();
            Row title = sheet.createRow(rowIndex);
            title.setHeight((short) 800);
            title.createCell(0).setCellValue("Raw materials");
            title.createCell(1);
            title.createCell(2);
            title.createCell(3);
            title.createCell(4);
            for (int i = 0; i < 5; i++) {
                title.getCell(i).setCellStyle(style);
            }
            CellRangeAddress cellRangeAddress = new CellRangeAddress(rowIndex, rowIndex, 0, 4);
            sheet.addMergedRegion(cellRangeAddress);
            rowIndex++;

            Row row1 = sheet.getRow(2);
            Cell cell1 = row1.getCell(0);
            CellStyle style1 = cell1.getCellStyle();
            Row title1 = sheet.createRow(rowIndex);
            title1.setHeight((short) 800);
            title1.createCell(0).setCellValue("NO.");
            title1.createCell(1).setCellValue("Raw materials");
            title1.createCell(2).setCellValue("Quantity");
            title1.createCell(3).setCellValue("Unit");
            title1.createCell(4).setCellValue("Note");
            for (int i = 0; i < 5; i++) {
                title1.getCell(i).setCellStyle(style1);
            }
            rowIndex++;

            // 填充数据
            num = 1;
            for (TPssrMaterialRaw t2 : list2) {
                Row row2 = sheet.createRow(rowIndex);
                row2.setHeight((short) 800);
                row2.createCell(0).setCellValue(num);
                row2.createCell(1).setCellValue(t2.getRawMaterial());
                row2.createCell(2).setCellValue(t2.getQuantity());
                row2.createCell(3).setCellValue(t2.getUnit());
                row2.createCell(4).setCellValue(t2.getRemarks());
                //渲染样式
                for (int i = 0; i < 5; i++) {
                    row2.getCell(i).setCellStyle(originalStyle);
                }
                num++;
                rowIndex++;
            }

            // 备注
            Row title2 = sheet.createRow(rowIndex);
            title2.setHeight((short) 800);
            title2.createCell(0).setCellValue("1.  以上蒸汽裂解装置开车时所需要的物料经确认全部都已获得或具备获得条件，确认人签字。");
            title2.createCell(1);
            title2.createCell(2);
            title2.createCell(3);
            title2.createCell(4);
            for (int i = 0; i < 5; i++) {
                title2.getCell(i).setCellStyle(originalStyleCopy);
            }
            CellRangeAddress cellRangeAddress1 = new CellRangeAddress(rowIndex, rowIndex, 0, 4);
            sheet.addMergedRegion(cellRangeAddress1);
            rowIndex++;
            Row title3 = sheet.createRow(rowIndex);
            title3.setHeight((short) 800);
            title3.createCell(0).setCellValue("2.  如果某些物料没有获得或不具备获得条件，请及时联系相关责任人按要求进行整改。");
            title3.createCell(1);
            title3.createCell(2);
            title3.createCell(3);
            title3.createCell(4);
            for (int i = 0; i < 5; i++) {
                title3.getCell(i).setCellStyle(originalStyleCopy);
            }
            CellRangeAddress cellRangeAddress2 = new CellRangeAddress(rowIndex, rowIndex, 0, 4);
            sheet.addMergedRegion(cellRangeAddress2);
            rowIndex++;

            // 确认人
            Row title4 = sheet.createRow(rowIndex);
            title4.setHeight((short) 800);
            title4.createCell(0);
            title4.createCell(1);
            title4.createCell(2);
            title4.createCell(3).setCellValue("确认人：");
            title4.createCell(4);
            try {
                if (list1.size() != 0) {
                    SysUser sysUser = sysUserService.selectUserById(Long.valueOf(list1.get(0).getConfirm1()));
                    String confirm = sysUser.getSignUrl();
                    ExcelUtils.insertPicture(wb, sheet, confirm, rowIndex, 4, 0.25, 1);
                }
            } catch (Exception e) {
            }
            for (int i = 0; i < 5; i++) {
                title4.getCell(i).setCellStyle(originalStyleCopy);
            }
            rowIndex++;

            // 确认时间
            Row title5 = sheet.createRow(rowIndex);
            title5.setHeight((short) 800);
            title5.createCell(0);
            title5.createCell(1);
            title5.createCell(2);
            title5.createCell(3).setCellValue("确认时间：");
            if (list1.size() != 0) {
                title5.createCell(4).setCellValue(DateUtils.dateTime(list1.get(0).getConfirmationDate()));
                for (int i = 0; i < 5; i++) {
                    title5.getCell(i).setCellStyle(originalStyleCopy);
                }
            }
            rowIndex++;

            filename = "PSSR_19_原辅料" + ".xlsx";
            out = new FileOutputStream(ExcelUtil.getAbsoluteFile(filename));
            wb.write(out);
            wb.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return filename;
    }

    /**
     * 获取原料详细信息
     */
    @PreAuthorize("@ss.hasPermi('pssr:material:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        TPssrMaterial item = tPssrMaterialService.selectTPssrMaterialById(id);
        
            List<TPssrFile> tPssrFiles = tPssrFileService.selectTPssrFileListByItem(item.getSubId(), item.getId(), forShort);
            item.setFileList(tPssrFiles);
            item.setFileNum((long) tPssrFiles.size());
        if (item.getApproveStatus() != 2)
            item.setReason(tPssrTurndownService.selectTPssrTurndownByItem(item.getSubId(), item.getId(), "yfl"));
        return AjaxResult.success(item);
    }

    /**
     * 新增原料
     */
    @PreAuthorize("@ss.hasPermi('pssr:material:add')")
    @Log(title = "原料", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody TPssrMaterial tPssrMaterial) {
        if (StringUtils.isNotEmpty(tPssrMaterial.getConfirm1()) && tPssrMaterial.getConfirm1().equals(tPssrMaterial.getConfirm2())) {
            return AjaxResult.error("确认人不能为同一人，请重新选择！");
        }
        return toAjax(tPssrMaterialService.insertTPssrMaterial(tPssrMaterial));
    }

    /**
     * 修改原料
     */
    @PreAuthorize("@ss.hasPermi('pssr:material:edit')")
    @Log(title = "原料", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody TPssrMaterial tPssrMaterial) {
        TPssrMaterial entity = tPssrMaterialService.selectTPssrMaterialById(tPssrMaterial.getId());
        if (entity.getApproveStatus() != 1 && entity.getApproveStatus() != 0) {
            return  AjaxResult.error("当前状态不可修改！");
        }
        if (tPssrMaterial.getConfirm1().equals(tPssrMaterial.getConfirm2())) {
            return AjaxResult.error("确认人不能为同一人，请重新选择！");
        }
        tPssrFileService.updateFileRelevance(tPssrMaterial.getFileIds(), "yfl", tPssrMaterial.getId(), tPssrMaterial.getSubId());
        return toAjax(tPssrMaterialService.updateTPssrMaterial(tPssrMaterial));
    }

    /**
     * 修改原料
     */
    @PreAuthorize("@ss.hasPermi('pssr:material:edit')")
    @Log(title = "原料", businessType = BusinessType.UPDATE)
    @PutMapping("editBatch")
    public AjaxResult editBatch(@RequestBody TPssrMaterial tPssrMaterial) {
        if (tPssrMaterial.getConfirm1().equals(tPssrMaterial.getConfirm2())) {
            return AjaxResult.error("确认人不能为同一人，请重新选择！");
        }
        return toAjax(tPssrMaterialMapper.updateTPssrMaterialByIds(tPssrMaterial));
    }

    /**
     * 删除原料
     */
    @PreAuthorize("@ss.hasPermi('pssr:material:remove')")
    @Log(title = "原料", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(tPssrMaterialService.deleteTPssrMaterialByIds(ids));
    }


    /**
     * 确认人身防护
     */
    @PreAuthorize("@ss.hasPermi('pssr:material:edit')")
    @Log(title = "人身防护", businessType = BusinessType.UPDATE)
    @PutMapping("/confirmMaterial")
    public AjaxResult confirmMaterial(@RequestBody TPssrMaterial tPssrMaterial) {
        Date date = null;
        TPssrMaterial material = new TPssrMaterial();
        if (tPssrMaterial.getIds() != null && tPssrMaterial.getIds().length > 0) {
            for (Long id : tPssrMaterial.getIds()) {
                material = tPssrMaterialService.selectTPssrMaterialById(id);
                material.setConfirmationDate(new Date());
                material.setApproveStatus(2L);
                material.setUpdatedate(new Date());
                material.setUpdaterCode(String.valueOf(getUserId()));
                tPssrMaterialService.updateTPssrMaterial(material);
            }
        } else {
            material.setSubId(tPssrMaterial.getSubId());
            material.setApproveStatus(1L);
            material.setConfirm1(getUserId().toString());
            for (TPssrMaterial item : tPssrMaterialService.selectTPssrMaterialList(material)) {
                item.setConfirmationDate(new Date());
                item.setApproveStatus(2L);
                item.setUpdatedate(new Date());
                item.setUpdaterCode(String.valueOf(getUserId()));
                tPssrMaterialService.updateTPssrMaterial(item);
            }
        }
        //查询当前待审批的确认人
        TPssrMaterial entity = new TPssrMaterial();
        entity.setSubId(tPssrMaterial.getSubId());
        entity.setApproveStatus(1L);
        TPssrMaterial Material = tPssrMaterialService.selectAllConfirmedPersonBySubId(entity);
        if (Material != null) {
            //如果当前用户还有待审批任务
            if (Material.getConfirm1().contains(getUserId().toString())) {
                return AjaxResult.success();
            }
        }
        //无待审批任务结束当前用户流程

        // 因为流程关系所以approve一定会有且只有一条数据
        TPssrApprove tPssrApprove = tPssrApproveService.selectTPssrApproveBySubId(tPssrMaterial.getSubId());
        TPssrApproveController.handleConfirmApprove(tPssrApprove, getUserId().toString());
        return AjaxResult.success();
    }


    /**
     * 驳回人身防护
     */
    @PutMapping("/turnDownMaterial")
    public AjaxResult turnDownMaterial(@RequestBody List<TPssrMaterial> tPssrMaterial) {
        if (CollectionUtils.isNotEmpty(tPssrMaterial)) {
            String userId = getUserId().toString();
            Long subId = tPssrMaterial.get(0).getSubId();
            // 修改已选择数据的状态
            for (TPssrMaterial item : tPssrMaterial) {
                TPssrMaterial blind = new TPssrMaterial();
                blind.setId(item.getId());
                blind.setApproveStatus(1L);
                blind.setUpdatedate(new Date());
                blind.setUpdaterCode(getUserId().toString());
                tPssrMaterialService.updateTPssrMaterial(blind);
                // 新增驳回原因数据
                TPssrTurndown turndown = new TPssrTurndown();
                turndown.setForShort(forShort);
                turndown.setSubId(item.getSubId());
                turndown.setItemId(item.getId());
                turndown.setReason(item.getReason());
                turndown.setCreatedate(new Date());
                turndown.setCreaterCode(getUserId().toString());
                tPssrTurndownService.insertTPssrTurndown(turndown);
            }
            // 查询当前流程
            TPssrApprove approve = tPssrApproveService.selectTPssrApproveBySubId(subId);

            try {
                runtimeService.deleteProcessInstance(approve.getProcessId(), "pssr1confirm");
                historyService.deleteHistoricProcessInstance(approve.getProcessId());
            } catch (Exception e) {
                logger.info("无运行时流程");
            }

            // 驳回 查询所有待审批的人员
            // 查询确认人
            TPssrMaterial entity = new TPssrMaterial();
            entity.setSubId(subId);
            entity.setApproveStatus(1L);
            TPssrMaterial PssrMaterial = tPssrMaterialService.selectAllConfirmedPersonBySubId(entity);
            String confirmer1s = null;
            if (PssrMaterial != null) {
                confirmer1s = PssrMaterial.getConfirm1();
            }
            logger.info("=======================confirmer1s:{}", confirmer1s);

            Set<String> confirmerUsers1 = new HashSet<>();
            if (StringUtils.isNotEmpty(confirmer1s)) {
                confirmerUsers1.addAll(Arrays.asList(confirmer1s.split(",")));
            }

            // 开始申请流程
            long businessKey = approve.getApproveId();
            //开始工作流、监听
            Authentication.setAuthenticatedUserId(userId);//设置当前申请人
            Map<String, Object> variables = new HashMap<>();
            variables.put("applyUser", userId);
            variables.put("confirmUsers", new ArrayList<>(confirmerUsers1));
            variables.put("confirmTaskCreateListener", new ConfirmTaskCreateListener());//发送邮件
            variables.put("chargePerson", approve.getSubCharge());
            //采用key来启动流程定义并设置流程变量，返回流程实例
            ProcessInstance pi = runtimeService.startProcessInstanceByKey("pssr1confirm", String.valueOf(businessKey), variables);

            // 修改审批表和sub表
            approve.setProcessId(pi.getProcessInstanceId());
            approve.setApproveStatus(1L);
            approve.setUpdatedate(new Date());
            approve.setUpdaterCode(getUserId().toString());
            tPssrApproveService.updateTPssrApprove(approve);

            TPssrSubcontent subcontent = new TPssrSubcontent();
            subcontent.setId(approve.getSubId());
            subcontent.setApproveStatus(1L);
            subcontent.setUpdatedate(new Date());
            subcontent.setUpdaterCode(getUserId().toString());
            tPssrSubcontentService.updateTPssrSubcontent(subcontent);
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }
}
