package com.ruoyi.project.pssr.controller;

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.*;
import com.deepoove.poi.data.style.Style;
import com.deepoove.poi.data.style.TableStyle;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.config.RuoYiConfig;
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.officeConvert.OfficeConvertController;
import com.ruoyi.project.pssr.domain.TPssrAboveall;
import com.ruoyi.project.pssr.domain.TPssrApprove;
import com.ruoyi.project.pssr.domain.TPssrContentModel;
import com.ruoyi.project.pssr.domain.TPssrSubcontent;
import com.ruoyi.project.pssr.service.ITPssrAboveallService;
import com.ruoyi.project.pssr.service.ITPssrApproveService;
import com.ruoyi.project.pssr.service.ITPssrContentModelService;
import com.ruoyi.project.pssr.service.ITPssrSubcontentService;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.service.impl.SysUserServiceImpl;
import io.jsonwebtoken.lang.Assert;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.apache.commons.collections4.CollectionUtils;
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.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 开车条件确认Controller
 *
 * @author ssy
 * @date 2024-09-18
 */
@RestController
@RequestMapping("/pssr/subcontent")
public class TPssrSubcontentController extends BaseController {
    @Autowired
    private ITPssrSubcontentService tPssrSubcontentService;
    @Autowired
    private ITPssrAboveallService tPssrAboveallService;
    @Autowired
    private ITPssrApproveService tPssrApproveService;
    @Autowired
    private SysUserServiceImpl sysUserService;
    @Autowired
    private TPssrApproveController tPssrApproveController;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private TaskService taskService;
    @Resource
    private OfficeConvertController officeConvertController;
    @Autowired
    private ITPssrContentModelService tPssrContentModelService;

    /**
     * 查询开车条件确认列表
     */
    @PreAuthorize("@ss.hasPermi('pssr:subcontent:list')")
    @GetMapping("/list")
    public TableDataInfo list(TPssrSubcontent tPssrSubcontent) {
        if (tPssrSubcontent.getTaskType() != null && tPssrSubcontent.getTaskType() == 1) {
            Long userId = getUserId();
            TPssrAboveall aboveall = tPssrAboveallService.selectTPssrAboveallById(tPssrSubcontent.getAboveallId());
            if (userId.equals(aboveall.getPlantMgr())) {
                tPssrSubcontent.setDeptUnit("Production");
            } else if (userId.equals(aboveall.getCtmMgr())) {
                tPssrSubcontent.setDeptUnit("CTM");
            } else if (userId.equals(aboveall.getCtaMgr())) {
                tPssrSubcontent.setDeptUnit("CTA");
            }
        }
        startPage();
        List<TPssrSubcontent> list = tPssrSubcontentService.selectTPssrSubcontentList(tPssrSubcontent);
        return getDataTable(list);
    }

    /**
     * 导出开车条件确认列表
     */
    @PreAuthorize("@ss.hasPermi('pssr:subcontent:export')")
    @Log(title = "开车条件确认", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(TPssrSubcontent tPssrSubcontent) throws IOException {
        List<TPssrSubcontent> list = tPssrSubcontentService.selectTPssrSubcontentList(tPssrSubcontent);

        Set<String> exists = list.stream().map(TPssrSubcontent::getSerialNumber).collect(Collectors.toSet());
        List<TPssrContentModel> models = tPssrContentModelService.selectTPssrContentModelList(new TPssrContentModel());
        List<TPssrContentModel> noExists = models.stream().filter(model -> !exists.contains(model.getSerialNumber())).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(noExists)) {
            for (TPssrContentModel noExist : noExists) {
                TPssrSubcontent subcontent = new TPssrSubcontent();
                subcontent.setConfirm1Name("NA");
                subcontent.setConfirm2Name("NA");
                subcontent.setConfirmName("NA");
                subcontent.setRemarks("NA");
                subcontent.setApproveStatus(99L);
                subcontent.setAboveallId(tPssrSubcontent.getAboveallId());
                subcontent.setDeptUnit(noExist.getDeptUnit());
                subcontent.setSerialNumber(noExist.getSerialNumber());
                subcontent.setItem(noExist.getItem());
                subcontent.setContent(noExist.getContent());
                list.add(subcontent);
            }
            list.sort(Comparator.comparing(TPssrSubcontent::getSerialNumber));
        }
//        ExcelUtil<TPssrSubcontent> util = new ExcelUtil<TPssrSubcontent>(TPssrSubcontent.class);
//        return util.exportExcel(list, "subcontent");

        //渲染文本
        Map<String, Object> params = getWordData(list, tPssrSubcontent.getAboveallId());
        // 模板路径
        String templatePath = "static/word/pssr/pssrConfirm.docx";
        // 生成word的路径
        String fileDir = RuoYiConfig.getProfile() + "/" + "pssr";
        // 生成word的文件名称
        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss"));
        String fileName = time + tPssrSubcontent.getAboveallId() + "_" + DateUtils.getDate() + ".docx";
        String wordPath = createWord(templatePath, fileDir, fileName, params, "pssr");
        return AjaxResult.success(officeConvertController.wordTransPdf(wordPath));

    }

