package com.ruoyi.project.sems.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

import com.alibaba.fastjson.JSON;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.document.ChartUtil;
import com.ruoyi.common.utils.document.DocumentHandler;
import com.ruoyi.common.utils.document.PDFTemplateUtil;
import com.ruoyi.common.utils.file.ExcelUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.framework.config.RuoYiConfig;
import com.ruoyi.project.sems.domain.TMeasureRecord;
import com.ruoyi.project.sems.domain.TSpecdevCc;
import com.ruoyi.project.sems.service.ITMeasureRecordService;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysDictData;
import freemarker.template.Template;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.jfree.data.category.DefaultCategoryDataset;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.project.sems.domain.TMeasureThickness;
import com.ruoyi.project.sems.service.ITMeasureThicknessService;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 定点测厚Controller
 *
 * @author ruoyi
 * @date 2021-07-07
 */
@RestController
@RequestMapping("/sems/thickness")
public class TMeasureThicknessController extends BaseController
{
    @Autowired
    private ITMeasureThicknessService tMeasureThicknessService;
    @Autowired
    private ITMeasureRecordService tMeasureRecordService;

    private final Long alarmtype = 1080L;//特种设备预警ID
    /**
     * 查询定点测厚列表
     */
    @PreAuthorize("@ss.hasPermi('sems:thickness:list')")
    @GetMapping("/list")
    public TableDataInfo list(TMeasureThickness tMeasureThickness)
    {
        startPage();
        List<TMeasureThickness> list = tMeasureThicknessService.selectTMeasureThicknessList(tMeasureThickness);
        for (TMeasureThickness m : list) {
            List<TMeasureRecord> measureRecords = tMeasureRecordService.queryRecords(m.getId().toString());
            if (measureRecords.size() > 0) {
                m.setFirstMeasureDate(measureRecords.get(measureRecords.size() - 1).getMeasureDate());
                m.setNewMeasureDate(measureRecords.get(0).getMeasureDate());
//                BigDecimal measureCycle = new BigDecimal(m.getMeasureCycle());
//                BigDecimal yearNum = new BigDecimal("31536000000");
//                Long cycle = measureCycle.multiply(yearNum).longValue();
//                Long newTime = measureRecords.get(0).getMeasureDate().getTime();
//                Long nextTime = newTime;
//                Date dat = new Date(nextTime);
//                GregorianCalendar nextMeasureDate = new GregorianCalendar();
//                nextMeasureDate.setTime(dat);
//                java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
//                m.setNextMeasureDate(format.format(nextMeasureDate.getTime()));
            }else {
                m.setFirstMeasureDate(null);
                m.setNewMeasureDate(null);
                m.setNextMeasureDate(null);
            }
            //寿命预警
            if (m.getNextWarnDate() != null && !StringUtils.isEmpty(m.getEstRemain())) {
               int day = this.formatDate(m.getNextWarnDate(),new Date());
               BigDecimal remain = new BigDecimal(m.getEstRemain()).multiply(new BigDecimal("365")).setScale(4,BigDecimal.ROUND_HALF_DOWN);
                logger.info(day +"::::" + remain);
               if (remain.compareTo(new BigDecimal(day)) == -1) {
                    m.setWarnFlag(1);
               }else {
                   m.setWarnFlag(0);
               }
            }else {
                m.setWarnFlag(0);
            }
        }
        return getDataTable(list);
    }

