package org.xyzh.file.strategy;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.xyzh.file.config.FileStorageConfig;
import org.xyzh.file.strategy.impl.LocalFileStorageStrategy;
import org.xyzh.file.strategy.impl.MinIOFileStorageStrategy;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @description 文件存储策略工厂
 * @filename FileStorageStrategyFactory.java
 * @author yslg
 * @copyright xyzh
 * @since 2025-10-16
 */
@Slf4j
@Component
public class FileStorageStrategyFactory {

    private final String defaultStorageType;
    private final Map<String, FileStorageStrategy> strategyMap = new ConcurrentHashMap<>();

    public FileStorageStrategyFactory(FileStorageConfig config) {
        this.defaultStorageType = config.getDefaultType();
        
        // 根据配置动态创建存储策略
        for (FileStorageConfig.StorageProperties storage : config.getStorages()) {
            if (storage.getEnabled() == null || !storage.getEnabled()) {
                log.info("跳过未启用的存储策略: {}", storage.getType());
                continue;
            }
            
            FileStorageStrategy strategy = createStrategy(storage);
            if (strategy != null) {
                strategyMap.put(storage.getType(), strategy);
                log.info("注册存储策略: {}", storage.getType());
            }
        }
        
        if (strategyMap.isEmpty()) {
            log.warn("没有配置任何存储策略，将使用默认本地存储");
            strategyMap.put("local", new LocalFileStorageStrategy("./uploads", "http://localhost:8080/files"));
        }
        
        log.info("文件存储策略工厂初始化完成，默认存储类型: {}, 已注册策略: {}", 
                defaultStorageType, strategyMap.keySet());
    }

    /**
     * @description 根据配置创建存储策略
     * @param storage 存储配置
     * @return FileStorageStrategy 存储策略
     * @author yslg
     * @since 2025-10-16
     */
    private FileStorageStrategy createStrategy(FileStorageConfig.StorageProperties storage) {
        try {
            return switch (storage.getType().toLowerCase()) {
                case "local" -> new LocalFileStorageStrategy(
                        storage.getBasePath(),
                        storage.getUrlPrefix()
                );
                case "minio" -> new MinIOFileStorageStrategy(
                        storage.getEndpoint(),
                        storage.getAccessKey(),
                        storage.getSecretKey(),
                        storage.getBucketName()
                );
                default -> {
                    log.warn("未知的存储类型: {}", storage.getType());
                    yield null;
                }
            };
        } catch (Exception e) {
            log.error("创建存储策略失败: type={}", storage.getType(), e);
            return null;
        }
    }

    /**
     * @description 获取默认存储策略
     * @return FileStorageStrategy 存储策略
     * @author yslg
     * @since 2025-10-16
     */
    public FileStorageStrategy getDefaultStrategy() {
        return getStrategy(defaultStorageType);
    }

    /**
     * @description 根据类型获取存储策略
     * @param storageType 存储类型
     * @return FileStorageStrategy 存储策略
     * @author yslg
     * @since 2025-10-16
     */
    public FileStorageStrategy getStrategy(String storageType) {
        FileStorageStrategy strategy = strategyMap.get(storageType);
        if (strategy == null) {
            log.warn("未找到存储类型 {} 的策略，使用默认策略: {}", storageType, defaultStorageType);
            strategy = strategyMap.get(defaultStorageType);
        }
        return strategy;
    }

    /**
     * @description 注册新的存储策略
     * @param storageType 存储类型
     * @param strategy 存储策略
     * @author yslg
     * @since 2025-10-16
     */
    public void registerStrategy(String storageType, FileStorageStrategy strategy) {
        strategyMap.put(storageType, strategy);
        log.info("注册新的存储策略: {}", storageType);
    }
}

