package com.qingyun.web.controller.api.contract;

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

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qingyun.common.exception.ServiceException;
import com.qingyun.common.helper.LoginHelper;
import com.qingyun.common.utils.MapstructUtils;
import com.qingyun.service.compare.factory.FileComparisonStrategyFactory;
import com.qingyun.service.compare.strategy.FileComparisonStrategy;
import com.qingyun.service.domain.ContractCompareResult;
import com.qingyun.service.domain.ContractCompareTask;
import com.qingyun.service.domain.ContractReviewResult;
import com.qingyun.service.mapper.ContractCompareTaskMapper;
import com.qingyun.service.service.IContractCompareResultService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.qingyun.idempotent.annotation.RepeatSubmit;
import com.qingyun.common.annotation.Log;
import com.qingyun.common.core.controller.BaseController;
import com.qingyun.common.core.domain.PageQuery;
import com.qingyun.common.core.domain.R;
import com.qingyun.common.core.validate.AddGroup;
import com.qingyun.common.core.validate.EditGroup;
import com.qingyun.common.enums.BusinessType;
import com.qingyun.service.domain.vo.ContractCompareTaskVo;
import com.qingyun.service.domain.bo.ContractCompareTaskBo;
import com.qingyun.service.service.IContractCompareTaskService;
import com.qingyun.mybatisplus.page.TableDataInfo;

import javax.validation.constraints.*;

/**
 * 合同对比任务管理
 *
 * @author jianlu
 * @date 2025-07-11
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/service/compareTask")
public class ContractCompareTaskController extends BaseController {

    private final IContractCompareTaskService contractCompareTaskService;

    private final IContractCompareResultService contractCompareResultService;

    private final SqlSessionFactory sqlSessionFactory;

    private final FileComparisonStrategyFactory strategyFactory;


    /**
     * 查询对比任务列表 "service:compareTask:list"
     * @param contractName 合同名称 模糊查询
     */
    @SaCheckPermission("service:compareTask:list")
    @GetMapping("/list")
    public TableDataInfo<ContractCompareTaskVo> list(String contractName, PageQuery pageQuery) {
        return contractCompareTaskService.queryPageList(contractName, pageQuery);
    }


    /**
     * 获取对比任务详细信息 "service:compareTask:query"
     *
     * @param taskId 主键
     */
    @SaCheckPermission("service:compareTask:query")
    @GetMapping("/{taskId}")
    public R<ContractCompareTaskVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long taskId) {
        return R.ok(contractCompareTaskService.queryById(taskId));
    }

    /**
     * 创建对比任务 "service:compareTask:add"
     */
    @SaCheckPermission("service:compareTask:add")
    //@RepeatSubmit(interval = 60000, message = "请勿重复提交")
    @PostMapping("/create")
    public R<Long> add(@Validated(AddGroup.class) @RequestBody ContractCompareTaskBo bo) {
        ContractCompareTask add = MapstructUtils.convert(bo, ContractCompareTask.class);
        if (add ==  null) {
            return R.fail("创建任务失败");
        }
        add.setStatus(1);
        add.setUserId(LoginHelper.getUserId());
        add.setDeptId(LoginHelper.getDeptId());
        add.setCreateTime(new Date());
        add.setCreateBy(LoginHelper.getUsername());
        FileComparisonStrategy strategy = strategyFactory.getStrategy(add);
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            ContractCompareTaskMapper mapper = sqlSession.getMapper(ContractCompareTaskMapper.class);
            // 提取内容
            strategy.extractContent(add);
            mapper.insert(add);
            sqlSession.commit();
        } catch (Exception e) {
            log.error("创建任务失败", e);
            throw new ServiceException("创建任务失败");
        }
        // 异步执行 比对任务
        contractCompareTaskService.executeTask(strategy, add);
        return R.ok(add.getTaskId());
    }

    /**
     * 执行对比任务 "service:compareTask:execute"
     * @param taskId   任务ID
     */
    @SaCheckPermission("service:compareTask:execute")
    @GetMapping("/execute/{taskId}")
    public R<Integer> execute(@NotNull(message = "任务ID不能为空") @PathVariable("taskId") Long taskId) {
        ContractCompareTask contractCompareTask = contractCompareTaskService.getBaseMapper().selectById(taskId);
        if (contractCompareTask == null) {
            throw new ServiceException("任务不存在");
        }
        contractCompareTask.setStatus(2);
        contractCompareTaskService.getBaseMapper().updateById(contractCompareTask);

        contractCompareResultService.getBaseMapper().delete(Wrappers.lambdaQuery(ContractCompareResult.class)
            .eq(ContractCompareResult::getTaskId, taskId)
        );
        FileComparisonStrategy strategy = strategyFactory.getStrategy(contractCompareTask);
        // 异步执行
        contractCompareTaskService.executeTask(strategy, contractCompareTask);
        return R.ok(2);
    }

    /**
     * 重试 "contract:compare:task:retry"
     */
    @SaCheckPermission("contract:compare:task:retry")
    @GetMapping("/retry/{taskId}")
    public R<Integer> retry(@NotNull(message = "任务ID不能为空") @PathVariable("taskId") Long taskId) {
        ContractCompareTask contractCompareTask = contractCompareTaskService.getBaseMapper().selectById(taskId);
        if (contractCompareTask == null) {
            throw new ServiceException("任务不存在");
        }
        contractCompareResultService.getBaseMapper().delete(Wrappers.lambdaQuery(ContractCompareResult.class)
            .eq(ContractCompareResult::getTaskId, taskId)
        );
        contractCompareTask.setStatus(2);
        contractCompareTaskService.getBaseMapper().updateById(contractCompareTask);
        FileComparisonStrategy strategy = strategyFactory.getStrategy(contractCompareTask);
        // 异步执行
        contractCompareTaskService.executeTask(strategy, contractCompareTask);
        return R.ok("重试成功", 2);
    }

    /**
     * 轮询对比任务结果 "contract:compareTask:status"
     */
    @SaCheckPermission("contract:compareTask:status")
    @GetMapping("/status/{taskId}")
    public R<Integer> queryStatus(@NotNull(message = "任务ID不能为空") @PathVariable("taskId") Long taskId) {
        ContractCompareTask contractCompareTask = contractCompareTaskService.getBaseMapper().selectById(taskId);
        if (contractCompareTask == null) {
            throw new ServiceException("任务不存在");
        }
        return R.ok(contractCompareTask.getStatus());
    }

    /**
     * 修改对比任务 "service:compareTask:edit"
     */
    @SaCheckPermission("service:compareTask:edit")
    @Log(title = "对比任务", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/update")
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody ContractCompareTaskBo bo) {
        return toAjax(contractCompareTaskService.updateByBo(bo));
    }

    /**
     * 删除对比任务 "service:compareTask:remove"
     *
     * @param taskIds 主键串
     */
    @SaCheckPermission("service:compareTask:remove")
    @Log(title = "对比任务", businessType = BusinessType.DELETE)
    @DeleteMapping("/{taskIds}")
    public R<Void> remove(@NotNull(message = "主键不能为空")
                          @PathVariable Long[] taskIds) {
        return toAjax(contractCompareTaskService.deleteWithValidByIds(Arrays.asList(taskIds), Boolean.TRUE));
    }
}
