package com.tuoheng.admin.service.inspection.update.flyer;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tuoheng.admin.entity.domain.Inspection;
import com.tuoheng.admin.entity.domain.Report;
import com.tuoheng.admin.enums.TaskStatusEnum;
import com.tuoheng.admin.mapper.InspectionMapper;
import com.tuoheng.admin.mapper.ReportMapper;
import com.tuoheng.admin.entity.request.inspection.UpdateTaskByCodeRequest;
import com.tuoheng.common.core.exception.ServiceException;
import com.tuoheng.common.core.utils.JacksonUtil;
import com.tuoheng.common.core.utils.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 修改任务(修改任务状态和飞手信息)
 *
 * @author wanjing
 * @team tuoheng
 * @date 2022-12-23
 */
@Slf4j
@Service
public class UpdateFlyerService {

    @Autowired
    private InspectionMapper inspectionMapper;

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private OnlineIdentifService onlineIdentifService;

    @Autowired
    private OnlineCompleteService onlineCompleteService;

    @Autowired
    private OffLineCompleteService offLineCompleteService;

    /**
     * 修改任务(修改任务状态和飞手信息)
     *
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult update(UpdateTaskByCodeRequest request) {
        log.info("进入修改任务状态和飞手信息业务接口", JacksonUtil.obj2StringPretty(request));
        JsonResult result = this.check(request);
        if (0 != result.getCode()) {
            log.info("修改任务状态和飞手信息业务接口：校验失败：{}", result.getMsg());
            return result;
        }

        Inspection inspection = (Inspection) result.getData();

        Integer status = request.getStatus();
        log.info("修改任务状态和飞手信息业务接口：状态：{}", status);

        if (status == TaskStatusEnum.INFLIGHT.getCode()) {
            // 开始飞行
            log.info("修改任务状态和飞手信息业务接口：开始飞行");
            this.updateInflight(request, inspection);
        } else if (status == TaskStatusEnum.COMPLETE.getCode()) {
            // 飞行完成
            log.info("修改任务状态和飞手信息业务接口：飞行完成");
            this.updateComplete(request, inspection);
        }

        // 直播
        if (1 == inspection.getIsLive() && status == TaskStatusEnum.INFLIGHT.getCode()) {
            log.info("修改任务状态和飞手信息业务接口：直播");
            onlineIdentifService.handle(request, inspection);
        }

        // 离线
        if (2 == inspection.getIsLive() && status == TaskStatusEnum.COMPLETE.getCode()) {
            log.info("修改任务状态和飞手信息业务接口：离线");
            offLineCompleteService.handle(inspection);
        }

        // 如果直播状态，飞行完成修改状态为待关闭（如果任务分析状态为失败或成功，不修改通道状态）
        if (1 == inspection.getIsLive() && status == TaskStatusEnum.COMPLETE.getCode()
                && 4 != inspection.getAnalyseStatus()
                && 5 != inspection.getAnalyseStatus()
                && 6 != inspection.getAnalyseStatus()) {
            log.info("修改任务状态和飞手信息业务接口：直播状态，飞行完成修改状态为待关闭");
            onlineCompleteService.handle(inspection);
        }
        return JsonResult.success();
    }

    /**
     * 检查参数
     *
     * @param request
     * @return
     */
    private JsonResult check(UpdateTaskByCodeRequest request) {
        if (ObjectUtil.isNull(request.getStatus())) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "变量status不能为空");
        }
        if (ObjectUtil.isNull(request.getTaskCode())) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "变量id不能为空");
        }
        // 检查任务是否存在
        Inspection inspection = inspectionMapper.selectOne(new LambdaQueryWrapper<Inspection>()
                .eq(Inspection::getCode, request.getTaskCode())
                .eq(Inspection::getMark, 1));
        if (inspection == null) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "当前任务不存在");
        }
        return JsonResult.success(inspection);
    }

    private void updateInflight(UpdateTaskByCodeRequest request, Inspection inspection) {
        log.info("开始飞行，修改任务状态和信息");
        //直播填充盒子设备
        if (1 == inspection.getIsLive()) {
            inspection.setCloudBoxId(request.getCloudBoxId());
            inspection.setCloudBoxName(request.getCloudBoxName());
            inspection.setBoxSn(request.getBoxSn());
        }
        inspection.setEquipmentId(request.getEquipmentId());
        inspection.setEquipmentName(request.getEquipmentName());
        inspection.setEquipmentMountId(request.getEquipmentMountId());
        inspection.setEquipmentMountName(request.getEquipmentMountName());
        inspection.setEquipmentMountType(request.getEquipmentMountType());
        inspection.setEquipmentMountCode(request.getEquipmentMountCode());
        inspection.setStatus(request.getStatus());
        inspection.setFlightHand(request.getFlightHand());
        inspection.setFlightHandName(request.getFlightHandName());
        inspection.setExecutionStartTime(request.getFlightStartTime());

        // 更改
        inspectionMapper.updateById(inspection);

        // 修改报告中的信息
        this.updateReport(inspection);
    }

    private void updateComplete(UpdateTaskByCodeRequest request, Inspection inspection) {
        log.info("开始完成，修改任务状态和执行结束时间");
        inspection.setStatus(request.getStatus());
        inspection.setExecutionEndTime(request.getFlightEndTime());
        inspectionMapper.updateById(inspection);

        // 修改报告中的信息
        this.updateReport(inspection);
    }

    /**
     * 修改报告中的信息，因为报告中的信息是随时生成的，在修改任务信息时，需同步修改
     *
     * @param inspection
     */

    private void updateReport(Inspection inspection) {
        Report report = reportMapper.selectOne(Wrappers.<Report>lambdaQuery()
                .eq(Report::getInspectionId, inspection.getId())
                .eq(Report::getMark, 1));
        if (ObjectUtil.isNull(report)) {
            log.info("该任务还没有生成报告，不需要修改报告的完成时间和状态");
            return;
        }
        if (1 == inspection.getIsLive()) {
            report.setCloudBoxId(inspection.getCloudBoxId());
            report.setCloudBoxName(inspection.getCloudBoxName());
            report.setBoxSn(inspection.getBoxSn());
        }
        report.setEquipmentId(inspection.getEquipmentId());
        report.setEquipmentName(inspection.getEquipmentName());
        report.setEquipmentMountId(inspection.getEquipmentMountId());
        report.setEquipmentMountName(inspection.getEquipmentMountName());
        report.setFlightHand(inspection.getFlightHand());
        report.setFlightHandName(inspection.getFlightHandName());
        report.setStatus(inspection.getStatus());
        report.setExecutionStartTime(inspection.getExecutionStartTime());
        report.setExecutionEndTime(inspection.getExecutionEndTime());
        reportMapper.updateById(report);
    }

}
