package com.zg.common.utils;

import com.zg.framework.config.RuoYiConfig;
import io.minio.*;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.InputStream;
import java.util.Base64;
import java.util.UUID;
import java.util.Date;

@Component
public class MinioUtil {

    @Value("${minio.endpoint}")
    private String endpoint;

    @Value("${minio.accessKey}")
    private String accessKey;

    @Value("${minio.secretKey}")
    private String secretKey;

    @Value("${minio.bucketName}")
    private String defaultBucket;

    private MinioClient minioClient;

    @PostConstruct
    public void init() {
        minioClient = MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
    }

    /**
     * 自动生成今日目录：yyyy-MM-dd/
     */
    private String getTodayFolder() {
        return DateUtils.parseDateToStr("yyyy-MM-dd", DateUtils.getNowDate()) + "/";
    }

    /**
     * 上传文件到指定 bucket 和目录
     */
    public String upload(MultipartFile file, String bucketName, String folder) throws Exception {
        String originalName = file.getOriginalFilename();
        String ext = (originalName != null && originalName.contains("."))
                ? originalName.substring(originalName.lastIndexOf("."))
                : "";
        String objectName = folder + UUID.randomUUID().toString().replace("-", "") + ext;

        try (InputStream in = file.getInputStream()) {
            // 检查或创建 bucket
            boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }

            // 设置 bucket 公共策略
            String policyJson = "{\n" +
                    "  \"Version\":\"2012-10-17\",\n" +
                    "  \"Statement\":[\n" +
                    "    {\n" +
                    "      \"Effect\":\"Allow\",\n" +
                    "      \"Principal\":{\"AWS\":\"*\"},\n" +
                    "      \"Action\":[\"s3:GetObject\"],\n" +
                    "      \"Resource\":[\"arn:aws:s3:::" + bucketName + "/*\"]\n" +
                    "    }\n" +
                    "  ]\n" +
                    "}";

            minioClient.setBucketPolicy(SetBucketPolicyArgs.builder()
                    .bucket(bucketName)
                    .config(policyJson)
                    .build());

            // 上传
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(in, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build());
        }

        return endpoint + "/" + bucketName + "/" + objectName;
    }

    /**
     * 上传 Base64 图片到指定 bucket 和目录
     */
    public String uploadBase64(String imgStr, String bucketName, String folder) {
        try {
            String objectName = folder + UUID.randomUUID().toString().replace("-", "") + ".png";
            imgStr = imgStr.replace("data:image/png;base64,", "").replace("data:image/jpeg;base64,", "");
            byte[] imageBytes = Base64.getDecoder().decode(imgStr);

            boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }

            String policyJson = "{\n" +
                    "  \"Version\":\"2012-10-17\",\n" +
                    "  \"Statement\":[\n" +
                    "    {\n" +
                    "      \"Effect\":\"Allow\",\n" +
                    "      \"Principal\":{\"AWS\":\"*\"},\n" +
                    "      \"Action\":[\"s3:GetObject\"],\n" +
                    "      \"Resource\":[\"arn:aws:s3:::" + bucketName + "/*\"]\n" +
                    "    }\n" +
                    "  ]\n" +
                    "}";

            minioClient.setBucketPolicy(SetBucketPolicyArgs.builder()
                    .bucket(bucketName)
                    .config(policyJson)
                    .build());

            try (InputStream inputStream = new java.io.ByteArrayInputStream(imageBytes)) {
                minioClient.putObject(PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .stream(inputStream, imageBytes.length, -1)
                        .contentType("image/png")
                        .build());
            }

            return endpoint + "/" + bucketName + "/" + objectName;
        } catch (Exception e) {
            System.err.println("Base64上传MinIO失败：" + e.getMessage());
            return "";
        }
    }

    /**
     * 默认 bucket 上传
     */
    public String upload(MultipartFile file) throws Exception {
        return upload(file, defaultBucket, "");
    }

    /**
     * 默认 bucket 指定目录上传
     */
    public String upload(MultipartFile file, String folder) throws Exception {
        return upload(file, defaultBucket, folder);
    }

    /**
     * 默认 bucket，按日期目录上传（MultipartFile）
     */
    public String uploadToDateFolder(MultipartFile file) throws Exception {
        return upload(file, defaultBucket, getTodayFolder());
    }

    /**
     * 默认 bucket，按日期目录上传（Base64）
     */
    public String uploadBase64ToDateFolder(String imgStr) {
        return uploadBase64(imgStr, defaultBucket, getTodayFolder());
    }
}
