import {
  IReactiveFileSystem,
  TypedEventEmitter,
  FileSystemEventPayloads,
  FileEntry,
  FileMetadata,
  FSEvent,
  Disposable,
  FileStat,
} from "@firesystem/core";

interface S3FileSystemConfig {
  /**
   * The S3 bucket name
   */
  bucket: string;
  /**
   * AWS region
   */
  region: string;
  /**
   * Optional prefix to namespace all operations
   * @default "/"
   */
  prefix?: string;
  /**
   * AWS credentials
   */
  credentials: {
    accessKeyId: string;
    secretAccessKey: string;
  };
  /**
   * Optional S3 client configuration
   */
  clientOptions?: {
    endpoint?: string;
    forcePathStyle?: boolean;
  };
  /**
   * Compatibility mode
   * - "strict": Requires directory markers and metadata (default for new systems)
   * - "lenient": Works with any existing S3 structure
   * @default "strict"
   */
  mode?: "strict" | "lenient";
}

declare class S3FileSystem implements IReactiveFileSystem {
  private client;
  private config;
  private watchers;
  readonly events: TypedEventEmitter<FileSystemEventPayloads>;
  constructor(config: S3FileSystemConfig);
  initialize(): Promise<void>;
  private toS3Key;
  private fromS3Key;
  private streamToString;
  private ensureDirectoryMarker;
  private ensureParentExists;
  private parseS3Metadata;
  private createS3Metadata;
  readFile(path: string): Promise<FileEntry>;
  writeFile(
    path: string,
    content: any,
    metadata?: FileMetadata,
  ): Promise<FileEntry>;
  deleteFile(path: string): Promise<void>;
  exists(path: string): Promise<boolean>;
  readDir(path: string): Promise<FileEntry[]>;
  mkdir(path: string, recursive?: boolean): Promise<FileEntry>;
  rmdir(path: string, recursive?: boolean): Promise<void>;
  rename(oldPath: string, newPath: string): Promise<FileEntry>;
  move(sourcePaths: string[], targetPath: string): Promise<void>;
  copy(sourcePath: string, targetPath: string): Promise<FileEntry>;
  watch(pattern: string, callback: (event: FSEvent) => void): Disposable;
  private notifyWatchers;
  private matchGlob;
  private isDirectory;
  stat(path: string): Promise<FileStat>;
  glob(pattern: string): Promise<string[]>;
  clear(): Promise<void>;
  size(): Promise<number>;
  canModify(path: string): Promise<boolean>;
  canCreateIn(parentPath: string): Promise<boolean>;
}

export { S3FileSystem, type S3FileSystemConfig };