    public Map<String, Object> getWordData(List<TPssrSubcontent> list, Long aboveallId) {
        TPssrApprove approve = null;
        TPssrAboveall aboveall = tPssrAboveallService.selectTPssrAboveallById(aboveallId);
        Map<String, Object> params = new HashMap<>();
        TableRenderData tableRenderData = new TableRenderData();

        TableStyle tableStyle = new TableStyle();
        tableStyle.setWidth("100%");
        tableStyle.setColWidths(new int[]{10, 13, 47, 10, 10, 10});
        tableRenderData.setTableStyle(tableStyle);

        // 创建表头行
        RowRenderData row1 = Rows.of("部门", "项目", "内容", "确认人", "确认时间", "备注").center().textBold().rowExactHeight(1.1f).create();
        tableRenderData.addRow(row1);

        int plant = 0, ctm = 0, cta = 0, count = 1;
        PictureRenderData plantMgr = null;

        for (int i = 0; i < list.size(); i++) {
            TPssrSubcontent subcontent = list.get(i);

            // 获取审批信息
            if (approve == null) {
                approve = tPssrApproveService.selectTPssrApproveByAboveallId(subcontent.getAboveallId());
            }

            // 创建数据行
            RowRenderData row = Rows.of(subcontent.getDeptUnit(), subcontent.getItem(), subcontent.getContent(), subcontent.getApproveStatus() == 99 ? "NA" : "",  // 如果需要确认人签名图片，这里空着
                    subcontent.getApproveStatus() != 99 ? DateUtils.dateTime(subcontent.getConfirmationDate()) : "NA", subcontent.getRemarks()).verticalCenter().rowExactHeight(1.1f).create();


            // 如果确认状态为2，插入确认人签名图片
            if (subcontent.getApproveStatus() == 2) {
                SysUser sysUser = sysUserService.selectUserById(Long.valueOf(subcontent.getConfirm()));
                if (sysUser != null) {
                    row.getCells().set(3, new CellRenderData().addParagraph(new ParagraphRenderData().addPicture(Pictures.ofLocal(FileUtils.fileName(sysUser.getSignUrl())).size(110, 30).create())));
                }
            }

            tableRenderData.addRow(row);

            // 判断所属部门是否相同，记录索引
            if (subcontent.getDeptUnit().equals("Production")) plant = count;
            if (subcontent.getDeptUnit().equals("CTM")) ctm = count;
            if (subcontent.getDeptUnit().equals("CTA")) cta = count;

            // 判断是否为最后一条或部门是否不相同
            if (i < list.size() - 1 && subcontent.getDeptUnit().equals(list.get(i + 1).getDeptUnit())) {
                count++;
            } else {
                count++;
                //根据当前数据所属部门添加经理审批行
                RowRenderData signRow = Rows.of("", "装置经理确认：                    日期：", "", "", "", "").verticalCenter().textBold().rowExactHeight(1.1f).create();
                if (subcontent.getDeptUnit().equals("Production")) {
                    plant = count;
                    signRow = Rows.of("", "装置经理确认：                    日期：", "", "", "", "").verticalCenter().textBold().rowExactHeight(1.1f).create();
                }
                if (subcontent.getDeptUnit().equals("CTM")) {
                    ctm = count + 1;
                    signRow = Rows.of("", "CTM 经理确认：                    日期：", "", "", "", "").verticalCenter().textBold().rowExactHeight(1.1f).create();
                }
                if (subcontent.getDeptUnit().equals("CTA")) {
                    if (ctm == 0) {
                        cta = count + 1;
                    } else {
                        cta = count + 2;
                    }
                    signRow = Rows.of("", "CTA 经理确认：                    日期：", "", "", "", "").verticalCenter().textBold().rowExactHeight(1.1f).create();
                }
                // 添加经理审批签字数据
                if (approve != null) {
                    SysUser sysUser = null;
                    //根据当前所属部门查询部门经理
                    if (subcontent.getDeptUnit().equals("Production")) {
                        sysUser = sysUserService.selectUserById(Long.valueOf(aboveall.getPlantMgr()));
                        plantMgr = Pictures.ofLocal(FileUtils.fileName(sysUser.getSignUrl())).size(110, 30).create();
                    }
                    if (subcontent.getDeptUnit().equals("CTM")) {
                        sysUser = sysUserService.selectUserById(Long.valueOf(aboveall.getCtmMgr()));
                    }
                    if (subcontent.getDeptUnit().equals("CTA")) {
                        sysUser = sysUserService.selectUserById(Long.valueOf(aboveall.getCtaMgr()));
                    }
                    if (sysUser != null) {
                        //经理签字图片
                        PictureRenderData mgr = Pictures.ofLocal(FileUtils.fileName(sysUser.getSignUrl())).size(110, 30).create();
                        //空数据列，为了后面合并
                        TextRenderData text = Texts.of("").create();
                        CellRenderData cell = new CellRenderData();
                        cell.addParagraph(new ParagraphRenderData().addText(text));
                        //数据列，该列内容为经理签字和日期
                        CellRenderData cell2 = new CellRenderData();
                        if (subcontent.getDeptUnit().equals("Production"))
                            cell2.addParagraph(new ParagraphRenderData().addText(Texts.of("装置经理确认：").create()).addPicture(mgr).addText("         日期：" + DateUtils.dateTime(aboveall.getConfirmationDate())));
                        if (subcontent.getDeptUnit().equals("CTM"))
                            cell2.addParagraph(new ParagraphRenderData().addText(Texts.of("CTM 经理确认：").create()).addPicture(mgr).addText("         日期：" + DateUtils.dateTime(aboveall.getConfirmationDate())));
                        if (subcontent.getDeptUnit().equals("CTA"))
                            cell2.addParagraph(new ParagraphRenderData().addText(Texts.of("CTA 经理确认：").create()).addPicture(mgr).addText("         日期：" + DateUtils.dateTime(aboveall.getConfirmationDate())));
                        signRow = Rows.of(cell, cell2, cell, cell, cell, cell).verticalCenter().textBold().rowExactHeight(1.1f).create();
                    }
                }
                tableRenderData.addRow(signRow);
            }
        }


        // 设置第一列加粗样式
        Style boldStyle = new Style();
        boldStyle.setBold(true);
        // 遍历每一行，将第一列的文字加粗
        for (RowRenderData row : tableRenderData.getRows()) {
            // 获取第一列
            CellRenderData firstColumn = row.getCells().get(0);

            // 直接使用现有内容并应用加粗样式
            String text = firstColumn.getParagraphs().get(0).getContents().get(0).toString();  // 获取第一列的文本内容

            // 使用 Cells.of 创建带加粗样式的新单元格
            firstColumn = Cells.of(Texts.of(text).style(boldStyle).create()).center().create();

            // 将加粗后的单元格重新放回第一列
            row.getCells().set(0, firstColumn);
        }

        // 合并第一列和每个部门的最后一行
        MergeCellRule.MergeCellRuleBuilder rule = MergeCellRule.builder();
        if (plant > 0 && ctm > 0 && cta > 0) {
            rule.map(MergeCellRule.Grid.of(1, 0), MergeCellRule.Grid.of(plant, 0))
                    .map(MergeCellRule.Grid.of(plant, 1), MergeCellRule.Grid.of(plant, 5))
                    .map(MergeCellRule.Grid.of(plant + 1, 0), MergeCellRule.Grid.of(ctm, 0))
                    .map(MergeCellRule.Grid.of(ctm, 1), MergeCellRule.Grid.of(ctm, 5))
                    .map(MergeCellRule.Grid.of(ctm + 1, 0), MergeCellRule.Grid.of(cta, 0))
                    .map(MergeCellRule.Grid.of(cta, 1), MergeCellRule.Grid.of(cta, 5));
        } else if (plant > 0 && ctm > 0 && cta == 0) {
            rule.map(MergeCellRule.Grid.of(1, 0), MergeCellRule.Grid.of(plant, 0))
                    .map(MergeCellRule.Grid.of(plant, 1), MergeCellRule.Grid.of(plant, 5))
                    .map(MergeCellRule.Grid.of(plant + 1, 0), MergeCellRule.Grid.of(ctm, 0))
                    .map(MergeCellRule.Grid.of(ctm, 1), MergeCellRule.Grid.of(ctm, 5));
        } else if (plant > 0 && ctm == 0 && cta > 0) {
            rule.map(MergeCellRule.Grid.of(1, 0), MergeCellRule.Grid.of(plant, 0))
                    .map(MergeCellRule.Grid.of(plant, 1), MergeCellRule.Grid.of(plant, 5))
                    .map(MergeCellRule.Grid.of(plant + 1, 0), MergeCellRule.Grid.of(cta, 0))
                    .map(MergeCellRule.Grid.of(cta, 1), MergeCellRule.Grid.of(cta, 5));
        } else if (plant == 0 && ctm > 0 && cta > 0) {
            rule.map(MergeCellRule.Grid.of(1, 0), MergeCellRule.Grid.of(ctm - 1, 0))
                    .map(MergeCellRule.Grid.of(ctm - 1, 1), MergeCellRule.Grid.of(ctm - 1, 5))
                    .map(MergeCellRule.Grid.of(ctm + 1, 0), MergeCellRule.Grid.of(cta, 0))
                    .map(MergeCellRule.Grid.of(cta, 1), MergeCellRule.Grid.of(cta, 5));
        } else if (plant > 0 && ctm == 0 && cta == 0) {
            rule.map(MergeCellRule.Grid.of(1, 0), MergeCellRule.Grid.of(plant, 0))
                    .map(MergeCellRule.Grid.of(plant, 1), MergeCellRule.Grid.of(plant, 5));
        } else if (plant == 0 && ctm > 0 && cta == 0) {
            rule.map(MergeCellRule.Grid.of(1, 0), MergeCellRule.Grid.of(ctm - 1, 0))
                    .map(MergeCellRule.Grid.of(ctm - 1, 1), MergeCellRule.Grid.of(ctm - 1, 5));
        } else if (plant == 0 && ctm == 0 && cta > 0) {
            rule.map(MergeCellRule.Grid.of(1, 0), MergeCellRule.Grid.of(cta - 2, 0))
                    .map(MergeCellRule.Grid.of(cta - 2, 1), MergeCellRule.Grid.of(cta - 2, 5));
        }

        tableRenderData.setMergeRule(rule.build());

        // 准备表格数据和其他参数
        params.put("unit", aboveall.getUnit());
        params.put("region", aboveall.getRegion());
        params.put("subcontent", tableRenderData);
        params.put("plantMgr", plantMgr);
        params.put("confirmDate", DateUtils.dateTime(aboveall.getConfirmationDate()));

        return params;

    }


