import type { WorkspaceConfig, ProjectConfig } from "../types";

export interface WorkspaceExport {
  version: string;
  exportedAt: Date;
  workspace: {
    settings?: any;
    activeProjectId?: string;
  };
  projects: Array<{
    id: string;
    name: string;
    type: "memory" | "indexeddb" | "s3";
    config?: any;
    files?: Array<{
      path: string;
      content: string;
      metadata?: Record<string, any>;
    }>;
  }>;
}

/**
 * Handles import/export of workspace configurations
 */
export class WorkspaceImporter {
  /**
   * Import workspace from JSON URL
   */
  static async fromJsonUrl(url: string): Promise<WorkspaceConfig> {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`Failed to fetch workspace: ${response.statusText}`);
    }

    const data: WorkspaceExport = await response.json();
    return this.parseExport(data);
  }

  /**
   * Import workspace from GitHub Gist
   */
  static async fromGitHubGist(gistId: string, token?: string): Promise<WorkspaceConfig> {
    const headers: Record<string, string> = {
      "Accept": "application/vnd.github.v3+json"
    };

    if (token) {
      headers["Authorization"] = `token ${token}`;
    }

    const response = await fetch(`https://api.github.com/gists/${gistId}`, {
      headers
    });

    if (!response.ok) {
      throw new Error(`Failed to fetch gist: ${response.statusText}`);
    }

    const gist = await response.json();
    
    // Look for workspace.json file in the gist
    const workspaceFile = Object.values(gist.files).find(
      (file: any) => file.filename === "workspace.json"
    ) as any;

    if (!workspaceFile) {
      throw new Error("No workspace.json found in gist");
    }

    const data: WorkspaceExport = JSON.parse(workspaceFile.content);
    return this.parseExport(data);
  }

  /**
   * Import workspace from API endpoint
   */
  static async fromApi(
    url: string, 
    options?: {
      headers?: Record<string, string>;
      method?: string;
      body?: any;
    }
  ): Promise<WorkspaceConfig> {
    const response = await fetch(url, {
      method: options?.method || "GET",
      headers: {
        "Content-Type": "application/json",
        ...options?.headers
      },
      body: options?.body ? JSON.stringify(options.body) : undefined
    });

    if (!response.ok) {
      throw new Error(`Failed to fetch from API: ${response.statusText}`);
    }

    const data: WorkspaceExport = await response.json();
    return this.parseExport(data);
  }

  /**
   * Parse export data into workspace config
   */
  private static parseExport(data: WorkspaceExport): WorkspaceConfig {
    // Validate version
    if (!data.version || !data.version.startsWith("1.")) {
      throw new Error(`Unsupported workspace version: ${data.version}`);
    }

    const projects: ProjectConfig[] = data.projects.map(p => {
      // Determine source based on type and presence of files
      let source: any;

      if (p.files && p.files.length > 0) {
        // If files are included, create memory source with initial data
        source = {
          type: "memory",
          config: {
            initialData: p.files.reduce((acc, file) => {
              acc[file.path] = {
                content: file.content,
                metadata: file.metadata
              };
              return acc;
            }, {} as Record<string, any>)
          }
        };
      } else if (p.type === "indexeddb") {
        // IndexedDB reference
        source = {
          type: "indexeddb",
          config: {
            dbName: p.config?.dbName || `firesystem-${p.id}`
          }
        };
      } else if (p.type === "s3") {
        // S3 reference
        source = {
          type: "s3",
          config: p.config
        };
      } else {
        // Default to empty memory
        source = {
          type: "memory",
          config: {}
        };
      }

      return {
        id: p.id,
        name: p.name,
        source
      };
    });

    return {
      version: data.version,
      projects,
      activeProjectId: data.workspace.activeProjectId,
      settings: data.workspace.settings
    };
  }
}