package cn.com.poc.covenant.rest.impl;

import cn.com.poc.common.service.BosConfigService;
import cn.com.poc.thirdparty.resource.text_in.entity.doc_flow.FileUploadResponse;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.multipart.MultipartFile;


import cn.com.poc.common.constant.CommonConstant;
import cn.com.poc.common.model.BizFileUploadRecordModel;
import cn.com.poc.common.service.BizFileUploadRecordService;
import cn.com.poc.common.utils.BlContext;
import cn.com.poc.common.utils.DocumentLoad;
import cn.com.poc.common.utils.UUIDTool;

import cn.com.poc.covenant.constants.ContractConstants;
import cn.com.poc.covenant.dto.ExtractionDto;
import cn.com.poc.covenant.dto.ReviewProgressDto;
import cn.com.poc.covenant.dto.StartDocFlowDto;
import cn.com.poc.covenant.dto.StartReviewDto;
import cn.com.poc.covenant.model.BizExtractionKeyInfoConfigModel;
import cn.com.poc.covenant.model.BizExtractionReviewTaskModel;
import cn.com.poc.covenant.model.BizExtreactionContractTypeModel;
import cn.com.poc.covenant.query.ExtractionTaskQueryCondition;
import cn.com.poc.covenant.query.ExtractionTaskQueryItem;
import cn.com.poc.covenant.rest.ExtractionRest;
import cn.com.poc.covenant.service.BizExtractionKeyInfoConfigService;
import cn.com.poc.covenant.service.BizExtractionReviewTaskService;
import cn.com.poc.covenant.service.BizExtreactionContractTypeService;
import cn.com.poc.support.security.oauth.entity.UserBaseEntity;
import cn.com.poc.thirdparty.resource.baidu.api.BaiduTokenAPI;
import cn.com.poc.thirdparty.resource.baidu.api.TextReviewApi;
import cn.com.poc.thirdparty.resource.baidu.entity.response.TextReviewSubmitResponse;
import cn.com.poc.thirdparty.resource.text_in.entity.doc_flow.FileUploadRequest;
import cn.com.poc.thirdparty.resource.baidu.entity.result.TextReviewRequest;
import cn.com.poc.thirdparty.resource.text_in.api.TextInClient;
import cn.com.poc.thirdparty.resource.text_in.entity.extraction.entity.ExtractionResult;
import cn.com.poc.thirdparty.resource.text_in.entity.extraction.entity.KeyInfo;
import cn.com.yict.framemax.core.exception.BusinessException;
import cn.com.yict.framemax.frame.service.FmxParamConfigService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author alex.yao
 * @date 2025/5/19
 */
@Component
public class ExtractionRestImpl implements ExtractionRest {

    private final TextInClient textInClient = new TextInClient();

    @Resource
    private BizExtractionKeyInfoConfigService bizExtractionKeyInfoConfigService;

    @Resource
    private BizExtractionReviewTaskService bizExtractionReviewTaskService;

    @Resource
    private BizExtreactionContractTypeService bizExtreactionContractTypeService;

    @Resource
    private BizFileUploadRecordService bizFileUploadRecordService;

    @Resource
    private TextReviewApi textReviewApi;

    @Resource
    private FmxParamConfigService fmxConfigService;

    @Resource
    private BaiduTokenAPI baiduTokenAPI;

    @Resource
    private BosConfigService ossservice;


    @Override
    public String startExtract(StartReviewDto startReviewDto) throws Exception {
        Assert.notNull(startReviewDto.getContractType());
        Assert.notEmpty(startReviewDto.getFileUrls());
        UserBaseEntity userBaseEntity = BlContext.getCurrentUserNotException();
        if (userBaseEntity == null) {
            throw new BusinessException("用户未登录");
        }

        String taskId = UUIDTool.getUUID();

        // 保存任务信息
        List<BizExtractionReviewTaskModel> bizExtractionReviewTaskModels = new ArrayList<>();
        for (String fileUrl : startReviewDto.getFileUrls()) {
            String textInTaskId = createExtractTask(fileUrl, startReviewDto.getContractType());

            BizFileUploadRecordModel bizFileUploadRecordModel = new BizFileUploadRecordModel();
            bizFileUploadRecordModel.setFileUrl(fileUrl);
            List<BizFileUploadRecordModel> models = bizFileUploadRecordService.findByExample(bizFileUploadRecordModel, null);
            BizExtractionReviewTaskModel bizExtractionReviewTaskModel = new BizExtractionReviewTaskModel();

            if (CollectionUtils.isNotEmpty(models)) {
                bizExtractionReviewTaskModel.setFileName(models.get(0).getFileName());
            } else {
                bizExtractionReviewTaskModel.setFileName(getFileName(fileUrl));
            }
            bizExtractionReviewTaskModel.setTaskId(taskId);
            bizExtractionReviewTaskModel.setUserId(userBaseEntity.getUserId());
            bizExtractionReviewTaskModel.setFileUrl(fileUrl);
            bizExtractionReviewTaskModel.setActionType(ContractConstants.ActionType.extract);
            bizExtractionReviewTaskModel.setReviewStatus("RUN");
            bizExtractionReviewTaskModel.setReviewErrorMsg(null);
            bizExtractionReviewTaskModel.setTextInTaskId(textInTaskId);
            bizExtractionReviewTaskModel.setContractType(startReviewDto.getContractType());
            bizExtractionReviewTaskModels.add(bizExtractionReviewTaskModel);
        }
        bizExtractionReviewTaskService.saveAll(bizExtractionReviewTaskModels);
        return taskId;
    }

