package com.fs.fastGpt.service.impl;


import com.alibaba.fastjson.JSON;
import com.fs.common.core.domain.R;
import com.fs.company.domain.CompanyConfig;
import com.fs.company.service.ICompanyConfigService;
import com.fs.fastGpt.domain.AiCompanyConfig;
import com.fs.fastGpt.domain.FastGptCollection;
import com.fs.fastGpt.mapper.FastGptCollectionMapper;
import com.fs.fastGpt.service.IFastGptCollectionService;
import com.fs.fastgptApi.param.*;
import com.fs.fastgptApi.result.*;
import com.fs.fastgptApi.service.DataSetCollectionService;
import com.fs.voice.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * 集合Service业务层处理
 * 
 * @author fs
 * @date 2024-09-30
 */
@Service
public class FastGptCollectionServiceImpl implements IFastGptCollectionService
{
    @Autowired
    private FastGptCollectionMapper fastGptCollectionMapper;

    @Autowired
    private DataSetCollectionService dataSetCollectionService;

    @Autowired
    private ICompanyConfigService companyConfigService;
    /**
     * 查询集合
     * 
     * @param collectionId 集合主键
     * @return 集合
     */
    @Override
    public FastGptCollection selectFastGptCollectionByCollectionId(String collectionId)
    {
        return fastGptCollectionMapper.selectFastGptCollectionByCollectionId(collectionId);
    }

    /**
     * 查询集合列表
     * 
     * @param fastGptCollection 集合
     * @return 集合
     */
    @Override
    public List<FastGptCollection> selectFastGptCollectionList(FastGptCollection fastGptCollection)
    {
        return fastGptCollectionMapper.selectFastGptCollectionList(fastGptCollection);
    }

