package com.yfd.platform.modules.patroltask.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.annotation.Log;
import com.yfd.platform.config.HttpServerConfig;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.constant.SystemCode;
import com.yfd.platform.modules.basedata.domain.SubstationPatroldevice;
import com.yfd.platform.modules.basedata.service.ISubstationPatroldeviceService;
import com.yfd.platform.modules.basedata.service.ISubstationService;
import com.yfd.platform.modules.patroltask.domain.Task;
import com.yfd.platform.modules.patroltask.domain.TaskTodo;
import com.yfd.platform.modules.patroltask.service.ITaskService;
import com.yfd.platform.modules.patroltask.service.impl.QuartzMultiTaskManage;
import com.yfd.platform.modules.robotapi.service.IStationRobotService;
import com.yfd.platform.utils.HttpRESTfulUtils;
import com.yfd.platform.utils.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.quartz.CronExpression;
import org.quartz.TriggerUtils;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.Year;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * <p>
 * 巡视任务表 前端控制器
 * </p>
 *
 * @since 2023-04-08
 */
@RestController
@RequestMapping("/patroltasks/task")
@Api(value = "TaskController", tags = "巡视任务")
public class TaskController {

    @Resource
    private ITaskService taskService;
    @Resource
    private QuartzMultiTaskManage quartztaskManage;
    @Resource
    private IStationRobotService stationRobotService;
    @Resource
    private HttpServerConfig httpServerConfig;
    @Resource
    private HttpRESTfulUtils httpRESTfulUtils;
    @Resource
    private ISubstationPatroldeviceService substationPatroldeviceService;


    @GetMapping("/getTaskList")
    @ApiOperation("分页查询巡视任务")
    public ResponseResult getTaskList(Page<Map<String, Object>> page,String stationId, String type, String taskName, String enable,
                                      String taskType,
                                      String taskTodoType,
                                      String startDate,
                                      String endDate) throws ParseException {
        if (StrUtil.isBlank(type)) {
            return ResponseResult.error("参数为空");
        }
        Page<Map<String, Object>> taskList = taskService.getTaskList(page,stationId, startDate, endDate, type, taskName, enable
                , taskType, taskTodoType);
        return ResponseResult.successData(taskList);
    }

    @Log(module = "巡视任务", value = "新增巡视任务", type = "1")
    @PostMapping("/addTask")
    @ApiOperation("新增巡视任务")
    public ResponseResult addTask(@RequestBody Task task) {
        String taskCode = task.getTaskCode();
        String type = task.getType();
        int count =
                taskService.count(new LambdaQueryWrapper<Task>().eq(Task::getType, type).eq(Task::getTaskCode, taskCode).ne(Task::getDatastatus, "3"));
        if (count > 0) {
            return ResponseResult.error("该巡视任务已经存在");
        }
        String cronValue = task.getCronValue();
        String taskTodoType = task.getTaskTodoType();
        if ("3".equals(taskTodoType) && !CronExpression.isValidExpression(cronValue)) {
            return ResponseResult.error("cron表达式格式错误");
        }
        // 设置优先级根据任务类型判断
        String taskType = task.getTaskType();
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String format = now.format(fmt);
        task.setCreateTime(format);
        String priority = task.getPriority();
        if (StrUtil.isBlank(priority)) {
            task.setPriority(taskType);
        }
        task.setIsReport("0");
        boolean ok = taskService.addTask(task);
        if (ok) {
            return ResponseResult.success();
        } else {
            return ResponseResult.error("新增失败");
        }
    }

    @GetMapping("/getTaskById")
    @ApiOperation("根据Id查询巡视任务")
    public ResponseResult getTaskById(String taskId) {
        Task task = taskService.getById(taskId);
        return ResponseResult.successData(task);
    }

    @GetMapping("/getBindInfoById")
    @ApiOperation("根据Id查询关联信息")
    public ResponseResult getBindInfoById(String taskId, String deviceLevel) {
        List<Map<String, Object>> mapList = taskService.getBindInfoById(taskId, deviceLevel);
        return ResponseResult.successData(mapList);
    }

