/*
 * Author: Zev
 * 生成controller
 */
package com.tofly.gpsboot.controller.plan.daily;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tofly.common.core.entity.ResultRespone;
import com.tofly.common.log.annotation.ToFlyAppLog;
import com.tofly.gpsboot.common.Constant;
import com.tofly.gpsboot.controller.BaseController;
import com.tofly.gpsboot.exception.BusinessException;
import com.tofly.gpsboot.handler.plan.PlanExecuteStateHandler;
import com.tofly.gpsboot.handler.plan.PlanTimeoutHandler;
import com.tofly.gpsboot.service.paln.task.PlanFactoryService;
import com.tofly.gpsboot.service.paln.task.PlanService;
import com.tofly.pojo.plan.Plan;
import com.tofly.pojo.plan.PlanFactory;
import com.tofly.pojo.plan.dto.PlanDeviceDTO;
import com.tofly.pojo.plan.dto.PlanDto;
import com.tofly.pojo.plan.dto.PlanFactoryDto;
import com.tofly.pojo.plan.dto.UpdatePlanFactoryDto;
import com.tofly.pojo.plan.vo.PlanDetailVo;
import com.tofly.pojo.plan.vo.PlanVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 巡检计划详细信息
 *
 * @author admin
 * @date Thu Mar 18 00:00:00 CST 2021
 */
@RestController
@RequestMapping("/plan")
@Api(tags = "巡检计划详细信息")
@Slf4j
public class PlanController extends BaseController<Plan, PlanVo> {

    @Autowired
    private PlanService service;
    @Autowired
    private PlanExecuteStateHandler planExecuteStateHandler;
    @Autowired
    private PlanFactoryService planFactoryService;
    @Autowired
    private PlanTimeoutHandler planTimeoutHandler;

    @Autowired
    public PlanController(PlanService planService) {
        init(planService);
    }

    @GetMapping("/page")
    @ApiOperation(value = "分页查询")
    @ToFlyAppLog(title = "分页查询巡检计划详细信息")
    public ResultRespone<Page<PlanVo>> getPlanPage(Page page, @ModelAttribute PlanDto parDto) {
        ResultRespone<Page<PlanVo>> rest = new ResultRespone<>();

        Page<PlanVo> voPage = service.getPlanPage(page, parDto);
        rest.setResult(voPage);
        return rest;

    }

    @GetMapping("/getPlanTimeIntervalPage")
    @ApiOperation(value = "分页查询巡检计划满足时间范围内详细信息")
    @ToFlyAppLog(title = "分页查询巡检计划满足时间范围内详细信息")
    public ResultRespone<Page<PlanVo>> getPlanTimeIntervalPage(Page page, @ModelAttribute PlanDto parDto) {
        ResultRespone<Page<PlanVo>> rest = new ResultRespone<>();
        Page<PlanVo> voPage = service.getPlanTimeIntervalPage(page, parDto);
        rest.setResult(voPage);
        return rest;
    }

    @ApiOperation(value = "新增基本信息对象")
    @PostMapping("/save")
    @ToFlyAppLog(title = "新增巡检计划详细信息")
    public ResultRespone<Object> savePlan(@Valid @RequestBody PlanDto parDto, BindingResult result) {
        ResultRespone<Object> rest = new ResultRespone<>();
        // 数据校验 判空返回
        if (!Optional.ofNullable(super.validRest(rest, result)).isPresent()) {
            try {
                service.savaPlanInfo(parDto);
                //执行一次定时任务
                planExecuteStateHandler.planExecuteStateHandler(null);

            } catch (BusinessException e) {
                rest.setCode(e.getRetCd());
                rest.setMessage(e.getMsgDes());
            } catch (Exception e){
                e.printStackTrace();
                rest.setCode(-1);
                rest.setMessage(e.getMessage());
            }
        }
        return rest;

    }

    @ApiOperation(value = "修改基本信息")
    @PutMapping("/updata")
    @ToFlyAppLog(title = "修改巡检计划详细信息")
    public ResultRespone<Object> updateByIdPlan(@Valid @RequestBody PlanDto parDto, BindingResult result) {
        ResultRespone<Object> rest = new ResultRespone<>();
        // 数据校验 判空返回
        if (!Optional.ofNullable(super.validRest(rest, result)).isPresent()) {
            try {
                service.updatePlanInfo(parDto);
            } catch (BusinessException e) {
                rest.setCode(e.getRetCd());
                rest.setMessage(e.getMsgDes());
            }
        }
        return rest;

    }