    /**
     * 批量导入
     */
    @PreAuthorize("@ss.hasPermi('sems:thickness:add')")
    @Log(title = "侧厚批量导入", businessType = BusinessType.INSERT)
    @PostMapping("/importData")
    public AjaxResult importData(@RequestParam("file") MultipartFile file) throws IOException
    {
        //获取操作人员ID
        Long userId = getUserId();
        //报错行数统计
        List<Integer> failRow =new ArrayList<Integer>();
        Workbook workbook = ExcelUtils.getWorkBook(file);
        Sheet sheet = workbook.getSheetAt(0);
        List<TMeasureThickness> list = new ArrayList<TMeasureThickness>();
        //字典查询

        int rowNum = sheet.getPhysicalNumberOfRows();
        int failNumber = 0;
        for (int i = 1; i < rowNum; i++) {
            try {
                logger.info("读取行数：" + i);
                Row row = sheet.getRow(i);
                int cellNum = row.getLastCellNum();
                TMeasureThickness entity = new TMeasureThickness();
                for (int j = 0; j < cellNum; j++) {
                    Cell cell = row.getCell(j);
                    if (cell == null) {
                        continue;
                    }
                    String cellValue = ExcelUtils.getCellValue(cell);
                    logger.info("cellValue:" + cellValue);
                    if (j == 0) {
                        //序号
                    } else if (j == 1) {
                        entity.setPlantCode(cellValue);//装置名称
                    } else if (j == 2) {
                        entity.setUnitCode(cellValue);//单元名称
                    } else if (j == 3) {
                        entity.setTagno(cellValue);//单位内编号
                    } else if (j == 4) {
                        entity.setPosition(cellValue);//测厚部位CML
                    } else if (j == 5) {
                        entity.setMeasureNo(cellValue);//检测编号
                    } else if (j == 6) {
                        entity.setEquipmentName(cellValue);//设备/管线名称
                    } else if (j == 7) {
                        entity.setMaterial(cellValue);//材质
                    } else if (j == 8) {
                        entity.setNominalTickness(cellValue);//公称壁厚(mm)
                    } else if (j == 9) {
                        entity.setThicknessMin(cellValue);//最小允许壁厚(mm)
                    } else if (j == 10) {
                        entity.setStCorrosion(cellValue);//短期腐蚀速率(mm/year)
                    } else if (j == 11) {
                        entity.setLtCorrosion(cellValue);//长期腐蚀速率(mm/year)
                    } else if (j == 12) {
                        entity.setMeasureCycle(cellValue);//长期腐蚀速率(mm/year)
                    } else if (j == 13) {
                        if (cellValue.length() > 3) {//下次测厚日期
                            entity.setNextWarnDate(new SimpleDateFormat(DateUtils.getDateFormat(cellValue)).parse(cellValue));
                        }
                    }  else if (j == 14) {
                        entity.setInspectionMethod(cellValue);//检测方法
                    }  else if (j == 15) {
                        entity.setCorAllowance(cellValue);//腐蚀裕度(mm)
                    } else if (j == 16) {
                        entity.setOriginalThickness(cellValue);//原始壁厚(mm)
                    } else if (j == 17) {
                        entity.setMedium(cellValue);//介质
                    } else if (j == 18) {
                        entity.setPressure(cellValue);//压力(MPa)
                    } else if (j == 19) {
                        entity.setSpecification(cellValue); //规格
                    } else if (j == 20) {
                        entity.setFlowRate(cellValue);//流速(m/s)
                    } else if (j == 21) {
                        //温度(℃)
                         entity.setTemperature(cellValue);
                    } else if (j == 22) {
                        //腐蚀类型
                        entity.setCorrosionType(cellValue);
                    } else if (j == 23) {
                        entity.setAnalysis(cellValue);//原因分析
                    }else if (j == 24) {
                        entity.setMethodCause(cellValue);//治理方法及依据
                    } else if (j == 25) {
                        entity.setEffectTracing(cellValue); //效果跟踪
                    }else if (j == 26) {
                        entity.setRaiser(cellValue);//提出人
                    }else if (j == 27) {
                        if (cellValue.length() > 3) {//提出时间
                            entity.setRaiserDate(new SimpleDateFormat(DateUtils.getDateFormat(cellValue)).parse(cellValue));
                        }
                    }else if (j == 28) {
                        entity.setOtherContent(cellValue);//其他检测方法内容
                    }else if (j == 29) {
                        entity.setRecorder(cellValue);//记录人
                    }else if (j == 30) {
                        if (cellValue.length() > 3) {//记录时间
                            entity.setRecorderDate(new SimpleDateFormat(DateUtils.getDateFormat(cellValue)).parse(cellValue));
                        }
                    }else if (j == 31) {
                        entity.setRemarks(cellValue);//备注
                    }
                }
                entity.setCreateBy(userId.toString());
                logger.info("entity:" + entity);
                list.add(entity);
            }catch (Exception e){
                failNumber++;
                logger.info("e:" + JSON.toJSONString(e));
                failRow.add(i + 1);
            }
        }
        int successNumber = 0;
        int failNum = 0;
        for (TMeasureThickness t : list
        ) {
            failNum++;
            try {
                tMeasureThicknessService.insertTMeasureThickness(t);
                successNumber++;
            }catch (Exception e){
                failNumber++;
                logger.info("e:" + e);
                failRow.add(failNum + 1);
            }
        }
        logger.info("list:" + JSON.toJSONString(list));
        logger.info("successNumber:" +String.valueOf(successNumber));
        logger.info("failNumber:" +String.valueOf(failNumber));
        logger.info("failRow:" +String.valueOf(failRow));
        return AjaxResult.success(String.valueOf(successNumber), failRow);
    }