    @GetMapping("/getTaskByStationId")
    @ApiOperation("根据变电站Id查询巡视任务")
    public ResponseResult getTaskByStationId(String stationId) {
        List<Task> taskList = taskService.getTaskByStationId(stationId);
        return ResponseResult.successData(taskList);
    }

    @Log(module = "巡视任务", value = "巡视任务关联设备", type = "1")
    @PostMapping("/bindTask")
    @ApiOperation("巡视任务关联设备")
    public ResponseResult bindTask(@RequestBody Task task) {
        task.setLastmodifier(SecurityUtils.getCurrentUsername());
        String deviceList = task.getDeviceList();
        if (StrUtil.isNotBlank(deviceList)) {
            task.setDeviceLevel(0);
        }
        task.setLastmodifydate(new Timestamp(DateUtil.current()));
        boolean ok = taskService.updateById(task);
        if (ok) {
            return ResponseResult.success();
        } else {
            return ResponseResult.error("关联失败");
        }
    }

    @Log(module = "巡视任务", value = "修改巡视任务", type = "1")
    @PostMapping("/updateTask")
    @ApiOperation("修改巡视任务")
    public ResponseResult updateTask(@RequestBody Task task) {
        String taskCode = task.getTaskCode();
        String taskId = task.getTaskId();
        int count =
                taskService.count(new LambdaQueryWrapper<Task>().ne(Task::getTaskId, taskId).eq(Task::getTaskCode,
                        taskCode).ne(Task::getDatastatus, "3"));
        if (count > 0) {
            return ResponseResult.error("该巡视任务已经存在");
        }
        if (!"1".equals(task.getDatastatus())) {
            return ResponseResult.error("初始创建状态可进行编辑");
        }
        String cronValue = task.getCronValue();
        String taskTodoType = task.getTaskTodoType();
        if ("3".equals(taskTodoType) && !CronExpression.isValidExpression(cronValue)) {
            return ResponseResult.error("cron表达式格式错误");
        }
        // 设置优先级根据任务类型判断
        String taskType = task.getTaskType();
        String priority = task.getPriority();
        if (StrUtil.isBlank(priority)) {
            task.setPriority(taskType);
        }
        String deviceList = task.getDeviceList();
        if (StrUtil.isBlank(deviceList)) {
            task.setDeviceLevel(0);
        }
        task.setLastmodifier(SecurityUtils.getCurrentUsername());
        task.setLastmodifydate(new Timestamp(DateUtil.current()));
        boolean ok = taskService.updateById(task);
        if (ok) {
            return ResponseResult.success();
        } else {
            return ResponseResult.error("修改失败");
        }
    }

    @Log(module = "巡视任务", value = "设置巡视任务是否启用", type = "1")
    @PostMapping("/setTaskStatus")
    @ApiOperation("设置巡视任务是否启用")
    public ResponseResult setTaskStatus(String taskId, String enable) throws ParseException {
        Task task = taskService.getById(taskId);
        String datastatus = task.getDatastatus();
        if (!"2".equals(datastatus)) {
            return ResponseResult.error("复核后才可以改变状态");
        }
        if (StrUtil.isBlank(task.getDeviceList())) {
            return ResponseResult.error("未关联启用状态不可操作");
        }
        task.setIsenable(enable);
        boolean ok = taskService.updateById(task);
        if ("1".equals(enable)) {
            //启用
            String taskTodoType = task.getTaskTodoType();
            if (StrUtil.isNotBlank(task.getRobotCode())) {
                //机器人任务启动
                List<SubstationPatroldevice> list = substationPatroldeviceService.list(new LambdaQueryWrapper<SubstationPatroldevice>().eq(SubstationPatroldevice::getPatroldeviceCode, task.getRobotCode()));
                if (list.size() > 0) {
                    SubstationPatroldevice substationPatroldevice = list.get(0);
                    if ("15".equals(substationPatroldevice.getType())) {
                        // 创建机巢任务
                        if ("1".equals(taskTodoType)) {
                            TaskTodo taskTodo = taskService.createRunNowTask(task);
                        } else {
                            //定期或者周期执行
                            taskService.createTodoTaskList(task);
                        }
                    } else {
                        stationRobotService.sendCommand(substationPatroldevice.getInternationalId(), httpServerConfig.getPatrolServerid(), substationPatroldevice.getInternationalId(), SystemCode.TYPE_TASK_CONTROL_CODE.getCode(), SystemCode.COMMAND_TASK_START_CODE.getCode(), task.getTaskCode(), null);
                    }

                }
                return ResponseResult.success();
            }
            if ("1".equals(taskTodoType)) {
                //立即执行
                TaskTodo taskTodo = taskService.createRunNowTask(task);
                //立即执行当前任务
                quartztaskManage.addJob(taskTodo);
            } else {
                //定期或者周期执行
                taskService.createTodoTaskList(task);
            }
        } else if ("2".equals(enable)) {
            taskService.deleteTodoTasks(task);
        }
        if (ok) {
            return ResponseResult.success();
        } else {
            return ResponseResult.error("修改失败");
        }
    }

