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

import cn.hutool.core.collection.CollectionUtil;
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.common.system.IsPlanChildStateEnum;
import com.tofly.gpsboot.common.system.PlanStateEnum;
import com.tofly.gpsboot.controller.BaseController;
import com.tofly.gpsboot.exception.BusinessException;
import com.tofly.gpsboot.handler.plan.PlanExecuteStateHandler;
import com.tofly.gpsboot.service.paln.task.PlanService;
import com.tofly.gpsboot.service.paln.task.PlanchildService;
import com.tofly.pojo.plan.Plan;
import com.tofly.pojo.plan.Planchild;
import com.tofly.pojo.plan.dto.PlanDto;
import com.tofly.pojo.plan.vo.PlanDetailVo;
import com.tofly.pojo.plan.vo.PlanVo;
import com.tofly.pojo.plan.vo.TreeVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

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

    @Autowired
    private PlanService service;
    @Autowired
    private PlanchildService planchildService;
    @Autowired
    private PlanExecuteStateHandler planExecuteStateHandler;

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

    @GetMapping("/getReportPlanYear")
    @ApiOperation(value = "本年度巡检计划统计")
    @ToFlyAppLog(title = "本年度巡检计划统计")
    public ResultRespone getReportPlanYear() {

        return ResultRespone.success(service.getReportPlanYear());
    }


    @GetMapping("/getReportPlanMonth")
    @ApiOperation(value = "本月巡检计划统计")
    @ToFlyAppLog(title = "本月巡检计划统计")
    public ResultRespone getReportPlanMonth() {

        return ResultRespone.success(service.getReportPlanMonth());
    }

    @GetMapping("/page")
    @ApiOperation(value = "分页查询")
    @ToFlyAppLog(title = "分页查询巡检计划详细信息")
    public ResultRespone<Page<PlanVo>> getPlanPage(Page page, @ModelAttribute PlanDto parDto) {
        ResultRespone<Page<PlanVo>> rest = new ResultRespone<>();
        try {
            Page<PlanVo> voPage = service.getPlanPage(page, parDto);
            rest.setResult(voPage);
            return rest;
        } catch ( BusinessException e ) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());
        }
        return rest;
    }

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

    @ApiOperation(value = "新增基本信息对象")
    @PostMapping("/save")
    @ToFlyAppLog(title = "新增巡检计划详细信息")
    public ResultRespone<Object> savePlan(@RequestBody @Validated PlanDto parDto) {
        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());
        }
//        }
        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());
        } catch ( Exception exception ) {
            exception.printStackTrace();
        }

        return rest;

    }

    @GetMapping("/getAppUserPlanList")
    @ApiOperation(value = "app获取巡检计划执行各页面数据")
    public ResultRespone getAppUserPlanList(Long inspectUsers, String planStates) {
        // 12 为不可执行页面  3为正在执行页面  2,3,5,7,9其他为可执行页面
        List<Plan> planAll = new ArrayList<>();
        List<String> planStateList = Arrays.stream(planStates.split(Constant.CSV))
                .collect(Collectors.toList());
        //查询近期完成数据
        if (PlanStateEnum.PLAN_STATE_PLAN_COMPLETE.getCode().equals(planStates)) {

            Date date = new Date();

            List<Plan> listPlan = service.list(new QueryWrapper<Plan>().lambda()
                    .ge(Plan::getPlanEnddate, date)
                    .le(Plan::getPlanBegindate, date)
                    .eq(Plan::getPlanState, PlanStateEnum.PLAN_STATE_PLAN_COMPLETE.getCode()));


            Set<Long> planIdSet = listPlan.stream().filter(Objects::nonNull).map(Plan::getId).collect(Collectors.toSet());

            if (CollectionUtil.isNotEmpty(planIdSet)) {
                Set<Long> planIdList = planchildService.list(new QueryWrapper<Planchild>().lambda()
                                .in(Planchild::getPlanId, planIdSet)
                                .eq(Planchild::getRespUser, inspectUsers)
                                .eq(Planchild::getPlanState, IsPlanChildStateEnum.PLAN_STATE_PLAN_COMPLETE.getCode()))
                        .stream().map(Planchild::getPlanId).collect(Collectors.toSet());
                listPlan.forEach(plan -> {
                    Long id = plan.getId();
                    if (planIdList.contains(id)) {
                        planAll.add(plan);
                    }
                });
            }

            return ResultRespone.success(service.viewConversion(planAll));
        }

        // 获取满足条件的主计划列表
        List<Plan> list = service.list(new QueryWrapper<Plan>().lambda().in(Plan::getPlanState, planStateList));

        if (PlanStateEnum.PLAN_STATE_UNENFORCEABLE.getCode().equals(planStates) || planStateList.size() > 1) {
            // 获取满足条件的子计划列表
            Set<Long> collect = list.stream().map(Plan::getId).collect(Collectors.toSet());
            // 获取正在执行的
            if (collect.size() > 0) {
                Set<Long> planIdList = planchildService.getChileInfo(collect, inspectUsers)
                        .stream().map(Planchild::getPlanId).collect(Collectors.toSet());
                list.forEach(plan -> {
                    Long id = plan.getId();
                    if (planIdList.contains(id)) {
                        planAll.add(plan);
                    }
                });
            }

        } else if (PlanStateEnum.PLAN_STATE_BEING_PERFORMED.getCode().equals(planStates)) {

            planStateList.add("2");
            List<Plan> listPlan = service.list(new QueryWrapper<Plan>().lambda().in(Plan::getPlanState, planStateList));
            // 获取满足条件的子计划列表
            Set<Long> collect = listPlan.stream().map(Plan::getId).collect(Collectors.toSet());
            // 获取正在执行的
            if (collect.size() > 0) {
                Set<Long> planIdList = planchildService.list(new QueryWrapper<Planchild>().lambda()
                                .in(Planchild::getPlanId, collect)
                                .eq(Planchild::getRespUser, inspectUsers)
                                .eq(Planchild::getPlanState, IsPlanChildStateEnum.PLAN_STATE_BEING_PERFORMED.getCode())
                        )
                        .stream().map(Planchild::getPlanId).collect(Collectors.toSet());
                listPlan.forEach(plan -> {
                    Long id = plan.getId();
                    if (planIdList.contains(id)) {
                        planAll.add(plan);
                    }
                });
            }
        }
        return ResultRespone.success(service.viewConversion(planAll));
    }


    @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"),
            @ApiImplicitParam(name = "deptId", value = "跨部门id", required = false, dataType = "Long")
    })
    @ToFlyAppLog(title = "通过ID查询计划详情")
    public ResultRespone<List<PlanDetailVo>> getPlanDetail(Long id, String flag, Long deptId) {
        ResultRespone<List<PlanDetailVo>> rest = new ResultRespone<>();
        try {
            List<PlanDetailVo> planDetail = service.getPlanDetail(id, flag, deptId);
            rest.setResult(planDetail);
        } catch ( BusinessException e ) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());
        }
        return rest;
    }

    @GetMapping("/deptInspectTree")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "isQueryGroup", value = "是否查询巡检组（0否1是）", required = true, dataType = "String"),
    })
    @ApiOperation(value = "获取部门巡检树")
    @ToFlyAppLog(title = "获取部门巡检树")
    public ResultRespone<List<TreeVo>> deptInspectTree(String isQueryGroup) {
        return ResultRespone.success(service.deptInspectTree(isQueryGroup));
    }
}
