package org.xyzh.file.config;

import io.minio.MinioClient;
import lombok.Data;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.xyzh.api.system.service.SysConfigService;

import org.apache.dubbo.config.annotation.DubboReference;
import jakarta.annotation.PostConstruct;

/**
 * @description MinIO 配置类，从数据库读取配置信息
 * @filename MinioConfig.java
 * @author yslg
 * @copyright yslg
 * @since 2025-12-09
 */
@Data
@Component
public class MinioConfig {
    
    private static final Logger logger = LoggerFactory.getLogger(MinioConfig.class);
    
    @DubboReference(version = "1.0.0", group = "system", timeout = 3000, retries = 0)
    private SysConfigService sysConfigService;
    
    // MinIO 配置项的键名
    private static final String MINIO_ENDPOINT_KEY = "minio.endpoint";
    private static final String MINIO_ACCESS_KEY = "minio.accessKey";
    private static final String MINIO_SECRET_KEY = "minio.secretKey";
    private static final String MINIO_BUCKET_NAME_KEY = "minio.bucketName";
    private static final String MINIO_PUBLIC_URL_KEY = "minio.publicUrl";
    
    // 默认值
    private static final String DEFAULT_ENDPOINT = "http://localhost:9000";
    private static final String DEFAULT_ACCESS_KEY = "minioadmin";
    private static final String DEFAULT_SECRET_KEY = "minioadmin123";
    private static final String DEFAULT_BUCKET_NAME = "urban-lifeline";
    private static final String DEFAULT_PUBLIC_URL = "http://localhost:9000";
    
    // 配置属性
    private String endpoint;
    private String accessKey;
    private String secretKey;
    private String bucketName;
    private String publicUrl;
    
    private MinioClient minioClient;
    
    @PostConstruct
    public void init() {
        loadConfig();
        initClient();
    }
    
    /**
     * 从数据库加载MinIO配置
     */
    private void loadConfig() {
        try {
            endpoint = sysConfigService.getStringConfig(MINIO_ENDPOINT_KEY);
            accessKey = sysConfigService.getStringConfig(MINIO_ACCESS_KEY);
            secretKey = sysConfigService.getStringConfig(MINIO_SECRET_KEY);
            bucketName = sysConfigService.getStringConfig(MINIO_BUCKET_NAME_KEY);
            publicUrl = sysConfigService.getStringConfig(MINIO_PUBLIC_URL_KEY);
            
            // 使用默认值如果配置不存在
            if (endpoint == null || endpoint.trim().isEmpty()) {
                endpoint = DEFAULT_ENDPOINT;
                logger.warn("未找到MinIO endpoint配置，使用默认值: {}", DEFAULT_ENDPOINT);
            }
            if (accessKey == null || accessKey.trim().isEmpty()) {
                accessKey = DEFAULT_ACCESS_KEY;
                logger.warn("未找到MinIO accessKey配置，使用默认值");
            }
            if (secretKey == null || secretKey.trim().isEmpty()) {
                secretKey = DEFAULT_SECRET_KEY;
                logger.warn("未找到MinIO secretKey配置，使用默认值");
            }
            if (bucketName == null || bucketName.trim().isEmpty()) {
                bucketName = DEFAULT_BUCKET_NAME;
                logger.warn("未找到MinIO bucketName配置，使用默认值: {}", DEFAULT_BUCKET_NAME);
            }
            if (publicUrl == null || publicUrl.trim().isEmpty()) {
                publicUrl = endpoint; // 默认使用endpoint作为公网访问地址
                logger.warn("未找到MinIO publicUrl配置，使用endpoint作为默认值: {}", endpoint);
            }
            
            logger.info("MinIO配置加载完成 - endpoint: {}, bucketName: {}", endpoint, bucketName);
            
        } catch (Exception e) {
            logger.error("加载MinIO配置失败，使用默认配置", e);
            endpoint = DEFAULT_ENDPOINT;
            accessKey = DEFAULT_ACCESS_KEY;
            secretKey = DEFAULT_SECRET_KEY;
            bucketName = DEFAULT_BUCKET_NAME;
            publicUrl = DEFAULT_PUBLIC_URL;
        }
    }
    
    /**
     * 初始化MinIO客户端
     */
    private void initClient() {
        try {
            minioClient = MinioClient.builder()
                    .endpoint(endpoint)
                    .credentials(accessKey, secretKey)
                    .build();
            
            logger.info("MinIO客户端初始化成功");
        } catch (Exception e) {
            logger.error("MinIO客户端初始化失败", e);
            throw new RuntimeException("MinIO客户端初始化失败", e);
        }
    }
    
    /**
     * 重新加载配置
     */
    public void reloadConfig() {
        logger.info("重新加载MinIO配置");
        loadConfig();
        initClient();
    }
    
    /**
     * 获取MinIO客户端
     */
    public MinioClient getMinioClient() {
        return minioClient;
    }
    
    /**
     * 构建文件的公网访问URL
     * @param objectName 对象名称
     * @return 完整的文件访问URL
     */
    public String buildFileUrl(String objectName) {
        return publicUrl + "/" + bucketName + "/" + objectName;
    }
}
