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

/**
 * Provider para IndexedDBFileSystem no workspace
 * Implementa o padrão de providers do VSCode
 */
export class IndexedDBWorkspaceProvider implements SourceProvider {
  readonly scheme = "indexeddb";
  readonly displayName = "IndexedDB File System";

  /**
   * Cria uma nova instância do IndexedDBFileSystem
   */
  async createFileSystem(config: any): Promise<IReactiveFileSystem> {
    // Configuração padrão se não fornecida
    const fsConfig = {
      dbName: config?.dbName || `firesystem-${Date.now()}`,
      version: config?.version || 1,
      storeName: config?.storeName || "files",
      enableExternalSync: config?.enableExternalSync ?? true,
      deepChangeDetection: config?.deepChangeDetection ?? false,
    };

    const fs = new IndexedDBFileSystem(fsConfig);

    // IndexedDB precisa ser inicializado para conectar ao banco
    await fs.initialize();

    return fs;
  }

  /**
   * Valida configuração do IndexedDB provider
   */
  async validateConfiguration(
    config: any,
  ): Promise<{ valid: boolean; errors?: string[] }> {
    const errors: string[] = [];

    if (config) {
      // Valida dbName
      if (config.dbName !== undefined) {
        if (typeof config.dbName !== "string") {
          errors.push("dbName must be a string");
        } else if (config.dbName.length === 0) {
          errors.push("dbName cannot be empty");
        } else if (!/^[a-zA-Z0-9_-]+$/.test(config.dbName)) {
          errors.push(
            "dbName can only contain letters, numbers, hyphens and underscores",
          );
        }
      }

      // Valida version
      if (config.version !== undefined) {
        if (typeof config.version !== "number") {
          errors.push("version must be a number");
        } else if (config.version < 1) {
          errors.push("version must be >= 1");
        } else if (!Number.isInteger(config.version)) {
          errors.push("version must be an integer");
        }
      }

      // Valida storeName
      if (config.storeName !== undefined) {
        if (typeof config.storeName !== "string") {
          errors.push("storeName must be a string");
        } else if (config.storeName.length === 0) {
          errors.push("storeName cannot be empty");
        }
      }

      // Valida enableExternalSync
      if (
        config.enableExternalSync !== undefined &&
        typeof config.enableExternalSync !== "boolean"
      ) {
        errors.push("enableExternalSync must be a boolean");
      }

      // Valida deepChangeDetection
      if (
        config.deepChangeDetection !== undefined &&
        typeof config.deepChangeDetection !== "boolean"
      ) {
        errors.push("deepChangeDetection must be a boolean");
      }
    }

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

  /**
   * Retorna as capacidades do IndexedDB FS
   */
  getCapabilities(): IFileSystemCapabilities {
    return {
      readonly: false,
      caseSensitive: true,
      atomicRename: true,
      supportsWatch: true,
      supportsMetadata: true,
      supportsGlob: true,
      supportsAtomicOperations: true,
      maxFileSize: 500 * 1024 * 1024, // 500MB practical limit
      maxPathLength: 1024,
      description:
        "Browser-based persistent storage using IndexedDB. Data survives page reloads and browser restarts.",
    };
  }

  /**
   * Limpa e destrói o file system
   */
  async dispose(fs: IReactiveFileSystem): Promise<void> {
    // Se for IndexedDBFileSystem, chamar dispose para limpar recursos
    if ("dispose" in fs && typeof fs.dispose === "function") {
      fs.dispose();
    }

    // Remove todos os event listeners se houver
    if (fs.events && "removeAllListeners" in fs.events) {
      fs.events.removeAllListeners();
    }
  }
}

// Exporta uma instância singleton para conveniência
export const indexedDBProvider = new IndexedDBWorkspaceProvider();