    /**
     * 导出定点测厚列表
     */
    @PreAuthorize("@ss.hasPermi('sems:thickness:export')")
    @Log(title = "定点测厚", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(TMeasureThickness tMeasureThickness)
    {
        List<TMeasureThickness> list = tMeasureThicknessService.selectTMeasureThicknessList(tMeasureThickness);
        ExcelUtil<TMeasureThickness> util = new ExcelUtil<TMeasureThickness>(TMeasureThickness.class);
        return util.exportExcel(list, "thickness");
    }

    /**
     * 获取定点测厚详细信息
     */
    @PreAuthorize("@ss.hasPermi('sems:thickness:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        //生成图表
        String chartUrl = "/profile/" + this.getRecordUrl(id.toString());
        TMeasureThickness t = tMeasureThicknessService.selectTMeasureThicknessById(id);
        t.setRecordUrl(chartUrl);
        return AjaxResult.success(t);
    }

    /**
     * 新增定点测厚
     */
    @PreAuthorize("@ss.hasPermi('sems:thickness:add')")
    @Log(title = "定点测厚", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody TMeasureThickness tMeasureThickness)
    {
        return toAjax(tMeasureThicknessService.insertTMeasureThickness(tMeasureThickness));
    }

    /**
     * 修改定点测厚
     */
    @PreAuthorize("@ss.hasPermi('sems:thickness:edit')")
    @Log(title = "定点测厚", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody TMeasureThickness tMeasureThickness)
    {
        return toAjax(tMeasureThicknessService.updateTMeasureThickness(tMeasureThickness));
    }

    /**
     * 删除定点测厚
     */
    @PreAuthorize("@ss.hasPermi('sems:thickness:remove')")
    @Log(title = "定点测厚", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(tMeasureThicknessService.deleteTMeasureThicknessByIds(ids));
    }

    /**
     * 定点测厚图片上传
     */
    @Log(title = "定点测厚图片上传", businessType = BusinessType.UPDATE)
    @PostMapping("/uploadFile")
    public AjaxResult uploadFile(@RequestParam("file") MultipartFile file) throws IOException
    {
        if (!file.isEmpty())
        {
            String avatar = FileUploadUtils.upload(RuoYiConfig.getFilePath("/thickness"), file);
            return AjaxResult.success(avatar);
        }
        return AjaxResult.error("上传图片异常，请联系管理员");
    }


    @RequestMapping("/measure/exportPDF")
    public String measure(@RequestParam String id, HttpServletRequest request, HttpServletResponse response) {
        OutputStream out= null;
        try {
            getRecordUrl(id);
            out = response.getOutputStream();
            logger.info("id:" + id);
            //获取信息，就是上面的结构
            HashMap<String, Object> map = new HashMap<>();
            DocumentHandler dh = new DocumentHandler();
            Template t = dh.getTemplate();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            TMeasureThickness measureThicknessEntity = tMeasureThicknessService.selectTMeasureThicknessById(Long.parseLong(id));
            //生成图表
            String chartUrl = this.getRecordUrl(id);
            map.put("chartUrl", chartUrl);
            logger.info(chartUrl);
            //测量方法
            String[] inspectionMethod = measureThicknessEntity.getInspectionMethod().split(",");
            logger.info("inspectionMethod:" + inspectionMethod);
            for (String m : inspectionMethod) {
                if (m.equals("1")){ measureThicknessEntity.setMethodUT(true); }
                if (m.equals("2")){ measureThicknessEntity.setMethodPEC(true); }
                if (m.equals("3")){ measureThicknessEntity.setMethodRT(true); }
                if (m.equals("4")){ measureThicknessEntity.setMethodEMAT(true); }
                if (m.equals("5")){ measureThicknessEntity.setMethodOther(true); }
            }
            map.put("measure", measureThicknessEntity);
            logger.info("measure:" + measureThicknessEntity);
            if(StringUtils.isNotEmpty(measureThicknessEntity.getPhoto())){
                String[] photos =  measureThicknessEntity.getPhoto().split(",");
                if (photos.length == 1) {
                    map.put("photo1", photos[0].replaceAll("/profile/",""));
                }else if (photos.length == 2) {
                    map.put("photo1", photos[0].replaceAll("/profile/",""));
                    map.put("photo2", photos[1].replaceAll("/profile/",""));
                }else if (photos.length == 3) {
                    map.put("photo1", photos[0].replaceAll("/profile/",""));
                    map.put("photo2", photos[1].replaceAll("/profile/",""));
                    map.put("photo3", photos[2].replaceAll("/profile/",""));
                }
            }
            if(StringUtils.isNotEmpty(measureThicknessEntity.getLocationUrl())){
                String[] locationUrls =  measureThicknessEntity.getLocationUrl().split(",");
                if (locationUrls.length == 1) {
                    map.put("locationUrl1", locationUrls[0].replaceAll("/profile/",""));
                }else if (locationUrls.length == 2) {
                    map.put("locationUrl1", locationUrls[0].replaceAll("/profile/",""));
                    map.put("locationUrl2", locationUrls[1].replaceAll("/profile/",""));
                    logger.info(locationUrls[0]);
                }else if (locationUrls.length == 3) {
                    map.put("locationUrl1", locationUrls[0].replaceAll("/profile/",""));
                    map.put("locationUrl2", locationUrls[1].replaceAll("/profile/",""));
                    map.put("locationUrl3", locationUrls[2].replaceAll("/profile/",""));
                }
            }
        //测量记录分行
        List<TMeasureRecord> measureRecords = tMeasureRecordService.queryRecords(id);
        List<List<TMeasureRecord>> result = new ArrayList<List<TMeasureRecord>>();
        int sourceSize = measureRecords.size();
            int size = (measureRecords.size() / 7) + 1;
            if (measureRecords.size() % 7 == 0) {
                size = size - 1;
            }
            for (int i = 0; i < size; i++) {
                List<TMeasureRecord> subset = new ArrayList<TMeasureRecord>();
                for (int j = i * 7; j < (i + 1) * 7; j++) {
                    if (j < sourceSize) {
                        subset.add(measureRecords.get(j));
                    }
                }
                if (subset.size() < 7) {
                    int supplement = 7 - subset.size();
                    for (int m = 0; m < supplement; m++) {
                        TMeasureRecord nullRecord = new TMeasureRecord();
                        subset.add(nullRecord);
                    }
                }
                result.add(subset);
            }
            map.put("result", result);
            logger.info("result:" + result);
            String name = measureThicknessEntity.getPlantCode() +"-" +measureThicknessEntity.getTagno() + "-" + measureThicknessEntity.getPosition();
            PDFTemplateUtil.exportPdf("measureFMaker.ftl", name + ".pdf","file:"+RuoYiConfig.getProfile(), map, response);
//             PDFTemplateUtil.exportPdf("measureFMaker.ftl", name + ".pdf",RuoYiConfig.getProfile(), map, response);

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(out!=null)
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
        return null;
    }

    public String getRecordUrl(String id){
        try {
            TMeasureThickness measureThicknessEntity = tMeasureThicknessService.selectTMeasureThicknessById(Long.parseLong(id));
            List<TMeasureRecord> measureRecords = tMeasureRecordService.queryRecords(id);
            Collections.reverse(measureRecords);
            //种类数据集
            DefaultCategoryDataset dataset = new DefaultCategoryDataset();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
            for (TMeasureRecord t: measureRecords
            ) {
                dataset.addValue(t.getMeasureValue() , "数值Value" , sdf.format(t.getMeasureDate()));
                if (measureThicknessEntity.getThicknessMin() != null){
                    dataset.addValue(Double.parseDouble(measureThicknessEntity.getThicknessMin()) , "最小允许壁厚" , sdf.format(t.getMeasureDate()));
                }
            }
            String url = RuoYiConfig.getProfile() + "/" + id +".jpg";
            ChartUtil.createLinePort("" , dataset ,"" ,"" , url ) ;

        }catch (Exception e) {
            logger.error("生成图片错误");
            logger.error(JSON.toJSONString(e));
        }
        return id +".jpg";
    }

    private int formatDate(Date nowDate, Date sqlDate){
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String newDate = df.format(nowDate);
        String sqlDate1 = df.format(sqlDate);
        try {
            nowDate = df.parse(newDate);
            sqlDate = df.parse(sqlDate1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Long time =  nowDate.getTime();
        Long time2 =  sqlDate.getTime();
        int day = (int) ((time - time2) / (24*3600*1000));
        return day;
    }
}