    private String createWord(String templatePath, String fileDir, String fileName, Map<String, Object> paramMap, String directory) throws IOException {
        Assert.notNull(templatePath, "word模板文件路径不能为空");
        Assert.notNull(fileDir, "生成的文件存放地址不能为空");
        Assert.notNull(fileName, "生成的文件名不能为空");
        File dir = new File(fileDir);
        if (!dir.exists()) {
            logger.info("目录不存在，创建文件夹{}!", fileDir);
            dir.mkdirs();
        }
        fileName = fileName.replaceAll("/", "_"); //替换文件中敏感字段
        logger.info("目录文件{}!", fileName);
        String filePath = fileDir + "/" + fileName;
        logger.info("目录{}!", filePath);
        logger.info("模板{}!", templatePath);
        // 读取模板渲染参数
        InputStream is = getClass().getClassLoader().getResourceAsStream(templatePath);

        XWPFTemplate template = XWPFTemplate.compile(is).render(paramMap);
        try {
            // 将模板参数写入路径
            template.writeToFile(filePath);
            template.close();
            is.close();
        } catch (Exception e) {
            logger.error("生成word异常{}", e.getMessage());
            e.printStackTrace();
        }
        String pathFileName = FileUploadUtils.getPathFileName(RuoYiConfig.getFilePath("/" + directory), fileName);
        return pathFileName;
    }


