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

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tuoheng.admin.entity.Business;
import com.tuoheng.admin.entity.Inspection;
import com.tuoheng.admin.entity.LiveChannel;
import com.tuoheng.admin.entity.Report;
import com.tuoheng.admin.enums.InspectionStatusEnum;
import com.tuoheng.admin.enums.MarkEnum;
import com.tuoheng.admin.mapper.*;
import com.tuoheng.admin.request.inspection.MissionStatusRequest;
import com.tuoheng.admin.service.third.dsp.IDspService;
import com.tuoheng.admin.vo.DspCallbackVo;
import com.tuoheng.admin.websocket.WebSocketService;
import com.tuoheng.common.core.utils.DateUtils;
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.stereotype.Service;

@Slf4j
@Service
public class UpdateFlightStatusService {

    @Autowired
    private InspectionMapper inspectionMapper;

    @Autowired
    private TenantMapper tenantMapper;

    @Autowired
    private LiveChannelMapper liveChannelMapper;

    @Autowired
    private BusinessMapper businessMapper;

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private IDspService dspService;

    @Autowired
    private WebSocketService webSocketService;

    public JsonResult updateFlightStatus(Inspection inspection, MissionStatusRequest missionStatusRequest) {
        Inspection inspectionUpdate = new Inspection();
        inspectionUpdate.setId(inspection.getId());
        JsonResult result = dspService.startAI(missionStatusRequest,inspection.getDspServiceInstId());
        if (0 != result.getCode()) {
            //如果调用DSP失败就直接失败！
            log.info("修改任务状态业务接口：调用DSP数据失败：{}", result.getMsg());
            inspectionUpdate.setStatus(InspectionStatusEnum.FLIGHT_FAILED.getCode());
            inspectionUpdate.setExecutionStartTime(DateUtils.now());
            inspectionMapper.updateById(inspectionUpdate);

            // 修改报告状态和开始时间
            this.updateReport(inspection);

            return result;
        }
        JSONObject jsonObject = (JSONObject) result.getData();
        DspCallbackVo dspCallbackVo = JSON.toJavaObject(jsonObject.getJSONObject("data"), DspCallbackVo.class);
        log.info("dsp响应体：{}", JacksonUtil.obj2StringPretty(dspCallbackVo));

        log.info("修改inspection status 开始");
        inspectionUpdate.setStatus(InspectionStatusEnum.IN_FLIGHT.getCode());
        inspectionUpdate.setExecutionStartTime(DateUtils.now());
        inspectionUpdate.setUpdateTime(DateUtils.now());
        log.info("inspectionUpdate：{}", inspectionUpdate);
        Integer count = inspectionMapper.updateStatus(inspectionUpdate);
        if (count <= 0) {
            log.info("修改inspection status 失败");
        } else {
            log.info("修改inspection status 成功");
        }
        log.info("修改inspection status 结束");

        // 处理通道数据
        this.liveChannelHandle(inspection, dspCallbackVo);

        // 将请求id和业务id消息存入数据库，用于监听获取任务信息
        this.businessHandle(inspection, dspCallbackVo);

        // 修改报告状态和开始时间
        this.updateReport(inspection);

        return JsonResult.success();
    }

    /**
     * 处理通道数据
     *
     * @param inspection
     * @param dspCallbackVo
     */
    private void liveChannelHandle(Inspection inspection, DspCallbackVo dspCallbackVo) {
        log.info("进入处理通道数据方法");
        //  通道表新增
        LiveChannel liveChannel = this.buildLiveChannel(inspection, dspCallbackVo);
        // 查验是否存在
        LiveChannel liveChannelQuery = liveChannelMapper.selectOne(new LambdaQueryWrapper<LiveChannel>()
                .eq(LiveChannel::getInspectionId, inspection.getId())
                .eq(LiveChannel::getMark, MarkEnum.VALID.getCode()));
        if (liveChannelQuery == null) {
            // 添加通道使用记录
            liveChannel.setCreateTime(DateUtils.now());
            liveChannelMapper.insert(liveChannel);
        } else {
            // 更新通道使用记录
            liveChannel.setId(liveChannelQuery.getId());
            liveChannelMapper.updateById(liveChannel);
        }

        webSocketService.accidentNotice(inspection.getTenantId());
    }

    private LiveChannel buildLiveChannel(Inspection inspection, DspCallbackVo dspCallbackVo) {
        LiveChannel liveChannel = new LiveChannel();
        liveChannel.setTenantId(inspection.getTenantId());
        liveChannel.setDeptId(inspection.getDeptId());
        liveChannel.setInspectionId(inspection.getId());
        liveChannel.setChannelCode("0");
        liveChannel.setPushUrl(dspCallbackVo.getPushUrl());
        liveChannel.setPullUrl(dspCallbackVo.getPlayUrl());
        liveChannel.setAipushUrl(dspCallbackVo.getAipushUrl());
        liveChannel.setAipullUrl(dspCallbackVo.getAiplayUrl());
        return liveChannel;
    }

    private void businessHandle(Inspection inspection, DspCallbackVo dspCallbackVo) {
        // 将请求id和业务id消息存入数据库，用于监听获取任务信息
        Business business = new Business();
        business.setTenantId(inspection.getTenantId());
        business.setMsgId(dspCallbackVo.getRequestId());
        business.setType(1);
        business.setTypeId(inspection.getId());
        business.setCreateTime(DateUtils.now());
        businessMapper.insert(business);
    }

    private void updateReport(Inspection inspection) {
        Report report = reportMapper.selectOne(Wrappers.<Report>lambdaQuery()
                .eq(Report::getInspectionId, inspection.getId())
                .eq(Report::getMark, MarkEnum.VALID.getCode()));
        if (ObjectUtil.isNull(report)) {
            log.info("该任务还没有生成报告，不需要修改报告的完成时间和状态");
            return;
        }
        report.setStatus(inspection.getStatus());
        report.setExecutionStartTime(inspection.getExecutionStartTime());
        reportMapper.updateById(report);
    }
}
