package com.ruoyi.project.task.controller;

import java.sql.Time;
import java.util.*;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.project.base.domain.TBaseDevice;
import com.ruoyi.project.base.domain.TBasePlant;
import com.ruoyi.project.base.domain.TBasePoint;
import com.ruoyi.project.base.domain.TBaseRegion;
import com.ruoyi.project.base.mapper.TBasePointMapper;
import com.ruoyi.project.base.mapper.TBaseRegionMapper;
import com.ruoyi.project.base.service.ITBaseDeviceService;
import com.ruoyi.project.base.service.ITBasePlantService;
import com.ruoyi.project.base.service.ITBasePointService;
import com.ruoyi.project.base.service.ITBaseRegionService;
import com.ruoyi.project.check.domain.TCheckCheckpoints;
import com.ruoyi.project.check.domain.TCheckLawitems;
import com.ruoyi.project.check.mapper.TCheckCheckpointsMapper;
import com.ruoyi.project.check.service.ITCheckCheckpointsService;
import com.ruoyi.project.check.service.ITCheckLawitemsService;
import com.ruoyi.project.task.domain.TTaskInspection;
import com.ruoyi.project.task.mapper.TTaskInspectionPlanMapper;
import com.ruoyi.project.task.service.ITTaskInspectionService;
import com.ruoyi.system.service.ISysDictTypeService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.project.task.domain.TTaskInspectionPlan;
import com.ruoyi.project.task.service.ITTaskInspectionPlanService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 检测计划Controller
 *
 * @author ruoyi
 * @date 2022-11-17
 */
@RestController
@RequestMapping("/task/plan")
public class TTaskInspectionPlanController extends BaseController {
    @Autowired
    private ITTaskInspectionPlanService tTaskInspectionPlanService;

    @Autowired
    private ITTaskInspectionService tTaskInspectionService;

    @Autowired
    private TTaskInspectionPlanMapper tTaskInspectionPlanMapper;

    @Autowired
    private ITBasePlantService tBasePlantService;

    @Autowired
    private ISysDictTypeService isysDictTypeService;

    @Autowired
    private TBasePointMapper tBasePointMapper;

    @Autowired
    private ITBaseRegionService tBaseRegionService;

    @Autowired
    private ITBaseDeviceService tBaseDeviceService;

    @Autowired
    private ITCheckCheckpointsService tCheckCheckpointsService;

    @Autowired
    private TCheckCheckpointsMapper tCheckCheckpointsMapper;

    @Autowired
    private ITCheckLawitemsService tCheckLawitemsService;

    /**
     * 查询检测计划列表
     */
    @PreAuthorize("@ss.hasPermi('task:plan:list')")
    @GetMapping("/list")
    public TableDataInfo list(TTaskInspectionPlan tTaskInspectionPlan) {
        startPage();
        List<TTaskInspectionPlan> list = tTaskInspectionPlanService.selectTTaskInspectionPlanList(tTaskInspectionPlan);
        list.forEach(item -> {
            TTaskInspection tTaskInspection = new TTaskInspection();
            tTaskInspection.setPlanId(item.getId());
            if (CollectionUtils.isNotEmpty(tTaskInspectionService.selectTTaskInspectionList(tTaskInspection))) {
                item.setHaveSub("1");
            } else {
                item.setHaveSub("0");
            }
        });
        return getDataTable(list);
    }

    @GetMapping("/allPlan")
    public AjaxResult selectAllPlan() {
        return AjaxResult.success(tTaskInspectionPlanService.selectAllPlan());
    }

    @GetMapping("/pointList")
    public TableDataInfo pointList(TBasePoint tBasePoint){
        startPage();
        List<TBasePoint> list = tBasePointMapper.selectTBasePointListNotInPlan(tBasePoint);
        return getDataTable(list);
    }

    /**
     * 导出检测计划列表
     */
    @PreAuthorize("@ss.hasPermi('task:plan:export')")
    @Log(title = "检测计划导出", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, TTaskInspectionPlan tTaskInspectionPlan) {
        List<TTaskInspectionPlan> list = tTaskInspectionPlanService.selectTTaskInspectionPlanList(tTaskInspectionPlan);
        ExcelUtil<TTaskInspectionPlan> util = new ExcelUtil<TTaskInspectionPlan>(TTaskInspectionPlan.class);
        util.exportExcel(response, list, "检测计划数据");
    }