    /**
     * 新增集合
     * 
     * @param fastGptCollection 集合
     * @return 结果
     */
    @Override
    public R insertFastGptCollection(FastGptCollection fastGptCollection) throws Exception {
        CompanyConfig companyConfig = companyConfigService.selectCompanyConfigByKey(fastGptCollection.getCompanyId(), "sys:AiKf:config");
        AiCompanyConfig aiCompanyConfig = JSON.parseObject(companyConfig.getConfigValue(), AiCompanyConfig.class);

        switch (fastGptCollection.getType()) {
            case "folder":
                CreateCollectionParam paramFd = new CreateCollectionParam();
                paramFd.setDatasetId(fastGptCollection.getDatasetId());
                paramFd.setName(fastGptCollection.getName());
                paramFd.setType(fastGptCollection.getType());
                KnowledgeBaseResult resultFolder = dataSetCollectionService.createEmptyCollection(paramFd,aiCompanyConfig.getUrl(), aiCompanyConfig.getKey());
                if (resultFolder != null&& resultFolder.getCode() == 200) {
                    fastGptCollection.setCollectionId(resultFolder.getData());
                    fastGptCollection.setCreateTime(new Date());
                    int i = fastGptCollectionMapper.insertFastGptCollection(fastGptCollection);
                    if (i > 0) {
                        return R.ok().put("data", "新增成功");
                    }else {
                        return R.error().put("data", "新增失败:"+resultFolder.getMessage());
                    }

                }else {
                    return R.error().put("data", "新增失败:"+resultFolder.getMessage());
                }
            case "virtual":
                CreateCollectionParam paramV = new CreateCollectionParam();
                paramV.setDatasetId(fastGptCollection.getDatasetId());
                paramV.setName(fastGptCollection.getName());
                paramV.setType(fastGptCollection.getType());
                KnowledgeBaseResult resultVirtual = dataSetCollectionService.createEmptyCollection(paramV,aiCompanyConfig.getUrl(), aiCompanyConfig.getKey());
                if (resultVirtual != null&& resultVirtual.getCode() == 200) {
                    fastGptCollection.setCollectionId(resultVirtual.getData());
                    fastGptCollection.setCreateTime(new Date());
                    int i = fastGptCollectionMapper.insertFastGptCollection(fastGptCollection);
                    if (i > 0) {
                        return R.ok().put("data", "新增成功");
                    }else {
                        return R.error().put("data", "新增失败:"+resultVirtual.getMessage());
                    }

                }else {
                    return R.error().put("data", "新增失败:"+resultVirtual.getMessage());
                }
            case "text":
                CreateTextCollectionParam textParam = new CreateTextCollectionParam();
                textParam.setText(fastGptCollection.getText());
                textParam.setDatasetId(fastGptCollection.getDatasetId());
                textParam.setName(fastGptCollection.getName());
                textParam.setTrainingType(fastGptCollection.getTrainingType());
                textParam.setChunkSize(fastGptCollection.getChunkSize());
                textParam.setChunkSplitter(fastGptCollection.getChunkSplitter());
                textParam.setQaPrompt(fastGptCollection.getQaPrompt());

                CreateTextCollectionResult textResult = dataSetCollectionService.createTextCollection(textParam,aiCompanyConfig.getUrl(), aiCompanyConfig.getKey());
                if (textResult!=null && textResult.getCode()==200) {
                    fastGptCollection.setCollectionId(textResult.getData().getCollectionId());
                    fastGptCollection.setCreateTime(new Date());
                    int i = fastGptCollectionMapper.insertFastGptCollection(fastGptCollection);
                    if (i>0){
                        return R.ok().put("data", "新增成功");
                    }else {
                        return R.error().put("data", "新增失败:"+textResult.getMessage());
                    }

                }else {
                    return R.error().put("data", "新增失败:"+textResult.getMessage());
                }
            case "link":
                CreateLinkCollectionParam linkParam = new CreateLinkCollectionParam();
                linkParam.setLink(fastGptCollection.getLink());
                linkParam.setName(fastGptCollection.getName());
                linkParam.setDatasetId(fastGptCollection.getDatasetId());
                linkParam.setTrainingType(fastGptCollection.getTrainingType());
                linkParam.setChunkSize(fastGptCollection.getChunkSize());
                linkParam.setChunkSplitter(fastGptCollection.getChunkSplitter());
                linkParam.setQaPrompt(fastGptCollection.getQaPrompt());
                CreateLinkCollectionResult linkResult = dataSetCollectionService.createLinkCollection(linkParam,aiCompanyConfig.getUrl(), aiCompanyConfig.getKey());
                if (linkResult!=null && linkResult.getCode()==200){
                    fastGptCollection.setCollectionId(linkResult.getData().getCollectionId());
                    fastGptCollection.setCreateTime(new Date());
                    int i = fastGptCollectionMapper.insertFastGptCollection(fastGptCollection);
                    if (i>0){
                        return R.ok().put("data", "新增成功");
                    }else {
                        return R.error().put("data", "新增失败:"+linkResult.getMessage());
                    }
                }else {
                    return R.error().put("data", "新增失败:"+linkResult.getMessage());
                }

            case "file":

                File file = urlToFile(fastGptCollection.getFileUrl());
                UploadFileParam fileParam = new UploadFileParam();
                fileParam.setDatasetId(fastGptCollection.getDatasetId());
                fileParam.setTrainingType(fastGptCollection.getTrainingType());
//                fileParam.setChunkSize(fastGptCollection.getChunkSize());
//                fileParam.setChunkSplitter(fastGptCollection.getChunkSplitter());
//                fileParam.setQaPrompt(fastGptCollection.getQaPrompt());

                CreateFileCollectionResult fileResult = dataSetCollectionService.createFileCollection(file,fastGptCollection.getFileName(), fileParam,aiCompanyConfig.getUrl(), aiCompanyConfig.getKey());

                file.delete();

                if(fileResult!=null && fileResult.getCode()==200){
                    fastGptCollection.setCollectionId(fileResult.getData().getCollectionId());
                    fastGptCollection.setCreateTime(new Date());
                    int i = fastGptCollectionMapper.insertFastGptCollection(fastGptCollection);
                    if (i>0){
                        return R.ok().put("data", "新增成功");
                    }else {
                        return R.error().put("data", "新增失败:"+fileResult.getMessage());
                    }
                }else {
                    return R.error().put("data", "新增失败:"+fileResult.getMessage());
                }

            default:
                break;
        }

        return R.ok();
    }

