package com.taais.biz.controller;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.taais.biz.constant.BizConstant;
import com.taais.biz.domain.TargetIdentificationSubtask;
import com.taais.biz.domain.TargetIdentificationSubtaskDetails;
import com.taais.biz.domain.vo.TargetIdentificationSubtaskVo;
import com.taais.biz.service.impl.TargetIdentificationSubtaskServiceImpl;
import com.taais.biz.service.impl.TargetIdentificationTaskServiceImpl;
import com.taais.biz.utils.ZipDirectory;
import com.taais.common.core.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import cn.dev33.satoken.annotation.SaCheckPermission;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
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.biz.domain.vo.TargetIdentificationSubtaskDetailsVo;
import com.taais.biz.domain.bo.TargetIdentificationSubtaskDetailsBo;
import com.taais.biz.service.ITargetIdentificationSubtaskDetailsService;

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

/**
 * 目标识别子任务Controller
 *
 * @author 0
 * 2024-08-17
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/identification/identificationSubtaskDetails")
public class TargetIdentificationSubtaskDetailsController extends BaseController {
    @Resource
    private ITargetIdentificationSubtaskDetailsService targetIdentificationSubtaskDetailsService;

    @Resource
    private TargetIdentificationSubtaskServiceImpl subtaskService;

    /**
     * 查询目标识别子任务列表
     */
    @SaCheckPermission("identification:identificationSubtaskDetails:list")
    @GetMapping("/list")
    public CommonResult<PageResult<TargetIdentificationSubtaskDetailsVo>> list(TargetIdentificationSubtaskDetailsBo targetIdentificationSubtaskDetailsBo) {
        return CommonResult.success(targetIdentificationSubtaskDetailsService.selectPage(targetIdentificationSubtaskDetailsBo));
    }

    /**
     * 导出目标识别子任务列表
     */
    @SaCheckPermission("identification:identificationSubtaskDetails:export")
    @Log(title = "目标识别子任务", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, TargetIdentificationSubtaskDetailsBo targetIdentificationSubtaskDetailsBo) {
        List<TargetIdentificationSubtaskDetailsVo> list = targetIdentificationSubtaskDetailsService.selectList(targetIdentificationSubtaskDetailsBo);
        ExcelUtil.exportExcel(list, "目标识别子任务", TargetIdentificationSubtaskDetailsVo.class, response);
    }

    /**
     * 获取目标识别子任务详细信息
     */
    @SaCheckPermission("identification:identificationSubtaskDetails:query")
    @GetMapping(value = "/{id}")
    public CommonResult<TargetIdentificationSubtaskDetailsVo> getInfo(@PathVariable Long id) {
        return CommonResult.success(targetIdentificationSubtaskDetailsService.selectById(id));
    }

    /**
     * 新增目标识别子任务
     */
    @SaCheckPermission("identification:identificationSubtaskDetails:add")
    @Log(title = "目标识别子任务", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping
    public CommonResult<Void> add(@Validated @RequestBody TargetIdentificationSubtaskDetailsBo targetIdentificationSubtaskDetailsBo) {
        boolean inserted = targetIdentificationSubtaskDetailsService.insert(targetIdentificationSubtaskDetailsBo);
        if (!inserted) {
            return CommonResult.fail("新增目标识别子任务记录失败！");
        }
        return CommonResult.success();
    }

    /**
     * 修改目标识别子任务
     */
    @SaCheckPermission("identification:identificationSubtaskDetails:edit")
    @Log(title = "目标识别子任务", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping
    public CommonResult<Void> edit(@Validated @RequestBody TargetIdentificationSubtaskDetailsBo targetIdentificationSubtaskDetailsBo) {
        Boolean updated = targetIdentificationSubtaskDetailsService.update(targetIdentificationSubtaskDetailsBo);
        if (!updated) {
            return CommonResult.fail("修改目标识别子任务记录失败!");
        }
        return CommonResult.success();
    }

    /**
     * 删除目标识别子任务
     */
    @SaCheckPermission("identification:identificationSubtaskDetails:remove")
    @Log(title = "目标识别子任务", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public CommonResult<Void> remove(@PathVariable Long[] ids) {
        boolean deleted = targetIdentificationSubtaskDetailsService.deleteByIds(ids);
        if (!deleted) {
            return CommonResult.fail("删除目标识别子任务记录失败!");
        }
        return CommonResult.success();
    }

    /**
     * 执行训练任务
     * @param params
     * @return
     */
    @PostMapping("/startTask")
    public CommonResult<Void> startTask(@RequestBody Map<String, String> params) {
        try {
            Long taskId = Long.parseLong(params.get("taskId"));
            TargetIdentificationSubtaskDetails details = targetIdentificationSubtaskDetailsService.getById(taskId);
            if (!(BizConstant.TASK_STATUS_PENDING.equals(details.getStatus()) ||
                BizConstant.TASK_STATUS_FAILED.equals(details.getStatus()))) {
                return CommonResult.fail("任务正在执行中，请勿重复执行！");
            }

            details.setStartTime(new Date());
            targetIdentificationSubtaskDetailsService.updateById(details);
            subtaskService.executeOneTask(taskId);
            return CommonResult.success();
        } catch (Exception e) {
            return CommonResult.fail(e.getMessage());
        }
    }

    /**
     * 执行测试或验证任务
     * @param params
     * @return
     */
    @PostMapping("/execute")
    public CommonResult<Void> executeTask(@RequestBody Map<String, String> params) {
        try {
            Long taskId = Long.parseLong(params.get("taskId"));
            TargetIdentificationSubtaskDetails details = targetIdentificationSubtaskDetailsService.getById(taskId);

            // check if training task is done
            TargetIdentificationSubtask subtask = subtaskService.getById(details.getSubtaskId());
            List<TargetIdentificationSubtaskVo> subtaskList = subtaskService.getSubtaskList(subtask.getTaskId());
            List<Long> trainingTaskIds = new ArrayList<>();
            subtaskList.forEach(subtaskVo -> {
                if (subtaskVo.getName().contains("训练")) {
                    trainingTaskIds.add(subtaskVo.getId());
                }
            });
            boolean isAllTrainingTaskDone = trainingTaskIds.stream().allMatch(trainingTaskId -> {
                List<TargetIdentificationSubtaskDetailsBo> list = targetIdentificationSubtaskDetailsService.getBySubtaskId(trainingTaskId);
                return list.stream().allMatch(taskDetails -> BizConstant.TASK_STATUS_SUCCEED.equals(taskDetails.getStatus()));
            });

            if (!isAllTrainingTaskDone) {
                return CommonResult.fail("训练任务未完成，请先完成训练任务！");
            }

            if (!(BizConstant.TASK_STATUS_PENDING.equals(details.getStatus()) ||
                BizConstant.TASK_STATUS_FAILED.equals(details.getStatus()))) {
                return CommonResult.fail("任务正在执行中，请勿重复执行！");
            }

            details.setStatus(BizConstant.TASK_STATUS_PENDING);
            details.setStartTime(new Date());
            targetIdentificationSubtaskDetailsService.updateById(details);

            subtaskService.executeOneTask(taskId);
            return CommonResult.success();
        } catch (Exception e) {
            return CommonResult.fail(e.getMessage());
        }
    }

    @Value("${taais.profile}")
    private String profile;

    @GetMapping("/getImgList")
    public CommonResult<List<String>> getImgList(String taskId, String subPath) {
        String path = profile + "/task/" + taskId;
        if (StringUtils.isNotEmpty(subPath)) {
            path += "/" + subPath;
        }
        System.out.println("path is : " + path);
        File file = new File( path );
        File[] files = file.listFiles();
        List<String> res = new ArrayList<>();
        for (File _file: files) {
            res.add(_file.getName());
        }
        return CommonResult.success(res);
    }

    @GetMapping("/resultZip")
    public CommonResult<String> genResultZip(String taskId) {
        TargetIdentificationSubtaskDetails details = targetIdentificationSubtaskDetailsService.getById(Long.parseLong(taskId));
        String sourcePath = TargetIdentificationTaskServiceImpl.PATH_PREFIX + details.getResultPath();
        String targetFile = sourcePath + ".zip";
        if (!new File(targetFile).exists()) {
            ZipDirectory.zipDirectory(new File(sourcePath), targetFile);
        }
        String url = "/api/profile/task" + details.getResultPath() + ".zip";
        return CommonResult.success(url);
    }
}
