import type {
  IReactiveFileSystem,
  IFileSystemCapabilities,
} from "@firesystem/core";
// Import type-only para evitar dependência em runtime
import type { SourceProvider } from "@workspace-fs/core";
import { S3FileSystem } from "../S3FileSystem";
import type { S3FileSystemConfig } from "../types";

export class S3WorkspaceProvider implements SourceProvider {
  readonly scheme = "s3";
  readonly displayName = "AWS S3 Storage";

  async createFileSystem(config: any): Promise<IReactiveFileSystem> {
    // Validar configuração primeiro
    const validation = await this.validateConfiguration(config);
    if (!validation.valid) {
      throw new Error(
        `Invalid S3 configuration: ${validation.errors?.join(", ")}`,
      );
    }

    // Configuração padrão se não fornecida
    const fsConfig: S3FileSystemConfig = {
      bucket: config.bucket,
      region: config.region,
      prefix: config.prefix || "/",
      mode: config.mode || "strict",
      credentials: config.credentials,
      clientOptions: config.clientOptions,
    };

    const fs = new S3FileSystem(fsConfig);

    // S3FileSystem tem método initialize se precisar conectar
    if ("initialize" in fs && typeof fs.initialize === "function") {
      await fs.initialize();
    }

    return fs;
  }

  getCapabilities(): IFileSystemCapabilities {
    return {
      readonly: false,
      caseSensitive: true,
      atomicRename: false, // S3 doesn't support atomic rename
      supportsWatch: false, // S3 doesn't support real-time watch
      supportsMetadata: true,
      supportsGlob: false, // S3 não tem suporte nativo para glob (é simulado via list + filter)
      maxFileSize: 5 * 1024 * 1024 * 1024 * 1024, // 5TB with multipart upload
      maxPathLength: 1024,
      description:
        "AWS S3 cloud storage with eventual consistency. Best for large files, backups, and static content.",
    };
  }

  async validateConfiguration(
    config: any,
  ): Promise<{ valid: boolean; errors?: string[] }> {
    const errors: string[] = [];

    if (!config) {
      errors.push("Configuration is required");
      return { valid: false, errors };
    }

    // Validar bucket (obrigatório)
    if (config.bucket === undefined || config.bucket === null) {
      errors.push("bucket is required");
    } else if (typeof config.bucket !== "string") {
      errors.push("bucket must be a string");
    } else if (config.bucket.trim() === "") {
      errors.push("bucket cannot be empty");
    } else if (!/^[a-z0-9.-]+$/.test(config.bucket)) {
      errors.push(
        "bucket name must contain only lowercase letters, numbers, dots, and hyphens",
      );
    }

    // Validar region (obrigatório)
    if (config.region === undefined || config.region === null) {
      errors.push("region is required");
    } else if (typeof config.region !== "string") {
      errors.push("region must be a string");
    } else if (config.region.trim() === "") {
      errors.push("region cannot be empty");
    }

    // Validar prefix (opcional)
    if (config.prefix !== undefined) {
      if (typeof config.prefix !== "string") {
        errors.push("prefix must be a string");
      } else if (config.prefix.length > 1000) {
        errors.push("prefix is too long (max 1000 characters)");
      }
    }

    // Validar mode (opcional)
    if (config.mode !== undefined) {
      if (config.mode !== "strict" && config.mode !== "lenient") {
        errors.push("mode must be 'strict' or 'lenient'");
      }
    }

    // Validar credentials (opcional)
    if (config.credentials !== undefined) {
      if (typeof config.credentials !== "object") {
        errors.push("credentials must be an object");
      } else {
        if (
          !config.credentials.accessKeyId ||
          typeof config.credentials.accessKeyId !== "string"
        ) {
          errors.push("credentials.accessKeyId must be a string");
        }
        if (
          !config.credentials.secretAccessKey ||
          typeof config.credentials.secretAccessKey !== "string"
        ) {
          errors.push("credentials.secretAccessKey must be a string");
        }
      }
    }

    // Validar clientOptions (opcional)
    if (config.clientOptions !== undefined) {
      if (typeof config.clientOptions !== "object") {
        errors.push("clientOptions must be an object");
      } else {
        if (
          config.clientOptions.endpoint !== undefined &&
          typeof config.clientOptions.endpoint !== "string"
        ) {
          errors.push("clientOptions.endpoint must be a string");
        }
        if (
          config.clientOptions.forcePathStyle !== undefined &&
          typeof config.clientOptions.forcePathStyle !== "boolean"
        ) {
          errors.push("clientOptions.forcePathStyle must be a boolean");
        }
      }
    }

    return {
      valid: errors.length === 0,
      errors: errors.length > 0 ? errors : undefined,
    };
  }

  async dispose(fs: IReactiveFileSystem): Promise<void> {
    if ("dispose" in fs && typeof fs.dispose === "function") {
      await fs.dispose();
    }
  }
}

// Export singleton instance
export const s3Provider = new S3WorkspaceProvider();
