package org.springblade.file.feign;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.file.config.ObsProperties;
import org.springblade.file.pojo.dto.*;
import org.springblade.file.pojo.entity.Attachment;
import org.springblade.file.pojo.vo.*;
import org.springblade.file.service.*;
import org.springblade.file.util.ObjectKeyUtils;
import org.springblade.thirdparty.ocr.pojo.vo.TransportCertificateVO;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * @author bfhuange
 * @date 2024/10/21
 */
@Slf4j
@Valid
@Hidden
@RestController
@AllArgsConstructor
public class FileClient implements IFileClient, IFileUploadClient {

    private final IAttachmentService attachmentService;
    private final IBusinessAttachmentService businessAttachmentService;
    private final IBusinessUnzipTaskService businessUnzipTaskService;
    private final IOCRConvertService ocrConvertService;
    private final IFileService fileService;
    private final ObsProperties obsProperties;

    @Override
    @GetMapping(ATTACHMENT)
    public R<List<Attachment>> getAttachment(String id) {
        return R.data(attachmentService.getAttachment(id));
    }

    @Override
    public R<AttachmentDetailVO> getAttachmentDetail(Long id) {
        return R.data(attachmentService.getDetail(id));
    }

    @Override
    public R saveAndRemoveBusinessAttachment(@RequestBody @Validated BusinessAttachmentBatchAddDTO param) {
        return R.status(businessAttachmentService.saveAndRemove(param));
    }

    @Override
    public R batchSaveAndRemoveBusinessAttachment(@RequestBody List<@Valid BusinessAttachmentAddDTO> params, @RequestParam(value = "bizId", required = false) Long bizId) {
        return R.status(businessAttachmentService.saveAndRemove(params, new BusinessAttachmentDeleteDTO(bizId)));
    }

    @Override
    public R batchSaveAndRemoveByParamBusinessAttachment(@RequestBody List<@Valid BusinessAttachmentAddDTO> params, @Valid BusinessAttachmentDeleteDTO deleteParam) {
        return R.status(businessAttachmentService.saveAndRemove(params, deleteParam));
    }

    @Override
    public R batchSaveAndRemoveBusinessAttachment(List<@Valid BusinessAttachmentAddDTO> params) {
        return R.status(businessAttachmentService.saveAndRemove(params, null));
    }

    @Override
    public R removeBusinessAttachment(@NotNull(message = "业务id不能为空") @RequestParam(value = "bizId", required = false) Long bizId) {
        businessAttachmentService.removeByBizIds(List.of(bizId));
        return R.data(true);
    }

    @Override
    public R<List<BusinessAttachmentVO>> getBusinessAttachments(@Validated @RequestBody BusinessAttachmentQueryDTO param) {
        return R.data(businessAttachmentService.queryList(param));
    }

    @Override
    public R saveBusinessUnzipTask(BusinessUnzipTaskAddDTO param) {
        return R.status(businessUnzipTaskService.save(param));
    }

    @Override
    public R updateBusinessUnzipTask(BusinessUnzipTaskUpdateDTO param) {
        Func.requireNotNull(param.getBizId(), "业务id不能为空");
        return R.status(businessUnzipTaskService.updateReupload(param));
    }

    @Override
    public R cancelBusinessUnzipTask(@NotNull(message = "业务id不能为空") Long bizId) {
        return R.status(businessUnzipTaskService.cancelBusinessUnzipTask(bizId, true));
    }

    @Override
    public R removeBusinessUnzipTask(Long bizId) {
        return R.status(businessUnzipTaskService.cancelBusinessUnzipTask(bizId, false));
    }

    @Override
    public R<List<BusinessUnzipTaskListVO>> getBusinessUnzipTasksByBizIds(List<Long> bizIds) {
        return R.data(businessUnzipTaskService.getBusinessUnzipTasksByBizIds(bizIds));
    }

    @Override
    public R<List<BusinessUnzipDetailListVO>> queryBusinessUnzipDetail(@NotNull(message = "业务id不能为空") Long bizId) {
        return R.data(businessUnzipTaskService.queryBusinessUnzipDetail(bizId));
    }

    @SentinelResource("ocr:batchCards")
    @Override
    public R<TransportCertificateVO> recognitionTransportCertificates(@Validated @RequestBody FileCertificateBatchRecognitionDTO param) {
        return R.data(ocrConvertService.recognitionTransportCertificate(param));
    }

    @Override
    public R<List<FileUrlVO>> getFileUrls(IdsDTO param) {
        List<FileUrlVO> list = attachmentService.listByIds(param.getIds()).stream()
                .map(attachment -> {
                    String fileUrl = fileService.getFileUrl(attachment.getObjectKey(), attachment.getAttachmentName(), null);
                    return new FileUrlVO(attachment.getId(), fileUrl);
                })
                .toList();
        return R.data(list);
    }

    @Override
    public R<List<Attachment>> ossUpload(MultipartFile[] files) {
        R<List<Attachment>> r = attachmentService.batchOssUpload(files, null);
        return R.isNotSuccess(r) ? R.fail(r.getCode(), r.getMsg()) : R.data(r.getData(), r.getMsg());
    }

    @Override
    public R<TempFileUrlVO> ossUploadTemp(MultipartFile file, Integer expires) {
        if (expires == null) {
            // 默认1天过期
            expires = 1;
        }
        try {
            String objectKey = ObjectKeyUtils.generateObjectKey(obsProperties.getTmpUploadDir(), file.getOriginalFilename());
            String fileUrl = fileService.uploadTempFile(objectKey, file.getInputStream(), expires);
            return R.data(new TempFileUrlVO(objectKey, fileUrl));
        } catch (Exception e) {
            log.error("上传临时文件异常", e);
            return R.fail("上传临时文件异常");
        }
    }
}