    /**
     * 获取检测计划详细信息
     */
    @PreAuthorize("@ss.hasPermi('task:plan:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(tTaskInspectionPlanService.selectTTaskInspectionPlanById(id));
    }

    /**
     * 新增检测计划
     */
    @PreAuthorize("@ss.hasPermi('task:plan:add')")
    @Log(title = "检测计划新增", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody TTaskInspectionPlan tTaskInspectionPlan) {
        tTaskInspectionPlan.setCreaterCode(getUserId());
        if (tTaskInspectionPlanService.insertTTaskInspectionPlan(tTaskInspectionPlan) > 0 && !"5".equals(tTaskInspectionPlan.getDetectionFrequency())) {
            TBasePlant tBasePlant = tBasePlantService.selectTBasePlantById(tTaskInspectionPlan.getPlantId());
            // 统计当前装置下的所有(动)密封点
            QueryWrapper<TBasePoint> points = new QueryWrapper<TBasePoint>().eq("plant_id", tTaskInspectionPlan.getPlantId()).eq("del_flag", 0).eq("approve_status", 2);
            List<TCheckLawitems> tCheckLawitems = tCheckLawitemsService.selectTCheckLawitemsByLawStatus();
            // 匹配法规标准
            if ("2".equals(tTaskInspectionPlan.getDetectionFrequency())) {
                Set<String> pointTypes = new HashSet<>();
                for (TCheckLawitems lawitem : tCheckLawitems) {
                    if (lawitem.getPlantType().equals(tBasePlant.getPlantType()) && lawitem.getDetectionFrequency().equals("2")) {
                        pointTypes.add(lawitem.getPointType());
                    }
                }
                if (CollectionUtils.isEmpty(pointTypes)){
                    return AjaxResult.success();
                }
                points.in("point_type", pointTypes);
            }
            Integer count = tBasePointMapper.selectCount(points);
            tTaskInspectionPlan.setPointNum(count.toString());
            tTaskInspectionPlan.setCreaterCode(getUserId());
            tTaskInspectionPlan.setCreatedate(new Date());
            tTaskInspectionPlan.setUpdaterCode(getUserId());
            tTaskInspectionPlan.setUpdatedate(new Date());

            // 新增检测点
            List<TCheckCheckpoints> tCheckCheckpoints = new ArrayList<>();
            List<TBasePoint> tBasePoints = tBasePointMapper.selectList(points);
            for (TBasePoint tBasePoint : tBasePoints) {

                TCheckCheckpoints tCheckCheckpoint = new TCheckCheckpoints();
                tCheckCheckpoint.setPlanId(tTaskInspectionPlan.getId());
                tCheckCheckpoint.setPointId(tBasePoint.getPointId());
                tCheckCheckpoint.setPlantName(tBasePlant.getPlantName());
                tCheckCheckpoint.setPlantId(tBasePlant.getPlantId());
                // TODO:需要优化，将区域名称和设备信息在新增密封点时直接存进去
                //                tCheckCheckpoint.setRegionName(tBaseRegionService.selectTBaseRegionById(tBasePoint.getRegionId()).getRegionName());
                tCheckCheckpoint.setRegionId(tBasePoint.getRegionId());
                tCheckCheckpoint.setLayer(tBasePoint.getLayer());
                //                TBaseDevice tBaseDevice = tBaseDeviceService.selectTBaseDeviceById(tBasePoint.getDevId());
                //                tCheckCheckpoint.setDevName(tBaseDevice.getDevDescribe());
                //                tCheckCheckpoint.setDevCode(tBaseDevice.getDevCode());
                tCheckCheckpoint.setDevId(tBasePoint.getDevId());
                tCheckCheckpoint.setGroupCode(tBasePoint.getGroupCode());
                tCheckCheckpoint.setExtendCode(tBasePoint.getExtendCode());
                tCheckCheckpoint.setPointType(tBasePoint.getPointType());
                tCheckCheckpoint.setCreaterCode(getUserId());
                tCheckCheckpoint.setCreatedate(new Date());
                tCheckCheckpoint.setUpdaterCode(getUserId());
                tCheckCheckpoint.setUpdatedate(new Date());
                tCheckCheckpoint.setPlantType(tBasePlant.getPlantType());
                tCheckCheckpoint.setMediumType(tBasePoint.getMediumType());
                tCheckCheckpoints.add(tCheckCheckpoint);
            }
            if (CollectionUtils.isNotEmpty(tCheckCheckpoints))
                tCheckCheckpointsService.insertTCheckCheckpointsByList(tCheckCheckpoints);
            return toAjax(tTaskInspectionPlanService.updateTTaskInspectionPlan(tTaskInspectionPlan));
        }
        return AjaxResult.success();
    }

