package com.taais.biz.controller;

import com.alibaba.fastjson2.JSON;
import com.taais.biz.constant.BizConstant;
import com.taais.biz.domain.TaskTrackResultBo;
import com.taais.biz.domain.bo.*;
import com.taais.biz.domain.dto.TaskResultDTO;
import com.taais.biz.service.*;
import com.taais.biz.service.impl.AlgorithmModelServiceImpl;
import com.taais.biz.service.impl.ObjectTraceMergeServiceImpl;
import com.taais.biz.service.impl.TargetIdentificationSubtaskDetailsServiceImpl;
import com.taais.biz.service.service.impl.ObjectMatchServiceImpl;
import com.taais.common.core.core.domain.CommonResult;
import com.taais.common.log.annotation.Log;
import com.taais.common.log.enums.BusinessType;
import com.taais.common.web.core.BaseController;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.Date;

/**
 * @author allen
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/public")
public class PublicController extends BaseController {
    private static final Logger log = LoggerFactory.getLogger(PublicController.class);
    @Resource
    private IVideoStableService videoStableService;
    @Resource
    private IToInfraredService toInfraredService;
    @Resource
    private ITrackSequenceService trackSequenceService;
    @Resource
    private ITargetDetectionService targetDetectionService;

    @Resource
    private IDataAugmentationService dataAugmentationService;

    @Resource
    IAlgorithmDataProcessService dataProcessService;
    @Resource
    IAlgorithmBizProcessService bizProcessService;

    @Resource
    TargetIdentificationSubtaskDetailsServiceImpl detailsService;

    @Resource
    private IAlgorithmTaskService algorithmTaskService;

    @Resource
    AlgorithmModelServiceImpl algorithmModelService;

    @Resource
    ObjectTraceMergeServiceImpl objectTraceMergeService;

    @Resource
    ObjectMatchServiceImpl objectMatchService;



    // todo: 2024080906
    @PostMapping("/taskResult")
    public CommonResult<Void> taskResult(@RequestBody TaskResultDTO resultDTO) {
        log.info("taskResult start,params:{}", resultDTO);
        String errorMsg = checkDTO(resultDTO);
        if (StringUtils.isNotEmpty(errorMsg)) {
            log.error("taskResult error,{}", errorMsg);
            return CommonResult.fail(errorMsg);
        }
        String bizType = resultDTO.getBizType();

        if(BizConstant.TYPE_DATA_BIZ_PROCESS.equals(bizType)){
            //errorMsg = bizProcessService.taskResult(resultDTO);
            TargetIdentificationSubtaskDetailsBo detailsBo = detailsService.getById(resultDTO.getBizId());
            detailsBo.setStatus(resultDTO.getStatus() != 200 ? BizConstant.TASK_STATUS_FAILED :
                resultDTO.getMsg().contains("finish") ? BizConstant.TASK_STATUS_SUCCEED : BizConstant.TASK_STATUS_PROCESSING);
            detailsBo.setRemarks(JSON.toJSONString(Arrays.asList(resultDTO.getMin(), resultDTO.getMax(), resultDTO.getAverage())));
            detailsBo.setEndTime(new Date());
            detailsBo.setCostSecond((detailsBo.getEndTime().getTime() - detailsBo.getStartTime().getTime()) / 1000);
            detailsService.update(detailsBo);

            // 保存模型
            if (BizConstant.TASK_STATUS_SUCCEED.equals(detailsBo.getStatus()) && detailsBo.getName().contains("训练")) {
                Long algorithmId = detailsBo.getAlgorithmId();
                AlgorithmModelBo bo = new AlgorithmModelBo();
                bo.setAlgorithmId(algorithmId);
                bo.setModelAddress("/profile/task" + detailsBo.getResultPath() + "weights/best.pt");
                bo.setModelName(detailsBo.getName() + "_" + detailsBo.getCreateTime().toString());
                algorithmModelService.insert(bo);
            }
        } else if (BizConstant.TYPE_OBJ_TRACE.equals(bizType)){
            ObjectTraceMergeBo bo = objectTraceMergeService.getById(resultDTO.getBizId());
            if (bo == null) {
                return CommonResult.fail("bo为null");
            }
            bo.setEndTime(new Date());
            bo.setCostSecond((bo.getEndTime().getTime() - bo.getStartTime().getTime()) / 1000);
            bo.setStatus(resultDTO.getStatus() == 200 ? BizConstant.TASK_STATUS_SUCCEED : BizConstant.TASK_STATUS_FAILED);
            objectTraceMergeService.update(bo);
        } else if (BizConstant.TYPE_OBJ_MATCH.equals(bizType)){
            ObjectMatchBo bo = objectMatchService.getById(resultDTO.getBizId());
            if (bo == null) {
                return CommonResult.fail("bo为null");
            }
            bo.setEndTime(new Date());
            bo.setCostSecond((bo.getEndTime().getTime() - bo.getStartTime().getTime()) / 1000);
            bo.setStatus(resultDTO.getStatus() == 200 ? BizConstant.TASK_STATUS_SUCCEED : BizConstant.TASK_STATUS_FAILED);
            objectMatchService.update(bo);
        } else if (BizConstant.TYPE_DATA_PROCESS.equals(bizType)) {
            errorMsg = dataProcessService.taskResult(resultDTO);
        } else {
            log.error("这种情况是不可能发生的,参数：{}",resultDTO);
            return CommonResult.fail("这种情况是不可能发生的");
        }

        if(StringUtils.isNotEmpty(errorMsg)){
            return CommonResult.fail(errorMsg);
        }
        return CommonResult.success();
    }

    private String checkDTO(TaskResultDTO resultDTO) {
        Integer status = resultDTO.getStatus();
        if(status != 200 && status != 500){
            return "status 只能是200或500";
        }
        Long bizId = resultDTO.getBizId();
        if(bizId == null){
            return "bizId 不能为null";
        }
        String bizType = resultDTO.getBizType();
        if(!BizConstant.TYPE_OBJ_MATCH.equals(bizType) && !BizConstant.TYPE_OBJ_TRACE.equals(bizType) && !BizConstant.TYPE_DATA_BIZ_PROCESS.equals(bizType) && !BizConstant.TYPE_DATA_PROCESS.equals(bizType)){
            return "status 只能是"+BizConstant.TYPE_DATA_BIZ_PROCESS+"或"+BizConstant.TYPE_DATA_PROCESS;
        }
        return null;
    }

    @GetMapping("/taskRun")
    public CommonResult<Void> taskRun() {
        algorithmTaskService.taskRun();
        return CommonResult.success();
    }

    @PostMapping("/videoStable/get_result")
    public CommonResult getResult(@Valid @RequestBody VideoStableStartResultBo videoStableStartResultBo) {
        return videoStableService.getResult(videoStableStartResultBo);
    }
    @PostMapping("/dataAugmentation/get_result")
    public CommonResult Result(@Valid @RequestBody DataAugmentationResultBo dataAugmentationStartResultBo) {
        return dataAugmentationService.getResult(dataAugmentationStartResultBo);
    }

    @PostMapping("/task/get_result")
    public CommonResult getResult(@Valid @RequestBody TaskTrackResultBo taskTrackResultBo) {
        if(BizConstant.BizType.TO_INFRARED.equals(taskTrackResultBo.getBizType())) {
            return toInfraredService.getResult(taskTrackResultBo);
        }
        else if(BizConstant.BizType.TRACK_SEQUENCE.equals(taskTrackResultBo.getBizType())) {
            return trackSequenceService.getResult(taskTrackResultBo);
        }
        else if(BizConstant.BizType.TARGET_DETECTION.equals(taskTrackResultBo.getBizType())) {
            return targetDetectionService.getResult(taskTrackResultBo);
        }
        else {
            return CommonResult.fail("业务类型不支持");
        }
    }
}