    @Override
    public String startReview(StartReviewDto startReviewDto) throws Exception {
        Assert.notNull(startReviewDto.getContractType());
        String taskId = UUIDTool.getUUID();

        UserBaseEntity userBaseEntity = BlContext.getCurrentUserNotException();
        if (userBaseEntity == null) {
            throw new BusinessException("用户未登录");
        }

        // 保存任务信息
        if (CollectionUtils.isEmpty(startReviewDto.getFileUrls())) {
            throw new BusinessException("请上传文件");
        }

        String fileUrl = startReviewDto.getFileUrls().get(0);

        //下载文件
        File tempAudioFile = DocumentLoad.downloadURLDocument(fileUrl);


        List<BizExtractionReviewTaskModel> bizExtractionReviewTaskModels = new ArrayList<>();
        TextReviewSubmitResponse textReviewSubmitResponse = createReviewTask(tempAudioFile, startReviewDto.getContractType());
        if (textReviewSubmitResponse == null || !"0".equals(textReviewSubmitResponse.getError_code())) {
            throw new BusinessException("上传异常，请稍后重试");
        }

        BizFileUploadRecordModel bizFileUploadRecordModel = new BizFileUploadRecordModel();
        bizFileUploadRecordModel.setFileUrl(fileUrl);
        List<BizFileUploadRecordModel> models = bizFileUploadRecordService.findByExample(bizFileUploadRecordModel, null);
        BizExtractionReviewTaskModel bizExtractionReviewTaskModel = new BizExtractionReviewTaskModel();
        if (CollectionUtils.isNotEmpty(models)) {
            bizExtractionReviewTaskModel.setFileName(models.get(0).getFileName());
        } else {
            bizExtractionReviewTaskModel.setFileName(getFileName(fileUrl));
        }
        bizExtractionReviewTaskModel.setTaskId(taskId);
        bizExtractionReviewTaskModel.setFileUrl(fileUrl);
        bizExtractionReviewTaskModel.setActionType(ContractConstants.ActionType.textreview);
        bizExtractionReviewTaskModel.setReviewStatus("RUN");
        bizExtractionReviewTaskModel.setUserId(userBaseEntity.getUserId());
        bizExtractionReviewTaskModel.setReviewErrorMsg(null);
        bizExtractionReviewTaskModel.setTextInTaskId(textReviewSubmitResponse.getResult().getTaskId());
        bizExtractionReviewTaskModel.setContractType(startReviewDto.getContractType());
        bizExtractionReviewTaskModels.add(bizExtractionReviewTaskModel);
        bizExtractionReviewTaskService.saveAll(bizExtractionReviewTaskModels);
        return taskId;
    }

    /**
     * 开始单据提取-textin docflow
     * https://docflow.apifox.cn/
     *
     * @param startDocFlowDto
     */
    @Override
    public String startDocFlow(StartDocFlowDto startDocFlowDto) throws Exception {
        Assert.notNull(startDocFlowDto.getContractType());
        String taskId = UUIDTool.getUUID();

        UserBaseEntity userBaseEntity = BlContext.getCurrentUserNotException();
        if (userBaseEntity == null) {
            throw new BusinessException("用户未登录");
        }

        // 保存任务信息
        MultipartFile file = startDocFlowDto.getFile();
        if (file == null) {
            throw new BusinessException("请上传文件");
        }

        String type = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1, file.getOriginalFilename().length());

        String fileUrl = ossservice.upload(file.getInputStream(), type, file.getContentType());

        String workspaceId = fmxConfigService.getParam("textin.docflow.workspaceId");
        if (StringUtils.isBlank(workspaceId)) {
            throw new BusinessException("请配置workspaceId");
        }

        //下载文件
        List<BizExtractionReviewTaskModel> bizExtractionReviewTaskModels = new ArrayList<>();
        FileUploadResponse fileUploadResponse = createDocFlowTask(file, workspaceId, startDocFlowDto.getCategory());
        if (fileUploadResponse == null || !"200".equals(fileUploadResponse.getCode())) {
            throw new BusinessException("上传异常，请稍后重试");
        }

