package com.taais.biz.controller;

import java.io.File;
import java.util.*;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.taais.biz.constant.BizConstant;
import com.taais.biz.domain.ObjectTraceMerge;
import com.taais.biz.domain.bo.ObjectTraceMergeBo;
import com.taais.biz.domain.vo.ObjectTraceMergeVo;
import com.taais.biz.service.IObjectTraceMergeService;
import com.taais.biz.service.impl.ObjectTraceMergeServiceImpl;
import com.taais.common.core.config.TaaisConfig;
import com.taais.common.core.utils.MapstructUtils;
import com.taais.common.core.utils.uuid.UUID;
import com.taais.system.domain.vo.SysOssVo;
import com.taais.system.service.ISysOssService;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import cn.dev33.satoken.annotation.SaCheckPermission;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.taais.common.core.core.domain.CommonResult;
import com.taais.common.excel.utils.ExcelUtil;
import com.taais.common.log.annotation.Log;
import com.taais.common.log.enums.BusinessType;
import com.taais.common.web.annotation.RepeatSubmit;
import com.taais.common.web.core.BaseController;
import jakarta.annotation.Resource;

import com.taais.common.core.core.page.PageResult;

import static com.taais.biz.constant.BizConstant.*;

/**
 * 多物体融合轨迹识别Controller
 *
 * @author km
 * 2024-10-16
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/demo/traceMerge")
@Slf4j
public class ObjectTraceMergeController extends BaseController {
    @Resource
    private ObjectTraceMergeServiceImpl objectTraceMergeService;

    @Resource
    private ISysOssService sysOssService;

    /**
     * 查询多物体融合轨迹识别列表
     */
    @SaCheckPermission("demo:traceMerge:list")
    @GetMapping("/list")
    public CommonResult<PageResult<ObjectTraceMergeVo>> list(ObjectTraceMergeBo objectTraceMergeBo) {
        return CommonResult.success(objectTraceMergeService.selectPage(objectTraceMergeBo));
    }

    /**
     * 导出多物体融合轨迹识别列表
     */
    @SaCheckPermission("demo:traceMerge:export")
    @Log(title = "多物体融合轨迹识别", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ObjectTraceMergeBo objectTraceMergeBo) {
        List<ObjectTraceMergeVo> list = objectTraceMergeService.selectList(objectTraceMergeBo);
        ExcelUtil.exportExcel(list, "多物体融合轨迹识别", ObjectTraceMergeVo.class, response);
    }

    /**
     * 获取多物体融合轨迹识别详细信息
     */
    @SaCheckPermission("demo:traceMerge:query")
    @GetMapping(value = "/{id}")
    public CommonResult<ObjectTraceMergeVo> getInfo(@PathVariable Long id) {
        return CommonResult.success(objectTraceMergeService.selectById(id));
    }


    /**
     * 新增多物体融合轨迹识别
     */
    @SaCheckPermission("demo:traceMerge:add")
    @Log(title = "多物体融合轨迹识别", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping
    public CommonResult<Void> add(@Validated @RequestBody ObjectTraceMergeBo objectTraceMergeBo) {
        String uuid = UUID.randomUUID().toString();
        String resultPath = DOCKER_MAT_TASK + "/" + uuid;
        objectTraceMergeBo.setResultPath(resultPath);
        objectTraceMergeBo.setStatus(TASK_STATUS_PENDING);

        String modelAddress = objectTraceMergeBo.getPreprocessPath();
        SysOssVo vo = sysOssService.getById(Long.parseLong(modelAddress));
        objectTraceMergeBo.setPreprocessPath((TaaisConfig.getProfile() + vo.getUrl().split("/profile")[1]));

        boolean inserted = objectTraceMergeService.insert(objectTraceMergeBo);
        if (!inserted) {
            return CommonResult.fail("新增多物体融合轨迹识别记录失败！");
        }
        // 创建结果路径
        try {
            File dir = new File(DOCKER_BASE_PATH + resultPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }
        } catch (Exception e) {
            return CommonResult.fail("创建结果路径失败！");
        }

        return CommonResult.success();
    }

    @PostMapping("/execute")
    public CommonResult<Void> execute(@RequestBody Map<String, String> _params) {
        if (!_params.containsKey("taskId")) {
            return CommonResult.fail("请提供任务ID!");
        }
        String taskId = _params.get("taskId");
        ObjectTraceMergeBo vo = objectTraceMergeService.getById(Long.valueOf(taskId));
        if (vo == null) {
            return CommonResult.fail("未找到任务内容!");
        }
        if (TASK_STATUS_SUCCEED.equals(vo.getStatus())) {
            return CommonResult.fail("任务已经执行完毕!");
        }
        if (!(TASK_STATUS_PENDING.equals(vo.getStatus()) || TASK_STATUS_FAILED.equals(vo.getStatus()))) {
            return CommonResult.fail("任务正在执行中!");
        }
        vo.setStartTime(new Date());

        Map<String, String> params = new HashMap<>();
        params.put("bizType", TYPE_OBJ_TRACE);
        params.put("bizId", String.valueOf(vo.getId()));
        params.put("logPath", DOCKER_BASE_PATH + vo.getResultPath());
        params.put("sourcePath", vo.getPreprocessPath());
        params.put("resultPath", DOCKER_BASE_PATH +  vo.getResultPath());
        params.put("otherParams", new JSONObject().toString());

        log.info("obj_trace params: {}", params);

        try {
            String res = HttpUtil.post(MULTI_OBJ_TRACE_URL, JSONUtil.toJsonStr(params));
            vo.setStatus(TASK_STATUS_PROCESSING);
        } catch (Exception e) {
            log.error("HTTP请求失败",e);
            vo.setStatus(TASK_STATUS_FAILED);
            return CommonResult.fail("HTTP请求失败" + e.getMessage());
        } finally {
            objectTraceMergeService.update(vo);
        }
        return CommonResult.success();
    }

    @GetMapping("/result")
    public CommonResult<List<String>> execute(String taskId) {
        if (taskId == null) {
            return CommonResult.fail("请提供任务ID!", new ArrayList<>());
        }
        ObjectTraceMergeBo bo = objectTraceMergeService.getById(Long.valueOf(taskId));
        if (bo == null) {
            return CommonResult.fail("无法查找到任务!", new ArrayList<>());
        }
//        if (!TASK_STATUS_SUCCEED.equals(bo.getStatus())) {
//            return CommonResult.fail("任务未成功执行!", new ArrayList<>());
//        }
        try {
            String res = DOCKER_BASE_PATH + bo.getResultPath();
            File dir = new File(res);
            File[] files = dir.listFiles();
            List<String> resList = new ArrayList<>();
            int maxNum = -1;
            for (File _file: files) {
                if (_file.getName().contains("number")) {
                    maxNum = Math.max(maxNum, Integer.parseInt(_file.getName()
                        .replace("number", "")
                        .replace(".png", "")
                    ));
                }
            }
            resList.add(String.valueOf(maxNum));
            return CommonResult.success(resList);
        } catch (Exception e) {
            return CommonResult.fail("查找结果失败!", new ArrayList<>());
        }
    }

    /**
     * 修改多物体融合轨迹识别
     */
    @SaCheckPermission("demo:traceMerge:edit")
    @Log(title = "多物体融合轨迹识别", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping
    public CommonResult<Void> edit(@Validated @RequestBody ObjectTraceMergeBo objectTraceMergeBo) {
        Boolean updated = objectTraceMergeService.update(objectTraceMergeBo);
        if (!updated) {
            return CommonResult.fail("修改多物体融合轨迹识别记录失败!");
        }
        return CommonResult.success();
    }

    /**
     * 删除多物体融合轨迹识别
     */
    @SaCheckPermission("demo:traceMerge:remove")
    @Log(title = "多物体融合轨迹识别", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public CommonResult<Void> remove(@PathVariable Long[] ids) {
        boolean deleted = objectTraceMergeService.deleteByIds(ids);
        if (!deleted) {
            return CommonResult.fail("删除多物体融合轨迹识别记录失败!");
        }
        return CommonResult.success();
    }
}