    @ApiOperation(value = "修改计划状态")
    @PutMapping("/updatePlanState")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "planId", value = "planId", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "planState", value = "planState 3 正在执行 5 已开始未执行", required = true, dataType = "String"),
            @ApiImplicitParam(name = "userId", value = "userId", required = true, dataType = "Long"),
    })
    @ToFlyAppLog(title = "修改计划状态")
    public ResultRespone<Boolean> updatePlanState(Long planId, String planState, Long userId) {
        ResultRespone<Boolean> rest = new ResultRespone<>();
        try {
            service.updatePlanState(planId, planState, userId);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());
        }

        return rest;

    }


    @GetMapping("/{id}")
    @ApiOperation(value = "通过ID查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "Long")
    })
    @ToFlyAppLog(title = "通过ID查询巡检计划详细信息")
    public ResultRespone<PlanVo> getByIdPlan(@PathVariable Long id) {
        ResultRespone<PlanVo> rest = new ResultRespone<>();
        try {
            PlanVo planInfo = service.getPlanInfo(id);
            rest.setResult(planInfo);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());
        }
        return rest;
    }

    @ApiOperation(value = "通过ID批量删除基本信息对象")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "idList", value = "批量删除，多个id以逗号隔开", required = true, dataType = "String")
    })
    @DeleteMapping("/deleteByIds")
    @ToFlyAppLog(title = "通过ID批量删除巡检计划详细信息")
    public ResultRespone<Object> removeByIdListPlan(String idList) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<Long> longList = Arrays.stream(idList.split(Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                    .collect(Collectors.toList());
            service.deletePlanInfo(longList);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());
        }
        return rest;
    }

    @GetMapping("/getPlanDetail")
    @ApiOperation(value = "通过ID查询计划详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "计划id", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "flag", value = "是否展示部门下所有数据 是则填1 个人不填为空", required = false, dataType = "String")
    })
    @ToFlyAppLog(title = "通过ID查询计划详情")
    public ResultRespone<List<PlanDetailVo>> getPlanDetail(Long id, String flag) {
        ResultRespone<List<PlanDetailVo>> rest = new ResultRespone<>();
        try {
            List<PlanDetailVo> planDetail = service.getPlanDetail(id, flag);
            rest.setResult(planDetail);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());
        }
        return rest;
    }

    @ApiOperation(value = "批量更新计划巡检是否到位")
    @PostMapping(value = "/senPlanFactory")
    public ResultRespone<Object> senPlanFactory(PlanFactoryDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            Boolean aBoolean = planFactoryService.senPlanFactory(dto.getPlanFactoryList(), dto.getUserId());
            rest.setResult(aBoolean);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());
        } catch (Exception exception) {
            rest.setCode(-1);
            exception.printStackTrace();
            log.error(exception.getMessage());
        }
        return rest;
    }

    @ApiOperation(value = "更新计划巡检详情信息")
    @PostMapping(value = "/updatePlanFactoryInfo")
    public synchronized ResultRespone<Object> senPlanFactory(@RequestParam(value = "fileList", required = false) List<MultipartFile> fileList,
                                                             @RequestParam(value = "looksPhotoList", required = false) List<MultipartFile> looksPhoto,
                                                             @RequestParam(value = "pretreatmentPhotoList", required = false) List<MultipartFile> pretreatmentPhoto,
                                                             @RequestParam(value = "twoTankPhotoList", required = false) List<MultipartFile> twoTankPhoto,
                                                             @RequestParam(value = "outWaterOpenChannelList", required = false) List<MultipartFile> outWaterOpenChannel,
                                                             @RequestParam(value = "flowmeterList", required = false) List<MultipartFile> flowmeter,
                                                             @RequestParam(value = "sampleList", required = false) List<MultipartFile> sample,
                                                             @RequestParam(value = "aerationTankPhotoList", required = false) List<MultipartFile> aerationTankPhoto,
                                                             UpdatePlanFactoryDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        if (StringUtils.isBlank(dto.getIsDeviceInspect())) {
            dto.setIsDeviceInspect("1");
        }
        if (dto.getIsDeviceInspect().equals("0")) {
            PlanFactory planFactory = new PlanFactory();
            planFactory.setIsDeviceError(dto.getIsDeviceError());
            planFactory.setDeviceId(dto.getDeviceId());
            planFactory.setPlanId(dto.getPlanId());
            planFactory.setNote(dto.getNote());
            planFactory.setBelongStationId(dto.getBelongStationId());
            rest.setResult(planFactoryService.updatePlanFactory(fileList,
                    looksPhoto,
                    pretreatmentPhoto,
                    twoTankPhoto,
                    outWaterOpenChannel,
                    flowmeter,
                    sample,
                    aerationTankPhoto,
                    planFactory,
                    dto.getUserId(),
                    dto.getWorkingCondition(),
                    dto.getStationReport()));
            return rest;
        }
        try {
            if (dto.getBelongStationId() != null) {
                List<PlanFactory> list = planFactoryService.list(new QueryWrapper<PlanFactory>().lambda().eq(PlanFactory::getPlanId, dto.getPlanId()).eq(PlanFactory::getBelongStationId, dto.getBelongStationId()).orderByAsc(PlanFactory::getCreateTime));
                if (CollUtil.isNotEmpty(list)) {
                    PlanFactory planFactory = list.get(0);
                    if (planFactory.getDeviceId() != null) {
                        rest.setCode(-1);
                        rest.setMessage("巡检计划异常，厂站巡检数据存在设备ID");
                        return rest;
                    }
                    planFactory.setOverAddress(dto.getOverAddress());
                    planFactory.setNote(dto.getNote());
                    planFactory.setIsDeviceError(dto.getIsDeviceError());
                    planFactory.setOverUser(dto.getUserId());
                    rest.setResult(planFactoryService.updatePlanFactory(fileList,
                            looksPhoto,
                            pretreatmentPhoto,
                            twoTankPhoto,
                            outWaterOpenChannel,
                            flowmeter,
                            sample,
                            aerationTankPhoto,
                            planFactory,
                            dto.getUserId(),
                            dto.getWorkingCondition(),
                            dto.getStationReport()));
                }else {
                    rest.setCode(-1);
                    rest.setMessage("未查到对应计划下巡检设备");
                }
            } else {
                List<PlanFactory> list = planFactoryService.list(new QueryWrapper<PlanFactory>().lambda().eq(PlanFactory::getPlanId, dto.getPlanId()).eq(PlanFactory::getDeviceId, dto.getDeviceId()));
                if (CollUtil.isNotEmpty(list)) {
                    PlanFactory planFactory = list.get(0);
                    if (planFactory.getDeviceId() != null && planFactory.getIsOver().equals("1")) {
                        rest.setMessage("此设备已到位，不做处理");
                        return rest;
                    }
                    planFactory.setOverAddress(dto.getOverAddress());
                    planFactory.setNote(dto.getNote());
                    planFactory.setIsDeviceError(dto.getIsDeviceError());
                    planFactory.setOverUser(dto.getUserId());
                    rest.setResult(planFactoryService.updatePlanFactory(fileList,
                            looksPhoto,
                            pretreatmentPhoto,
                            twoTankPhoto,
                            outWaterOpenChannel,
                            flowmeter,
                            sample,
                            aerationTankPhoto,
                            planFactory,
                            dto.getUserId(),
                            dto.getWorkingCondition(),
                            dto.getStationReport()));
                }else {
                    rest.setCode(-1);
                    rest.setMessage("未查到对应计划下巡检设备");
                }
            }
        } catch (Exception exception) {
            rest.setCode(-1);
            exception.printStackTrace();
            log.error(exception.getMessage());
        }
        return rest;
    }

    @ApiOperation(value = "手动结束巡检计划")
    @PostMapping(value = "/updatePlanOver")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "planId", value = "计划id", required = true, dataType = "Long"),
    })
    public ResultRespone<Object> updatePlanOver(Long planId) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            rest.setResult(planFactoryService.updatePlanOver(planId));
        } catch (Exception exception) {
            rest.setCode(-1);
            rest.setMessage(exception.getMessage());
            log.error(exception.getMessage());
        }
        return rest;
    }

    @GetMapping("/getPlanDeviceList")
    @ApiOperation(value = "下发巡检计划查询对应设备信息")
    public ResultRespone<Page<PlanFactory>> getPlanDeviceList(Page page, PlanDeviceDTO dto) {
        ResultRespone<Page<PlanFactory>> rest = new ResultRespone<>();
        try {
            rest.setResult(planFactoryService.getPlanDeviceList(page, dto));
        } catch (Exception e) {
            rest.setCode(-1);
            e.printStackTrace();
        }
        return rest;
    }

    @GetMapping("/planTimeoutHand")
    @ApiOperation(value = "计划超时处理手动执行")
    public ResultRespone planTimeoutHand() {
        ResultRespone rest = new ResultRespone<>();
        try {
            planTimeoutHandler.planTimeoutHandler(null);
        } catch (Exception e) {
            rest.setCode(-1);
            e.printStackTrace();
        }
        return rest;
    }
}