    @PostMapping("/addCheckpoints")
    @Log(title = "检测计划新增临时计划添加检测点", businessType = BusinessType.INSERT)
    public AjaxResult addCheckpoints(@RequestBody TTaskInspectionPlan tTaskInspectionPlan) {
        TTaskInspection tTaskInspection = new TTaskInspection();
        tTaskInspection.setPlanId(tTaskInspectionPlan.getId());
        if (CollectionUtils.isNotEmpty(tTaskInspectionService.selectTTaskInspectionList(tTaskInspection))) {
            return AjaxResult.error();
        }
        QueryWrapper<TBasePoint> points = new QueryWrapper<TBasePoint>().eq("del_flag", 0).eq("approve_status", 2).in("point_id", tTaskInspectionPlan.getPointIds());
        List<TBasePoint> tBasePoints = tBasePointMapper.selectList(points);
        TBasePlant tBasePlant = tBasePlantService.selectTBasePlantById(tTaskInspectionPlan.getPlantId());
        // 新增检测点
        List<TCheckCheckpoints> tCheckCheckpoints = new ArrayList<>();
        for (TBasePoint tBasePoint : tBasePoints) {
            TCheckCheckpoints tCheckCheckpoint = new TCheckCheckpoints();
            tCheckCheckpoint.setPointId(tBasePoint.getPointId());
            tCheckCheckpoint.setPlantName(tTaskInspectionPlan.getPlantName());
            tCheckCheckpoint.setPlantId(tBasePoint.getPlantId());
            // TODO:需要优化，将区域名称和设备信息在新增密封点时直接存进去
//                tCheckCheckpoint.setRegionName(tBaseRegionService.selectTBaseRegionById(tBasePoint.getRegionId()).getRegionName());
            tCheckCheckpoint.setRegionId(tBasePoint.getRegionId());
            tCheckCheckpoint.setLayer(tBasePoint.getLayer());
//                TBaseDevice tBaseDevice = tBaseDeviceService.selectTBaseDeviceById(tBasePoint.getDevId());
//                tCheckCheckpoint.setDevName(tBaseDevice.getDevDescribe());
//                tCheckCheckpoint.setDevCode(tBaseDevice.getDevCode());
            tCheckCheckpoint.setDevId(tBasePoint.getDevId());
            tCheckCheckpoint.setGroupCode(tBasePoint.getGroupCode());
            tCheckCheckpoint.setExtendCode(tBasePoint.getExtendCode());
            tCheckCheckpoint.setPointType(tBasePoint.getPointType());
            tCheckCheckpoint.setCreaterCode(getUserId());
            tCheckCheckpoint.setCreatedate(new Date());
            tCheckCheckpoint.setUpdaterCode(getUserId());
            tCheckCheckpoint.setUpdatedate(new Date());
            tCheckCheckpoint.setPlantType(tBasePlant.getPlantType());
            tCheckCheckpoint.setMediumType(tBasePoint.getMediumType());
            tCheckCheckpoint.setPlanId(tTaskInspectionPlan.getId());
            tCheckCheckpoints.add(tCheckCheckpoint);
        }
        if (CollectionUtils.isNotEmpty(tCheckCheckpoints))
            tCheckCheckpointsService.insertTCheckCheckpointsByList(tCheckCheckpoints);

        QueryWrapper<TCheckCheckpoints> wrapper = new QueryWrapper<TCheckCheckpoints>().eq("plan_id", tTaskInspectionPlan.getId());
        Integer count = tCheckCheckpointsMapper.selectCount(wrapper);
        tTaskInspectionPlan.setPointNum(count.toString());
        tTaskInspectionPlan.setUpdaterCode(getUserId());
        tTaskInspectionPlan.setUpdatedate(new Date());
        return AjaxResult.success(tTaskInspectionPlanService.updateTTaskInspectionPlan(tTaskInspectionPlan));
    }


