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.pssr.domain.*;
import com.ruoyi.project.pssr.mapper.TPssrPublicMapper;
import com.ruoyi.project.pssr.service.*;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.service.ISysUserService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.TaskService;
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.Row;
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.math.BigDecimal;
import java.util.*;

/**
 * 公用工程Controller
 *
 * @author ssy
 * @date 2024-09-18
 */
@RestController
@RequestMapping("/pssr/public")
public class TPssrPublicController extends BaseController {
    @Resource
    private TPssrPublicMapper tPssrPublicMapper;
    @Autowired
    private ITPssrFileService tPssrFileService;

    @Autowired
    private ITPssrTurndownService tPssrTurndownService;
    @Autowired
    private ITPssrPublicService tPssrPublicService;

    @Autowired
    private ITPssrApproveService tPssrApproveService;

    @Autowired
    private ITPssrSubcontentService tPssrSubcontentService;

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


    /**
     * 查询公用工程列表
     */
    @PreAuthorize("@ss.hasPermi('pssr:public:list')")
    @GetMapping("/list")
    public TableDataInfo list(TPssrPublic tPssrPublic) {
        try {
            TPssrApprove approve = tPssrApproveService.selectTPssrApproveBySubId(tPssrPublic.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")){
                        tPssrPublic.setConfirm1(getUserId().toString());
                    }else if (task.getName().equals("确认人2")){
                       tPssrPublic.setConfirm2(getUserId().toString());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("待办确认人查询报错：{}",e.getMessage());
        }
        startPage();
        List<TPssrPublic> list = tPssrPublicService.selectTPssrPublicList(tPssrPublic);
        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(), forShort));
        });
        return getDataTable(list);
    }

    /**
     * 导出公用工程列表
     */
    @PreAuthorize("@ss.hasPermi('pssr:public:export')")
    @Log(title = "公用工程", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(TPssrPublic tPssrPublic) {
        List<TPssrPublic> list = tPssrPublicService.selectTPssrPublicList(tPssrPublic);
        if (list.size() != 0) {
            return AjaxResult.success(exportTmpl(list));
        } else {
            return AjaxResult.error("暂无可导出数据");
        }
    }

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

            //填充数据
            int rowIndex = 3;
            int num = 1;

            Row originalRow = sheet.getRow(3);
            Cell originalcell = originalRow.getCell(0);
            // 获取单元格样式
            CellStyle originalStyle = originalcell.getCellStyle();

            for (TPssrPublic t : list) {
                Row row = sheet.createRow(rowIndex);
                row.setHeight((short) 800);
                row.createCell(0).setCellValue(num);
                row.createCell(1).setCellValue(t.getCheckContent());
                row.createCell(2).setCellValue(t.getCheckRequire());
                row.createCell(3).setCellValue("界区阀"+t.getValveStatus()+"；"+t.getCheckCondition());
                row.createCell(4).setCellValue(t.getCheckResult());
                row.createCell(5);
                row.createCell(6);
                try {
                    SysUser sysUser = sysUserService.selectUserById(Long.valueOf(t.getConfirm1()));
                    SysUser sysUser2 = sysUserService.selectUserById(Long.valueOf(t.getConfirm2()));
                    String confirm1 = sysUser.getSignUrl();
                    String confirm2 = sysUser2.getSignUrl();
                    ExcelUtils.insertPicture(wb, sheet, confirm1, row.getRowNum(), 5, 1, 1);
                    ExcelUtils.insertPicture(wb, sheet, confirm2, row.getRowNum(), 6, 1, 1);
                } catch (Exception e) {

                }
                row.createCell(7).setCellValue(DateUtils.dateTime(t.getConfirmationDate()));
                row.createCell(8).setCellValue(t.getRemarks());


                //渲染样式
                for (int i = 0; i < 9; i++) {
                    row.getCell(i).setCellStyle(originalStyle);
                }
                num++;
                rowIndex++;
            }
            filename = "PSSR_17_公用工程"  + ".xlsx";
            out = new FileOutputStream(ExcelUtil.getAbsoluteFile(filename));
            wb.write(out);
            wb.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
        return filename;
    }

    /**
     * 获取公用工程详细信息
     */
    @PreAuthorize("@ss.hasPermi('pssr:public:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        TPssrPublic item = tPssrPublicService.selectTPssrPublicById(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(), forShort));
        return AjaxResult.success(item);
    }

    /**
     * 新增公用工程
     */
    @PreAuthorize("@ss.hasPermi('pssr:public:add')")
    @Log(title = "公用工程", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody TPssrPublic tPssrPublic) {
        if (StringUtils.isNotEmpty(tPssrPublic.getConfirm1())&&tPssrPublic.getConfirm1().equals(tPssrPublic.getConfirm2())) {
            return AjaxResult.error("确认人不能为同一人，请重新选择！");
        }
        tPssrPublic.setApproveStatus(0L);
        return toAjax(tPssrPublicService.insertTPssrPublic(tPssrPublic));
    }

    /**
     * 修改公用工程
     */
    @PreAuthorize("@ss.hasPermi('pssr:public:edit')")
    @Log(title = "公用工程", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody TPssrPublic tPssrPublic) {
        TPssrPublic entity = tPssrPublicService.selectTPssrPublicById(tPssrPublic.getId());
        if (entity.getApproveStatus() != 1 && entity.getApproveStatus() != 0) {
            return  AjaxResult.error("当前状态不可修改！");
        }
        if (tPssrPublic.getConfirm1().equals(tPssrPublic.getConfirm2())){
            return AjaxResult.error("确认人不能为同一人，请重新选择！");
        }
        try {
            String checkRequire = tPssrPublic.getCheckRequire().replace(" ", "");
            String checkCondition = tPssrPublic.getCheckCondition().replace(" ", "");
            String valveStatus = tPssrPublic.getValveStatus();
            if (!"已打开".equals(valveStatus)) {
                tPssrPublic.setCheckResult("✖");
            } else if (checkRequire.contains("达(") && checkCondition.contains("达(")) {
                String rKpa = "0";
                String rycKpa = "0";
                String rTemp = "0";
                String rMpa = "0";
                String cKpa = "-1";
                String cTemp = "-1";
                String cMpa = "-1";
                String cycKpa = "-1";
                if (checkRequire.contains("压力达(") && checkRequire.contains(")kPa"))
                    rKpa = checkRequire.substring(checkRequire.indexOf("压力达(") + 4, checkRequire.indexOf(")kPa")).trim();
                if (checkRequire.contains("压差达("))
                    rycKpa = checkRequire.substring(checkRequire.indexOf("压差达(") + 4, checkRequire.indexOf(")kPa")).trim();
                if (checkRequire.contains("温度达("))
                    rTemp = checkRequire.substring(checkRequire.indexOf("温度达(") + 4, checkRequire.indexOf(")℃")).trim();
                if (checkRequire.contains("压力达(") && checkRequire.contains(")MPa"))
                    rMpa = checkRequire.substring(checkRequire.indexOf("压力达(") + 4, checkRequire.indexOf(")MPa")).trim();
                if (checkCondition.contains("压力达(") && checkCondition.contains(")kPa"))
                    cKpa = checkCondition.substring(checkCondition.indexOf("压力达(") + 4, checkCondition.indexOf(")kPa")).trim();
                if (checkCondition.contains("压差达("))
                    cycKpa = checkCondition.substring(checkCondition.indexOf("压差达(") + 4, checkCondition.indexOf(")kPa")).trim();
                if (checkCondition.contains("温度达("))
                    cTemp = checkCondition.substring(checkCondition.indexOf("温度达(") + 4, checkCondition.indexOf(")℃")).trim();
                if (checkCondition.contains("压力达(") && checkCondition.contains("MPa"))
                    cMpa = checkCondition.substring(checkCondition.indexOf("压力达(") + 4, checkCondition.indexOf(")MPa")).trim();

                if (new BigDecimal(rKpa).compareTo(new BigDecimal(cKpa)) <= 0 || new BigDecimal(rycKpa).compareTo(new BigDecimal(cycKpa)) <= 0 ||
                        (new BigDecimal(rTemp).compareTo(new BigDecimal(cTemp)) <= 0 && new BigDecimal(rMpa).compareTo(new BigDecimal(cMpa)) <= 0)
                        || (new BigDecimal(rMpa).compareTo(new BigDecimal(cMpa)) <= 0 && !checkRequire.contains(")℃"))) {
                    tPssrPublic.setCheckResult("✔");
                } else {
                    tPssrPublic.setCheckResult("✖");
                }
            }else{
                return AjaxResult.error("检查条件/内容不符合填写要求");
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        tPssrFileService.updateFileRelevance(tPssrPublic.getFileIds(), forShort, tPssrPublic.getId(), tPssrPublic.getSubId());
        return toAjax(tPssrPublicService.updateTPssrPublic(tPssrPublic));
    }

    /**
     * 从字符串中提取压力和温度的值
     *
     * @param input 输入的字符串
     * @return 返回 [压力值, 温度值] 数组；如果格式不正确，返回 null
     */
    public static Double[] extractValues(String input) {

        return null;
    }


    /**
     * 比对方法：检查 require 中的值是否小于 condition 中的值
     *
     * @param condition 条件值数组 [压力值, 温度值]
     * @param require   要求值数组 [压力值, 温度值]
     * @return 如果 require 中的值均小于 condition 中的值，则返回 true，否则返回 false
     */
    public static boolean compareValues(Double[] condition, Double[] require) {
        // 比较压力值或压差值
        if (require[0] > condition[0]) {
            return false;
        }

        // 比较温度值（如果 condition 和 require 都包含温度值）
        if (condition.length > 1 && require.length > 1 && condition[1] != null && require[1] != null) {
            if (require[1] > condition[1]) {
                return false;
            }
        }

        return true; // 如果所有值都满足条件，返回 true
    }

    /**
     * 修改公用工程
     */
    @PreAuthorize("@ss.hasPermi('pssr:public:edit')")
    @Log(title = "公用工程", businessType = BusinessType.UPDATE)
    @PutMapping("/editBatch")
    public AjaxResult editb(@RequestBody TPssrPublic tPssrPublic) {
        if (tPssrPublic.getConfirm1().equals(tPssrPublic.getConfirm2())){
            return AjaxResult.error("确认人不能为同一人，请重新选择！");
        }
        return toAjax(tPssrPublicMapper.updateTPssrPublicByIds(tPssrPublic));
    }

    /**
     * 删除公用工程
     */
    @PreAuthorize("@ss.hasPermi('pssr:public:remove')")
    @Log(title = "公用工程", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(tPssrPublicService.deleteTPssrPublicByIds(ids));
    }

    /**
     * 确认公用工程
     */
    @PreAuthorize("@ss.hasPermi('pssr:public:edit')")
    @Log(title = "公用工程", businessType = BusinessType.UPDATE)
    @PutMapping("/confirmPublic")
    public AjaxResult confirmPublic(@RequestBody TPssrPublic tPssrPublic) {
        long queryStatus = 0;
        long approveStatus = 0;
        Date date = null;
        TPssrPublic lock = new TPssrPublic();
        if (tPssrPublic.getTaskType() == 4) {
            //拆锁确认
            queryStatus = 1;
            approveStatus = 3;
            date = new Date();
            lock.setConfirm1(getUserId().toString());
        } else if (tPssrPublic.getTaskType() == 5) {
            //上锁确认
            queryStatus = 3;
            approveStatus = 2;
            date = new Date();
            lock.setConfirm2(getUserId().toString());
        }
        // 修改状态
        if (tPssrPublic.getIds() != null && tPssrPublic.getIds().length > 0) {
            for (Long id : tPssrPublic.getIds()) {
                TPssrPublic item = tPssrPublicService.selectTPssrPublicById(id);
                if (item.getCheckResult().equals("✖")){
                    return AjaxResult.error("公用工程检查不合格，请重新确认！");
                }
                item.setApproveStatus(approveStatus);
                if (item.getConfirmationDate() == null && queryStatus == 3) {
                    item.setConfirmationDate(date);
                }
                tPssrPublicService.updateTPssrPublic(item);
            }
        } else {
            lock.setSubId(tPssrPublic.getSubId());
            lock.setApproveStatus(queryStatus);
            for (TPssrPublic item : tPssrPublicService.selectTPssrPublicList(lock)) {
                if (item.getCheckResult().equals("✖")){
                    return AjaxResult.error("公用工程检查不合格，请重新确认！");
                }
                if (item.getConfirmationDate() == null && queryStatus == 3) {
                    item.setConfirmationDate(date);
                }
                item.setApproveStatus(approveStatus);
                tPssrPublicService.updateTPssrPublic(item);
            }
        }
        //查询当前待审批的确认人
        TPssrPublic entity = new TPssrPublic();
        entity.setSubId(tPssrPublic.getSubId());
        entity.setApproveStatus(queryStatus);
        for (TPssrPublic item : tPssrPublicService.selectTPssrPublicList(entity)) {
            if (tPssrPublic.getTaskType() == 4) {
                if (item.getConfirm1().equals(getUserId().toString())) {
                    return AjaxResult.success();
                }
            } else if (tPssrPublic.getTaskType() == 5) {
                if (item.getConfirm2().equals(getUserId().toString())) {
                    return AjaxResult.success();
                }
            }
        }

        //无待审批任务结束当前用户流程

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

    }

    /**
     * 驳回公用工程
     */
    @PutMapping("/turnDownPublic")
    public AjaxResult turnDownPublic(@RequestBody List<TPssrPublic> tPssrPublic) {
        if (CollectionUtils.isNotEmpty(tPssrPublic)) {
            String userId = getUserId().toString();
            Long subId = tPssrPublic.get(0).getSubId();
            // 修改已选择数据的状态
            for (TPssrPublic item : tPssrPublic) {
                TPssrPublic blind = new TPssrPublic();
                blind.setId(item.getId());
                blind.setApproveStatus(1L);
                blind.setUpdatedate(new Date());
                blind.setUpdaterCode(getUserId().toString());
                tPssrPublicService.updateTPssrPublic(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);

            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            TaskService taskService = processEngine.getTaskService();
            Task task = processEngine.getTaskService()//获取任务service
                    .createTaskQuery()//创建查询对象
                    .taskAssignee(userId)
                    .processInstanceId(approve.getProcessId()).singleResult();
            String taskId = task.getId();

            // 驳回 查询所有待审批的人员
            TPssrPublic blind = new TPssrPublic();
            blind.setSubId(subId);
            blind.setApproveStatus(1L);
            Set<String> installer = new HashSet<>();
            Set<String> remover = new HashSet<>();
            for (TPssrPublic item : tPssrPublicService.selectTPssrPublicList(blind)) {

                // 安装人员
                installer.add(item.getConfirm1());

                //拆除人员
                remover.add(item.getConfirm2());
            }


            //处理流程节点
            Map<String, Object> param = new HashMap<>();
            param.put("condition", 1);
            param.put("confirmUsers1", new ArrayList<>(installer));
            param.put("confirmUsers2", new ArrayList<>(remover));
            //认领任务
            processEngine.getTaskService().claim(taskId, userId);
            taskService.addComment(taskId, approve.getProcessId(), "驳回");
            taskService.complete(taskId, param);

            // 修改审批表和sub表
            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();
    }
}