    /**
     * 获取开车条件确认详细信息
     */
    @PreAuthorize("@ss.hasPermi('pssr:subcontent:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(tPssrSubcontentService.selectTPssrSubcontentById(id));
    }

    /**
     * 新增开车条件确认
     */
    @PreAuthorize("@ss.hasPermi('pssr:subcontent:add')")
    @Log(title = "开车条件确认", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody TPssrSubcontent tPssrSubcontent) {
        return toAjax(tPssrSubcontentService.insertTPssrSubcontent(tPssrSubcontent));
    }

    /**
     * 修改开车条件确认
     */
    @PreAuthorize("@ss.hasPermi('pssr:subcontent:edit')")
    @Log(title = "开车条件确认", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody TPssrSubcontent tPssrSubcontent) {
        return toAjax(tPssrSubcontentService.updateTPssrSubcontent(tPssrSubcontent));
    }

    /**
     * 删除开车条件确认
     */
    @PreAuthorize("@ss.hasPermi('pssr:subcontent:remove')")
    @Log(title = "开车条件确认", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        for (Long id : ids) {
            TPssrSubcontent subcontent = tPssrSubcontentService.selectTPssrSubcontentById(id);
            if (subcontent.getApproveStatus() != 0) {
                return AjaxResult.error("已发起审批的检查项不可删除！");
            }
        }
        return toAjax(tPssrSubcontentService.deleteTPssrSubcontentByIds(ids));
    }