    @DeleteMapping("/removeCheckPoints")
    @Log(title = "检测计划删除", businessType = BusinessType.DELETE)
    public AjaxResult removeCheckPoints(@RequestBody TCheckCheckpoints tCheckCheckpoints) {
        tCheckCheckpointsService.deleteCheckpoints(tCheckCheckpoints);
        QueryWrapper<TCheckCheckpoints> wrapper = new QueryWrapper<TCheckCheckpoints>().eq("plan_id", tCheckCheckpoints.getPlanId());
        Integer count = tCheckCheckpointsMapper.selectCount(wrapper);
        TTaskInspectionPlan tTaskInspectionPlan = new TTaskInspectionPlan();
        tTaskInspectionPlan.setId(tCheckCheckpoints.getPlanId());
        tTaskInspectionPlan.setPointNum(count.toString());
        tTaskInspectionPlan.setUpdaterCode(getUserId());
        tTaskInspectionPlan.setUpdatedate(new Date());
        return AjaxResult.success(tTaskInspectionPlanService.updateTTaskInspectionPlan(tTaskInspectionPlan));
    }

    @PreAuthorize("@ss.hasPermi('task:plan:add')")
    @Log(title = "校验检测计划", businessType = BusinessType.INSERT)
    @PostMapping("/checkPlan")
    public AjaxResult checkPlan() {
        List<TTaskInspectionPlan> tTaskInspectionPlans = new ArrayList<>();
        int nowQuarter = DateUtils.getNowQuarter(); // 获取当前季度
        Calendar calendar = Calendar.getInstance(); // 获取当前时间
        String year = String.valueOf(calendar.get(Calendar.YEAR)); // 获取当前年份
        List<TCheckLawitems> tCheckLawitems = tCheckLawitemsService.selectTCheckLawitemsByLawStatus();
        for (TBasePlant tBasePlant : tBasePlantService.selectAllPlantName()) {// 查询已审核所有装置
            // 查询今年当前季度是否有监测计划
            QueryWrapper<TTaskInspectionPlan> plansWrapper = new QueryWrapper<TTaskInspectionPlan>().eq("plan_year", year).eq("plan_quarter", nowQuarter).eq("plant_id", tBasePlant.getPlantId()).eq("del_flag", 0);
            List<TTaskInspectionPlan> plans = tTaskInspectionPlanService.list(plansWrapper);
            if (CollectionUtils.isNotEmpty(plans)) {// 有则跳过
                continue;
            }
            TTaskInspectionPlan tTaskInspectionPlan = new TTaskInspectionPlan();
            tTaskInspectionPlan.setPlantId(tBasePlant.getPlantId());
            // 查询最后一个计划编号
            plansWrapper.clear();
            plansWrapper.eq("del_flag", 0).orderByDesc("plan_code");
            plans = tTaskInspectionPlanMapper.selectList(plansWrapper);
            int code = 0;
            if (CollectionUtils.isNotEmpty(plans)) {
                code = plans.get(0).getPlanCode() + 1;// 当前计划编号为前一个计划编号+1
            }
            // 检测计划编号
            tTaskInspectionPlan.setInspectionPlanNo("LTP_" + year + "_" + "0" + nowQuarter + "_" + code);
            // 检测计划名称
            tTaskInspectionPlan.setInspectionPlanName(tBasePlant.getPlantName() + "_" + year + "第" + nowQuarter + "季度检测计划");
            if (nowQuarter == 1 && nowQuarter == 3) {
                // 当前季度为1、3季度时，检测频次为一季一次
                tTaskInspectionPlan.setDetectionFrequency("2");
                // 检测结束时间为开始时间+3个月
                tTaskInspectionPlan.setEndTime(DateUtils.addTime(new Date(), Calendar.MONTH, 3));
            } else {
                // 当前季度为2、4季度时，检测频次为半年一次
                tTaskInspectionPlan.setDetectionFrequency("3");
                // 检测结束时间为开始时间+6个月
                tTaskInspectionPlan.setEndTime(DateUtils.addTime(new Date(), Calendar.MONTH, 6));
            }
            // 检测开始时间 TODO:改成传过来的
            tTaskInspectionPlan.setStartTime(new Date());
            // 统计当前装置下的所有(动)密封点
            QueryWrapper<TBasePoint> points = new QueryWrapper<TBasePoint>().eq("plant_id", tBasePlant.getPlantId()).eq("del_flag", 0).eq("approve_status", 2);

            // 当1、3季度时仅查询动密封点
            // 匹配法规标准
            if (nowQuarter == 1 && nowQuarter == 3) {
                Set<String> pointTypes = new HashSet<>();
                for (TCheckLawitems lawitem : tCheckLawitems) {
                    if (lawitem.getPlantType().equals(tBasePlant.getPlantType()) && lawitem.getDetectionFrequency().equals("2")) {
                        pointTypes.add(lawitem.getPointType());
                    }
                }
                points.in("point_type", pointTypes);
            }
            Integer count = tBasePointMapper.selectCount(points);
            if (count == 0) {
                // 当前计划中没有密封点时，跳过此计划
                continue;
            }
            tTaskInspectionPlan.setPointNum(count.toString());
            tTaskInspectionPlan.setCreaterCode(getUserId());
            tTaskInspectionPlan.setCreatedate(new Date());
            tTaskInspectionPlan.setUpdaterCode(getUserId());
            tTaskInspectionPlan.setUpdatedate(new Date());
            tTaskInspectionPlan.setPlanCode(code);
            tTaskInspectionPlan.setPlanYear(year);
            tTaskInspectionPlan.setPlanQuarter(String.valueOf(nowQuarter));
            tTaskInspectionPlans.add(tTaskInspectionPlan);

            // 新增检测点
            List<TCheckCheckpoints> tCheckCheckpoints = new ArrayList<>();
            List<TBasePoint> tBasePoints = tBasePointMapper.selectList(points);
            for (TBasePoint tBasePoint : tBasePoints) {

                TCheckCheckpoints tCheckCheckpoint = new TCheckCheckpoints();
                tCheckCheckpoint.setPointId(tBasePoint.getPointId());
                tCheckCheckpoint.setPlantName(tBasePlant.getPlantName());
                tCheckCheckpoint.setPlantId(tBasePlant.getPlantId());
                // TODO:需要优化，将区域名称和设备信息在新增密封点时直接存进去
//                tCheckCheckpoint.setRegionName(tBaseRegionService.selectTBaseRegionById(tBasePoint.getRegionId()).getRegionName());
                tCheckCheckpoint.setRegionId(tBasePoint.getRegionId());
                tCheckCheckpoint.setLayer(tBasePoint.getLayer());
//                TBaseDevice tBaseDevice = tBaseDeviceService.selectTBaseDeviceById(tBasePoint.getDevId());
//                tCheckCheckpoint.setDevName(tBaseDevice.getDevDescribe());
//                tCheckCheckpoint.setDevCode(tBaseDevice.getDevCode());
                tCheckCheckpoint.setDevId(tBasePoint.getDevId());
                tCheckCheckpoint.setGroupCode(tBasePoint.getGroupCode());
                tCheckCheckpoint.setExtendCode(tBasePoint.getExtendCode());
                tCheckCheckpoint.setPointType(tBasePoint.getPointType());
                tCheckCheckpoint.setCreaterCode(getUserId());
                tCheckCheckpoint.setCreatedate(new Date());
                tCheckCheckpoint.setUpdaterCode(getUserId());
                tCheckCheckpoint.setUpdatedate(new Date());
                tCheckCheckpoint.setPlantType(tBasePlant.getPlantType());
                tCheckCheckpoint.setMediumType(tBasePoint.getMediumType());
                tCheckCheckpoints.add(tCheckCheckpoint);
            }
            if (CollectionUtils.isNotEmpty(tCheckCheckpoints))
                tCheckCheckpointsService.insertTCheckCheckpointsByList(tCheckCheckpoints);
        }
        if (CollectionUtils.isNotEmpty(tTaskInspectionPlans)) {
            return toAjax(tTaskInspectionPlanService.insertTTaskInspectionPlanByList(tTaskInspectionPlans));
        }
        return AjaxResult.success();
    }


    /**
     * 修改检测计划
     */
    @PreAuthorize("@ss.hasPermi('task:plan:edit')")
    @Log(title = "检测计划修改", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody TTaskInspectionPlan tTaskInspectionPlan) {
        tTaskInspectionPlan.setUpdaterCode(getUserId());
        return toAjax(tTaskInspectionPlanService.updateTTaskInspectionPlan(tTaskInspectionPlan));
    }

    /**
     * 删除检测计划
     */
    @PreAuthorize("@ss.hasPermi('task:plan:remove')")
    @Log(title = "检测计划删除", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        for (Long id : ids) {
            TTaskInspection tTaskInspection = new TTaskInspection();
            tTaskInspection.setPlanId(id);
            if (CollectionUtils.isNotEmpty(tTaskInspectionService.selectTTaskInspectionList(tTaskInspection))) {
                return AjaxResult.error("不可删除已存在检测任务的计划！");
            }
        }
        return toAjax(tTaskInspectionPlanService.deleteTTaskInspectionPlanByIds(ids));
    }
}