    /**
     * 修改集合
     * 
     * @param fastGptCollection 集合
     * @return 结果
     */
    @Override
    public R updateFastGptCollection(FastGptCollection fastGptCollection)
    {
        CompanyConfig companyConfig = companyConfigService.selectCompanyConfigByKey(fastGptCollection.getCompanyId(), "sys:AiKf:config");
        AiCompanyConfig aiCompanyConfig = JSON.parseObject(companyConfig.getConfigValue(), AiCompanyConfig.class);

        UpdateCollectionByIdParam param = new UpdateCollectionByIdParam();
        param.setId(fastGptCollection.getCollectionId());
        param.setName(fastGptCollection.getName());
        if (fastGptCollection.getForbid()!=null) {
            param.setForbid(fastGptCollection.getForbid() == 1);
        }
        KnowledgeBaseResult result = dataSetCollectionService.updateCollectionInfoById(param,aiCompanyConfig.getUrl(), aiCompanyConfig.getKey());
        if(result.getCode()==200){
            return R.ok().put("data",fastGptCollectionMapper.updateFastGptCollection(fastGptCollection));
        }else {
            return R.error("修改失败");
        }
    }

    /**
     * 批量删除集合
     * 
     * @param collectionIds 需要删除的集合主键
     * @return 结果
     */
    @Override
    public R deleteFastGptCollectionByCollectionIds(String[] collectionIds,Long companyId)
    {

        ArrayList<String> list=new ArrayList<>();

        CompanyConfig companyConfig = companyConfigService.selectCompanyConfigByKey(companyId, "sys:AiKf:config");
        AiCompanyConfig aiCompanyConfig = JSON.parseObject(companyConfig.getConfigValue(), AiCompanyConfig.class);

        for (String collectionId : collectionIds) {

            KnowledgeBaseResult knowledgeBaseResult = dataSetCollectionService.deleteCollection(collectionId,aiCompanyConfig.getUrl(),aiCompanyConfig.getKey());
            if (knowledgeBaseResult.getCode()==200){
                fastGptCollectionMapper.deleteFastGptCollectionByCollectionIds(collectionIds);
            }else {
                list.add(collectionId);
            }

        }

        return R.ok().put("data",list);
    }

    /**
     * 删除集合信息
     * 
     * @param collectionId 集合主键
     * @return 结果
     */
    @Override
    public int deleteFastGptCollectionByCollectionId(String collectionId)
    {
        return fastGptCollectionMapper.deleteFastGptCollectionByCollectionId(collectionId);
    }

    @Override
    public R syncCollection(String datasetId,Long companyId) throws ParseException {

        CompanyConfig companyConfig = companyConfigService.selectCompanyConfigByKey(companyId, "sys:AiKf:config");
        AiCompanyConfig aiCompanyConfig = JSON.parseObject(companyConfig.getConfigValue(), AiCompanyConfig.class);


        int pageNum=1;
        int pageSize=30;

        GetCollectionListParam param=new GetCollectionListParam();
        param.setDatasetId(datasetId);
        param.setPageSize(pageSize);
        param.setPageNum(pageNum);

        // 获取总条目数
        int total = syncCollection(param,aiCompanyConfig.getUrl(), aiCompanyConfig.getKey(),companyId);

        // 计算总页数
        int totalPages = (int) Math.ceil((double) total / pageSize);

        // 如果总页数大于1，则遍历剩余页
        if (totalPages > 1) {
            for (int i = 2; i <= totalPages; i++) {
                param.setPageNum(i);
                try {
                    syncCollection(param,aiCompanyConfig.getUrl(), aiCompanyConfig.getKey(),companyId);
                } catch (Exception e) {
                    // 处理可能的异常
                    System.err.println("同步出错 " + i + ": " + e.getMessage());
                }
            }
        }
        return R.ok();
    }

