package com.sqx.modules.file.service;

import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.sqx.common.constant.RedisKey;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.RedisUtils;
import com.sqx.config.MinioConfig;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.file.utils.FileUploadUtils;
import com.sqx.modules.file.utils.MimeTypeUtils;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;

/**
 * @author codingliang
 * @date 2025-10-21
 */
@Service
@RequiredArgsConstructor
public class NewFileService {

    private final CommonInfoService commonInfoService;
    private final MinioClient minioClient;
    private final MinioConfig minioConfig;
    private final RedisUtils redisUtils;

    public String upload(MultipartFile file) {
        // 新增图片类型验证
        String extension = FileUploadUtils.getExtension(file);
        if (!FileUploadUtils.isAllowedExtension(extension, MimeTypeUtils.IMAGE_EXTENSION)) {
            throw new SqxException("文件必须为图片类型");
        }

        // 上传方式 1阿里云oss  2本地 3 minio
        String value = commonInfoService.findOne(234).getValue();
        if(StrUtil.equals(value, "1")){
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(commonInfoService.findOne(68).getValue(), commonInfoService.findOne(69).getValue(), commonInfoService.findOne(70).getValue());
            String suffix = file.getOriginalFilename().substring(Objects.requireNonNull(file.getOriginalFilename()).lastIndexOf("."));
            // 上传文件流
            InputStream inputStream;
            try {
                inputStream = new ByteArrayInputStream(file.getBytes());
            } catch (IOException e) {
                throw new SqxException("文件上传失败!" + e.getMessage());
            }
            String completePath = getPath(suffix);
            ossClient.putObject(commonInfoService.findOne(71).getValue(), completePath, inputStream);
            ossClient.shutdown();
            return commonInfoService.findOne(72).getValue()+ "/" + completePath;
        } else if (StrUtil.equals(value, "3")) {
            String suffix = file.getOriginalFilename().substring(Objects.requireNonNull(file.getOriginalFilename()).lastIndexOf("."));
            String completePath = getPath(suffix);
            try {
                minioClient.putObject(PutObjectArgs.builder()
                        .bucket(minioConfig.getBucket())
                        .object(completePath)
                        .stream(file.getInputStream(), file.getSize(), -1)
                        .build());

                return commonInfoService.findOne(72).getValue() + "/" + completePath;
            } catch (Exception e) {
                throw new SqxException("文件上传失败!");
            }
        } else{
            try {
                String http = commonInfoService.findOne(19).getValue();
                String[] split = http.split("://");
                // 上传文件路径
                String filePath ="/mydata/project/media/" + split[1] + "/file/uploadPath";
                // 上传并返回新文件名称
                String fileName = FileUploadUtils.upload(filePath, file);
                return http + fileName;
            } catch (Exception e) {
                throw new SqxException("文件上传失败!");
            }
        }
    }

    public String upload(String clientIp, MultipartFile file) {
        String ipLimitKey = String.format(RedisKey.IMAGE_UPLOAD_TOKEN_CACHE_KEY_IP_LIMIT, clientIp);
        long count = redisUtils.increment(ipLimitKey);

        if (count == 1) {
            // 第一次访问，设置过期时间为1小时
            redisUtils.expire(ipLimitKey, RedisUtils.HOUR_ONE_EXPIRE);
        } else if (count > 15) {
            // 超过限制，抛出异常
            throw new SqxException("获取上传token过于频繁，请稍后再试");
        }

        // 上传文件
        return upload(file);
    }

    private String getPath(String suffix) {
        // 生成uuid
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        // 文件路径
        String path = DateFormatUtils.format(new Date(), "yyyyMMdd") + "/" + uuid;
        return path + suffix;
    }
}
