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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tuoheng.admin.entity.Business;
import com.tuoheng.admin.entity.Inspection;
import com.tuoheng.admin.entity.LiveChannel;
import com.tuoheng.admin.enums.MarkTypeEnum;
import com.tuoheng.admin.enums.TaskStatusEnum;
import com.tuoheng.admin.enums.code.inspection.EditInspectionStatusCodeEnum;
import com.tuoheng.admin.mapper.BusinessMapper;
import com.tuoheng.admin.mapper.InspectionMapper;
import com.tuoheng.admin.mapper.LiveChannelMapper;
import com.tuoheng.admin.mapper.TenantMapper;
import com.tuoheng.admin.request.inspection.MissionStatusRequest;
import com.tuoheng.admin.service.third.dsp.IDspService;
import com.tuoheng.admin.vo.DspCallbackVo;
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.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
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 IDspService dspService;

    @Value("${tuoheng.dsp-callback-url:}")
    private String dspCallbackUrl;

    public JsonResult updateFlightStatus(Inspection inspection, MissionStatusRequest missionStatusRequest) {
        Inspection inspectionUpdate = new Inspection();
        inspectionUpdate.setId(inspection.getId());
        JsonResult result = startAI(missionStatusRequest);

        if (0 != result.getCode()) {
            //如果调用DSP失败就直接失败！
            log.info("修改任务状态业务接口：调用DSP数据失败：{}", result.getMsg());

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

        inspectionUpdate.setStatus(TaskStatusEnum.INFLIGHT.getCode());
        inspectionMapper.updateById(inspectionUpdate);

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

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

        return JsonResult.success();
    }

    private JsonResult startAI(MissionStatusRequest missionStatusRequest) {
        //调用DSP接口
        JSONObject request = new JSONObject();
        JSONArray configList = new JSONArray();
        JSONObject instConfigMode = new JSONObject();
        instConfigMode.put("ename", "service_mode");
        instConfigMode.put("evalue", "1");
        configList.add(instConfigMode);
        JSONObject instConfigUrl = new JSONObject();
        instConfigUrl.put("ename", "callback_url");
        instConfigUrl.put("evalue", dspCallbackUrl);
        configList.add(instConfigUrl);
        request.put("serviceInstConfigList", configList);

        JSONArray reqList = new JSONArray();

        JSONObject instReqUrlPush = new JSONObject();
        instReqUrlPush.put("ename", "push_url");
        instReqUrlPush.put("evalue", missionStatusRequest.getPushUrl());
        reqList.add(instReqUrlPush);

        JSONObject instReqUrlPull = new JSONObject();
        instReqUrlPull.put("ename", "pull_url");
        instReqUrlPull.put("evalue", missionStatusRequest.getPullUrl());
        reqList.add(instReqUrlPull);

        request.put("serviceInstReqList", reqList);
        JSONObject responseJson = dspService.serviceInstApplication(request);
        if (responseJson.getIntValue("code") == 0) {
            String requestId = responseJson.getJSONObject("data").getString("requestId");
            log.info("dsp实时调用响应requestId：{}", requestId);

        } else {
            log.error("dsp实时调用失败：{}", responseJson);
            return JsonResult.error(EditInspectionStatusCodeEnum.TASK_ANALYSIS_FAILED.getCode(), EditInspectionStatusCodeEnum.TASK_ANALYSIS_FAILED.getMsg());
        }
        return JsonResult.success(responseJson);
    }

    private void liveChannelHandle(Inspection inspection, DspCallbackVo dspCallbackVo) {
        //  通道表新增
        LiveChannel liveChannel = this.buildLiveChannel(inspection, dspCallbackVo);
        // 查验是否存在
        LiveChannel liveChannelQuery = liveChannelMapper.selectOne(new LambdaQueryWrapper<LiveChannel>()
                .eq(LiveChannel::getInspectionId, inspection.getId())
                .eq(LiveChannel::getMark, MarkTypeEnum.VALID.getCode()));
        if (liveChannelQuery == null) {
            // 添加通道使用记录
            liveChannel.setCreateTime(DateUtils.now());
            liveChannelMapper.insert(liveChannel);
        } else {
            // 更新通道使用记录
            liveChannel.setId(liveChannelQuery.getId());
            liveChannelMapper.updateById(liveChannel);
        }
    }

    private LiveChannel buildLiveChannel(Inspection inspection, DspCallbackVo dspCallbackVo) {
        LiveChannel liveChannel = new LiveChannel();
        liveChannel.setTenantId(inspection.getTenantId());
        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);
    }
}