    public  int syncCollection(GetCollectionListParam param,String url,String key,Long companyId) throws ParseException {


        // 定义输出格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        sdf.setTimeZone(TimeZone.getTimeZone("UTC")); // 设置时区为 UTC

        int total=0;
        FastGptCollection fastGptCollection = new FastGptCollection();

        GetCollectionListResult collectionList = dataSetCollectionService.getCollectionList(param,url, key);
        if (collectionList!=null && collectionList.getCode()==200){
            List<GetCollectionListResult.Data.Item> data = collectionList.getData().getData();
            if (data!=null && data.size()>0){
                for (GetCollectionListResult.Data.Item item : data) {

                    fastGptCollection.setCollectionId(item.get_id());
                    fastGptCollection.setParentId(item.getParentId());
                    fastGptCollection.setType(item.getType());
                    fastGptCollection.setName(item.getName());
                    fastGptCollection.setForbid(item.isForbid() ?1L:0L);
                    fastGptCollection.setTrainingType(item.getTrainingType());
                    fastGptCollection.setUpdateTime(sdf.parse(item.getUpdateTime()));
                    fastGptCollection.setDatasetId(param.getDatasetId());
                    fastGptCollection.setCompanyId(companyId);
                    fastGptCollection.setDataAmount(item.getDataAmount());
                    GetCollectionDetailResult collectionDetail = dataSetCollectionService.getCollectionDetail(item.get_id(),url,key);
                    fastGptCollection.setCreateTime(sdf.parse(collectionDetail.getData().getCreateTime()));
                    fastGptCollection.setChunkSize(collectionDetail.getData().getChunkSize());
                    fastGptCollection.setChunkSplitter(collectionDetail.getData().getChunkSplitter());
                    fastGptCollection.setQaPrompt(collectionDetail.getData().getQaPrompt());

                    fastGptCollectionMapper.insertOrUpdateFastGptCollection(fastGptCollection);

                }
            }
            total=collectionList.getData().getTotal();
        }
        return total;
    }

    /**
     *  url转临时文件filr
     */
    public static File urlToFile(String fileUrl) throws Exception {

        // 从URL中提取文件名，文件后缀
        String fileExtension = getFileExtension(new File(fileUrl).getName());
        String fileName = extractFileName(new URL(fileUrl))+new Date().getTime();
        File tempFile=null;
        if (!StringUtil.strIsNullOrEmpty(fileExtension)){
            // 创建一个临时文件
            tempFile = File.createTempFile(fileName, "."+fileExtension);
        }else {
            tempFile = File.createTempFile(fileName, null);
        }


        // 使用 try-with-resources 语句自动关闭资源
        try (BufferedInputStream in = new BufferedInputStream(new URL(fileUrl).openStream());
             FileOutputStream out = new FileOutputStream(tempFile)) {

            byte[] buffer = new byte[1024];
            int len;

            // 读取数据并写入到临时文件
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
            out.flush();
        } catch (IOException e) {
            // 处理异常，例如删除创建的临时文件
            tempFile.delete();
            throw e;
        }finally {

        }

        return tempFile;
    }

    /**
     *  获取文件名
     */
    private static String extractFileName(URL url) throws Exception {
        String path = url.getPath();
        int lastSlashIndex = path.lastIndexOf('/');
        String fileNameWithExt = path.substring(lastSlashIndex + 1);

        int dotIndex = fileNameWithExt.lastIndexOf('.');
        String baseName;
        if (dotIndex > 0) {
            // 如果有扩展名，移除扩展名
            baseName = fileNameWithExt.substring(0, dotIndex);
        } else {
            // 如果没有扩展名，直接使用文件名
            baseName = fileNameWithExt;
        }

        return baseName;
    }

    /**
     *  获取文件名后缀
     */

    public static String getFileExtension(String fileName) {
        int lastIndex = fileName.lastIndexOf('.');
        if (lastIndex != -1 && lastIndex + 1 < fileName.length()) {
            return fileName.substring(lastIndex + 1);
        }
        return ""; // 如果没有扩展名，返回空字符串
    }
}