    /**
     * 修改开车条件确认
     */
    @PreAuthorize("@ss.hasPermi('pssr:subcontent:edit')")
    @Log(title = "开车条件确认", businessType = BusinessType.UPDATE)
    @PutMapping("/turnDownSubcontent")
    public AjaxResult turnDownSubcontent(@RequestBody TPssrSubcontent tPssrSubcontent) {
        if (tPssrSubcontent.getIds() != null && tPssrSubcontent.getIds().size() > 0) {
            for (Long id : tPssrSubcontent.getIds()) {
                tPssrApproveController.doApprove(id);
            }
            TPssrAboveall aboveall = new TPssrAboveall();
            aboveall.setId(tPssrSubcontent.getAboveallId());
            aboveall.setApproveStatus(0L);
            tPssrAboveallService.updateTPssrAboveall(aboveall);
            TPssrApprove approve = tPssrApproveService.selectTPssrApproveByAboveallId(tPssrSubcontent.getAboveallId());
            try {
                runtimeService.deleteProcessInstance(approve.getProcessId(), "pssrMgrConfirm");
                historyService.deleteHistoricProcessInstance(approve.getProcessId());
            } catch (Exception e) {
                logger.info("无运行时流程");
            }
            return AjaxResult.success();
        }
        return AjaxResult.error("请选择需要执行的流程");
    }
}