    @Log(module = "巡视任务", value = "巡视任务上报", type = "1")
    @PostMapping("/setReportTask")
    @ApiOperation("巡视任务上报")
    public ResponseResult setReportTask(String taskId) {
        if (StrUtil.isBlank(taskId)) {
            return ResponseResult.error("参数为空");
        }
        String[] split = taskId.split(",");
        try {
            for (String id : split) {
                Task task = taskService.getById(id);
                task.setIsReport("1");
                task.setLastmodifier(SecurityUtils.getCurrentUsername());
                task.setLastmodifydate(new Timestamp(DateUtil.current()));
                taskService.updateById(task);
            }
        } catch (Exception e) {
            throw new RuntimeException("上报失败");
        }
        return ResponseResult.success();
    }

    @Log(module = "巡视任务", value = "复核巡视任务", type = "1")
    @PostMapping("/checkTask")
    @ApiOperation("复核巡视任务")
    public ResponseResult checkTask(String taskId) throws ParseException {
        Task task = taskService.getById(taskId);
        if (!"1".equals(task.getDatastatus())) {
            return ResponseResult.error("初始创建状态可进行审核");
        }
        if (StrUtil.isNotBlank(task.getRobotCode())&&StrUtil.isBlank(task.getDockInfo())) {

            String fixedStartTime = task.getFixedStartTime();
            if (StrUtil.isBlank(fixedStartTime) && "1".equals(task.getTaskTodoType())) {
                fixedStartTime = DateUtil.now();
            }
            // 任务发送数据
            JSONObject jsonObject = new JSONObject();
            jsonObject.putOnce("type", task.getType());
            jsonObject.putOnce("task_code", task.getTaskCode());
            jsonObject.putOnce("task_name", task.getTaskName());
            jsonObject.putOnce("priority", task.getPriority());
            jsonObject.putOnce("device_level", task.getDeviceLevel());
            jsonObject.putOnce("device_list", task.getDeviceList());
            jsonObject.putOnce("fixed_start_time", fixedStartTime);
            jsonObject.putOnce("cycle_month", task.getCycleMonth());
            jsonObject.putOnce("cycle_week", task.getCycleWeek());
            jsonObject.putOnce("cycle_execute_time", task.getCycleExecuteTime());
            String cycle_start_time = "";
            String cycle_end_time = "";
            if ("3".equals(task.getTaskTodoType())) {
                CronTriggerImpl cronTriggerImpl = new CronTriggerImpl();
                cronTriggerImpl.setCronExpression(task.getCronValue());
                Calendar calendar = Calendar.getInstance();
                Date begindate = calendar.getTime();  //当前时间
                // 获取当前年份
                Year currentYear = Year.now();

                // 获取当前年份的最后一天（LocalDateTime会默认带上00:00:00的时间）
                LocalDateTime lastDayOfYear = YearMonth.of(currentYear.getValue(), 12).atEndOfMonth().atStartOfDay();
                lastDayOfYear = lastDayOfYear.plusHours(23).plusMinutes(59).plusSeconds(59);
                Date to = Date.from(lastDayOfYear.atZone(ZoneId.systemDefault()).toInstant());
                // 如果需要带上具体的时间（比如23:59:59），则进行相应的调整
                List<Date> dates = TriggerUtils.computeFireTimesBetween(cronTriggerImpl, null, begindate, to);
                List<Date> dateList = new ArrayList<>();
                for (Date date : dates) {
                    if (StrUtil.isNotEmpty(task.getInvalidStartTime()) && StrUtil.isNotEmpty(task.getInvalidEndTime())) {
                        if (DateUtil.parse(task.getInvalidStartTime()).isBefore(date) && DateUtil.parse(task.getInvalidEndTime()).isAfter(date)) {
                            continue;
                        }
                    }
                    dateList.add(date);
                }
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                if (dateList.size() > 0) {
                    Date startdate = dateList.get(0);
                    Date enddate = dateList.get(dateList.size() - 1);
                    cycle_start_time = sdf.format(startdate);
                    cycle_end_time = sdf.format(enddate);
                }
            }
            jsonObject.putOnce("cycle_start_time", cycle_start_time);
            jsonObject.putOnce("cycle_end_time", cycle_end_time);
            jsonObject.putOnce("interval_number", task.getIntervalNumber());
            jsonObject.putOnce("interval_type", task.getIntervalType());
            jsonObject.putOnce("interval_execute_time", task.getIntervalExecuteTime());
            jsonObject.putOnce("interval_start_time", task.getIntervalStartTime());
            jsonObject.putOnce("interval_end_time", task.getIntervalEndTime());
            jsonObject.putOnce("invalid_start_time", task.getInvalidStartTime());
            jsonObject.putOnce("invalid_end_time", task.getInvalidEndTime());
            jsonObject.putOnce("isenable", "0");
            jsonObject.putOnce("creator", task.getCreator());
            jsonObject.putOnce("create_time", task.getCreateTime());

            List<SubstationPatroldevice> list = substationPatroldeviceService.list(new LambdaQueryWrapper<SubstationPatroldevice>().eq(SubstationPatroldevice::getPatroldeviceCode, task.getRobotCode()));
            if (list.size() > 0) {
                SubstationPatroldevice substationPatroldevice = list.get(0);
                stationRobotService.sendCommand(substationPatroldevice.getInternationalId(), httpServerConfig.getPatrolServerid(), substationPatroldevice.getInternationalId(),
                        SystemCode.TYPE_TASK_ISSUED_CODE.getCode(),  SystemCode.COMMAND_TASK_CONFIG_CODE.getCode(), task.getStationCode(), jsonObject.toString());
            }
            if ("1".equals(task.getTaskTodoType())) {
                // 如果是机器人立即执行任务复合，就把状态改成启用
                task.setIsenable("1");
            }
        }
        task.setDatastatus("2");
        task.setCreator(SecurityUtils.getCurrentUsername());
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime now = LocalDateTime.now();
        String format = now.format(fmt);
        task.setCreateTime(format);
        boolean ok = taskService.updateById(task);
        if (ok) {
            return ResponseResult.success();
        } else {
            return ResponseResult.error("复核失败");
        }
    }

    @Log(module = "巡视任务", value = "删除巡视任务", type = "1")
    @PostMapping("/deleteTaskById")
    @ApiOperation("删除巡视任务")
    public ResponseResult deleteTaskById(String taskId) {
        String[] split = taskId.split(",");
        for (String id : split) {
            Task task = taskService.getById(id);
            if ("1".equals(task.getIsenable()) || "2".equals(task.getDatastatus())) {
                return ResponseResult.error("删除失败，已含有复核生效的巡视任务");
            }
        }
        for (String id : split) {
            Task task = taskService.getById(id);
            task.setDatastatus("3");
            taskService.updateById(task);
        }
        return ResponseResult.success();
    }

}
