package com.pavis.admin.controller.aigc;

import com.pavis.admin.aigc.constant.EmbedConst;
import com.pavis.admin.aigc.core.llm.exception.ServiceException;
import com.pavis.admin.aigc.core.task.TaskManager;
import com.pavis.admin.aigc.mapper.DocMapper;
import com.pavis.admin.aigc.model.entity.DocDO;
import com.pavis.admin.aigc.service.EmbedStoreService;
import com.pavis.admin.aigc.service.KnowledgeService;
import com.pavis.admin.common.context.UserContextHolder;
import com.pavis.admin.system.service.FileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import jakarta.annotation.Resource;
import org.dromara.x.file.storage.core.FileInfo;
import org.springframework.web.multipart.MultipartFile;
import top.continew.starter.extension.crud.enums.Api;

import io.swagger.v3.oas.annotations.tags.Tag;

import org.springframework.web.bind.annotation.*;

import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
import com.pavis.admin.common.controller.BaseController;
import com.pavis.admin.aigc.model.query.DocQuery;
import com.pavis.admin.aigc.model.req.DocReq;
import com.pavis.admin.aigc.model.resp.DocDetailResp;
import com.pavis.admin.aigc.model.resp.DocResp;
import com.pavis.admin.aigc.service.DocService;
import top.continew.starter.web.model.R;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;

/**
 * 智能文档管理 API
 *
 * @author semi
 * @since 2025/05/26 17:28
 */
@Tag(name = "AIGC智能文档管理 API")
@RestController
@CrudRequestMapping(value = "/aigc/doc", api = {Api.PAGE, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE, Api.EXPORT})
public class DocController extends BaseController<DocService, DocResp, DocDetailResp, DocQuery, DocReq> {
    @Resource
    private FileService fileService;

    @Resource
    private KnowledgeService aigcKnowledgeService;

    @Resource
    private DocService docService;

    @Resource
    private DocMapper docMapper;

    @Operation(summary = "文档上传切片接口", description = "文档上传切片接口")
    @Parameter(name = "knowledgeId", description = "知识库id", example = "1hdjshfaaj", in = ParameterIn.PATH)
    @PostMapping("/docs/{knowledgeId}")
    // @SaCheckPermission("aigc:embedding:docs")
    public R docs(MultipartFile file, @PathVariable Long knowledgeId) {
        String userId = String.valueOf(UserContextHolder.getUserId());
        try {
            FileInfo upload = fileService.upload(file);
            DocDO data = new DocDO();
            data.setName(upload.getOriginalFilename());
            data.setProcessingStatus("uploaded");
            data.setStoragePath(upload.getUrl());
            data.setFileSize(file.getSize());
            data.setFileType(EmbedConst.ORIGIN_TYPE_UPLOAD);
            data.setKnowledgeId(knowledgeId);
            aigcKnowledgeService.addDocs(data);
            TaskManager.submitTask(userId, Executors.callable(() -> {
                docService.embedDocsSlice(data, upload.getUrl());
            }));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return R.ok();
    }

    @GetMapping("/re-embed/{docsId}")
    @Operation(summary = "文档切片重置接口", description = "文档切片重置接口")
    public R reEmbed(@PathVariable String docsId) {
        String userId = String.valueOf(UserContextHolder.getUserId());
        DocDO docs = docMapper.selectById(docsId);
        if (docs == null) {
            throw new ServiceException("没有查询到文档数据");
        }
        // if (EmbedConst.ORIGIN_TYPE_INPUT.equals(docs.getFileType())) {
        //     text(docs);
        // }
        if (EmbedConst.ORIGIN_TYPE_UPLOAD.equals(docs.getFileType())) {
            // clear before re-embed
            baseService.clearDocSlices(docsId);
            TaskManager.submitTask(userId, Executors.callable(() -> {
                docService.embedDocsSlice(docs, docs.getStoragePath());
            }));
        }
        return R.ok();
    }

    @GetMapping("/delete/{docsId}")
    @Operation(summary = "文档切片删除接口", description = "文档切片删除接口")
    public R delDocAndSlices(@PathVariable String docsId) {
        // clear before re-embed
        baseService.clearDocSlices(docsId);
        List<Long> docs = new ArrayList<>();
        docs.add(Long.valueOf(docsId));
        baseService.delete(docs);
        return R.ok();
    }

}