        BizExtractionReviewTaskModel bizExtractionReviewTaskModel = new BizExtractionReviewTaskModel();
        bizExtractionReviewTaskModel.setFileName(file.getOriginalFilename());
        bizExtractionReviewTaskModel.setTaskId(taskId);
        bizExtractionReviewTaskModel.setFileUrl(fileUrl);
        bizExtractionReviewTaskModel.setActionType(ContractConstants.ActionType.docFlow);
        bizExtractionReviewTaskModel.setReviewStatus("RUN");
        bizExtractionReviewTaskModel.setUserId(userBaseEntity.getUserId());
        bizExtractionReviewTaskModel.setReviewErrorMsg(null);
        bizExtractionReviewTaskModel.setTextInTaskId(fileUploadResponse.getResult().getFiles().get(0).getid());
        bizExtractionReviewTaskModel.setContractType(startDocFlowDto.getContractType());
        bizExtractionReviewTaskModels.add(bizExtractionReviewTaskModel);
        bizExtractionReviewTaskService.saveAll(bizExtractionReviewTaskModels);
        return taskId;
    }

    private TextReviewSubmitResponse createReviewTask(File file, String contractType) throws IOException {
        TextReviewRequest textReviewRequest = new TextReviewRequest();
        textReviewRequest.setFile(file);
        textReviewRequest.setTemplateName(contractType);
        textReviewRequest.setCommentRiskLevel("all");

        String clientId = fmxConfigService.getParam("baidu.textmind.clientId");
        String clientSecret = fmxConfigService.getParam("baidu.textmind.clientSecret");

        return textReviewApi.textReview(textReviewRequest, baiduTokenAPI.getToken(clientId, clientSecret).getAccess_token());
    }

    @Override
    public List<BizExtreactionContractTypeModel> getContractTypeList(String contractType) throws Exception {
        Assert.notNull(contractType);
        BizExtreactionContractTypeModel bizExtreactionContractTypeModel = new BizExtreactionContractTypeModel();
        bizExtreactionContractTypeModel.setContractType(contractType);
        List<BizExtreactionContractTypeModel> models = bizExtreactionContractTypeService.findByExample(bizExtreactionContractTypeModel, null);
        return models;
    }

    @Override
    public List<ReviewProgressDto> reviewProgressList(String reviewTaskId, String search, String actionType) {
        Assert.notNull(reviewTaskId);

        UserBaseEntity currentUser = BlContext.getCurrentUserNotException();

        if (currentUser == null) {
            throw new BusinessException("用户未登录");
        }
        ExtractionTaskQueryCondition condition = new ExtractionTaskQueryCondition();
        condition.setTaskId(reviewTaskId);
        condition.setSearch(search);
        condition.setUserId(currentUser.getUserId());
        condition.setActionType(actionType);
        List<ExtractionTaskQueryItem> extractionTaskQueryItems = bizExtractionReviewTaskService.extractionTaskQuery(condition, null);
        List<ReviewProgressDto> reviewProgressDtos = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(extractionTaskQueryItems)) {
            for (ExtractionTaskQueryItem extractionTaskQueryItem : extractionTaskQueryItems) {
                reviewProgressDtos.add(itemConvertDto(extractionTaskQueryItem));
            }
        }
        return reviewProgressDtos;
    }

    @Override
    public ExtractionDto getResult(String taskId) {
        ExtractionResult extractionResult = textInClient.extractedResults(taskId);
        ExtractionDto result = new ExtractionDto();
        if (extractionResult == null) {
            result.setStatus(-1);
            result.setResult(null);
        } else if (extractionResult.getCode().equals(209L)) {
            result.setStatus(0);
            result.setResult(null);
        } else if (extractionResult.getCode().equals(200L)) {
            result.setStatus(1);
            result.setResult(extractionResult.getResult());
        } else {
            result.setStatus(-1);
            result.setResult(null);
        }
        return result;
    }

    private ReviewProgressDto itemConvertDto(ExtractionTaskQueryItem extractionTaskQueryItem) {
        ReviewProgressDto reviewProgressDto = new ReviewProgressDto();
        reviewProgressDto.setReviewDate(extractionTaskQueryItem.getCreatedTime());
        reviewProgressDto.setTextInTaskId(extractionTaskQueryItem.getTextInTaskId());
        reviewProgressDto.setReviewTaskId(extractionTaskQueryItem.getTaskId());
        reviewProgressDto.setFileName(extractionTaskQueryItem.getFileName());
        reviewProgressDto.setFileUrl(extractionTaskQueryItem.getFileUrl());
        reviewProgressDto.setReviewStatus(extractionTaskQueryItem.getReviewStatus());
        return reviewProgressDto;
    }


    /**
     * 创建 TextIn 合同审核任务
     *
     * @param fileUrl      文件地址
     * @param contractType 合同类型
     * @return textId_task_id
     */
    private String createExtractTask(String fileUrl, String contractType) {
        List<KeyInfo> keyInfoList = new ArrayList<>();
        BizExtractionKeyInfoConfigModel model = new BizExtractionKeyInfoConfigModel();
        model.setContractType(contractType);
        List<BizExtractionKeyInfoConfigModel> bizExtractionKeyInfoConfigModels = bizExtractionKeyInfoConfigService.findByExample(model, null);
        if (CollectionUtils.isNotEmpty(bizExtractionKeyInfoConfigModels)) {
            for (BizExtractionKeyInfoConfigModel bizExtractionKeyInfoConfigModel : bizExtractionKeyInfoConfigModels) {
                KeyInfo keyInfo = new KeyInfo();
                keyInfo.setKey_info(bizExtractionKeyInfoConfigModel.getKeyInfo());
                if (StringUtils.isNoneBlank(bizExtractionKeyInfoConfigModel.getParaphraseNames())) {
                    JSONArray jsonArray = new JSONArray(bizExtractionKeyInfoConfigModel.getParaphraseNames());
                    if (!jsonArray.isEmpty()) {
                        keyInfo.setParaphrase_names(jsonArray.toList().toArray(new String[0]));
                    }
                }
                if (StringUtils.isNoneBlank(bizExtractionKeyInfoConfigModel.getFieldType())) {
                    keyInfo.setField_type(bizExtractionKeyInfoConfigModel.getFieldType());

                }
                if (StringUtils.isNoneBlank(bizExtractionKeyInfoConfigModel.getIsInTable())) {
                    keyInfo.setIs_in_table(CommonConstant.YOrN.Y.equals(bizExtractionKeyInfoConfigModel.getIsInTable()));
                }
                if (StringUtils.isNotBlank(bizExtractionKeyInfoConfigModel.getKeywords())) {
                    JSONArray jsonArray = new JSONArray(bizExtractionKeyInfoConfigModel.getKeywords());
                    if (!jsonArray.isEmpty()) {
                        keyInfo.setKeywords(jsonArray.toList().toArray(new String[0]));
                    }
                }
                keyInfoList.add(keyInfo);
            }
        }
        return textInClient.extraction(fileUrl, keyInfoList);
    }

    /**
     * 获取文件名
     *
     * @param fileUrl
     * @return
     */
    private String getFileName(String fileUrl) {
        int i = fileUrl.lastIndexOf("/");
        return fileUrl.substring(i + 1);
    }

    @Override
    public String getReviewUrl(String taskId) throws Exception {
        Assert.notNull(taskId);

        BizExtractionReviewTaskModel example = new BizExtractionReviewTaskModel();
        example.setActionType(ContractConstants.ActionType.textreview);
        example.setTaskId(taskId);
        List<BizExtractionReviewTaskModel> bizExtractionReviewTaskModelList = bizExtractionReviewTaskService.findByExample(example, null);
        if (CollectionUtils.isEmpty(bizExtractionReviewTaskModelList)) {
            return StringUtils.EMPTY;
        }

        String originUrl = "https://textmind-sdk.bce.baidu.com/textmind/sdk/textreview/{taskId}?access_token={access_token}";

        String clientId = fmxConfigService.getParam("baidu.textmind.clientId");
        String clientSecret = fmxConfigService.getParam("baidu.textmind.clientSecret");

        String accessToken = baiduTokenAPI.getToken(clientId, clientSecret).getAccess_token();

        return originUrl.replaceAll("\\{taskId}", bizExtractionReviewTaskModelList.get(0).getTextInTaskId()).replaceAll("\\{access_token}", accessToken);
    }

    @Override
    public FileUploadResponse createDocFlowTask(MultipartFile multipartFile, String workspaceid, String category) throws IOException {
        FileUploadRequest fileUploadRequest = new FileUploadRequest();
        fileUploadRequest.setFile(multipartFile);
        fileUploadRequest.setCategory(category);
        fileUploadRequest.setWorkspaceid(workspaceid);
        return textInClient.fileUpload(fileUploadRequest);
    }

    @Override
    public BizExtractionReviewTaskModel getReviewTaskByTextInTaskId(String textInTaskId) throws Exception {
        BizExtractionReviewTaskModel example = new BizExtractionReviewTaskModel();
        example.setIsDeleted(CommonConstant.IsDeleted.N);
        example.setTextInTaskId(textInTaskId);
        List<BizExtractionReviewTaskModel> bizExtractionReviewTaskModelList = bizExtractionReviewTaskService.findByExample(example, null);
        if (CollectionUtils.isNotEmpty(bizExtractionReviewTaskModelList)) {
            return bizExtractionReviewTaskModelList.get(0);
        }
        return null;
    }

}