/**
 * DSS API Client
 *
 * Communicates with the DSS server.
 */

import { getConfig } from './config.js';

export interface ApiOptions {
  port?: number;
  baseUrl?: string;
}

export class DSSApiClient {
  private baseUrl: string;

  constructor(options: ApiOptions = {}) {
    const config = getConfig();
    const port = options.port || config.port || 3456;
    this.baseUrl = options.baseUrl || `http://localhost:${port}/api`;
  }

  private async request<T>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<T> {
    const url = `${this.baseUrl}${endpoint}`;
    const response = await fetch(url, {
      ...options,
      headers: {
        'Content-Type': 'application/json',
        ...options.headers,
      },
    });

    if (!response.ok) {
      const errorData = await response.json().catch(() => ({ message: response.statusText })) as { message?: string };
      throw new Error(errorData.message || `Request failed: ${response.status}`);
    }

    const text = await response.text();
    return text ? JSON.parse(text) as T : {} as T;
  }

  async health(): Promise<{ status: string; figma_mode: string }> {
    // Health endpoint is at root, not under /api
    const url = this.baseUrl.replace('/api', '') + '/health';
    const response = await fetch(url);
    return response.json() as Promise<{ status: string; figma_mode: string }>;
  }

  async getConfig(): Promise<Record<string, unknown>> {
    return this.request('/config');
  }

  async setFigmaToken(token: string): Promise<void> {
    await this.request('/config', {
      method: 'PUT',
      body: JSON.stringify({ figma_token: token }),
    });
  }

  async testFigmaConnection(): Promise<{ success: boolean; user?: string; error?: string }> {
    return this.request('/config/figma/test', { method: 'POST' });
  }

  async extractTokens(fileKey: string, format: string = 'css'): Promise<{
    success: boolean;
    tokens_count: number;
    tokens: Array<{ name: string; value: string; type: string; category: string }>;
    formatted_output: string;
    output_path: string;
  }> {
    return this.request('/figma/extract-variables', {
      method: 'POST',
      body: JSON.stringify({ file_key: fileKey, format }),
    });
  }

  async extractComponents(fileKey: string): Promise<{
    success: boolean;
    components_count: number;
    components: Array<{ name: string; key: string; description: string; variants: string[] }>;
    output_path: string;
  }> {
    return this.request('/figma/extract-components', {
      method: 'POST',
      body: JSON.stringify({ file_key: fileKey }),
    });
  }

  async syncTokens(fileKey: string, targetPath: string, format: string = 'css'): Promise<{
    success: boolean;
    tokens_synced: number;
    output_file: string;
  }> {
    return this.request('/figma/sync-tokens', {
      method: 'POST',
      body: JSON.stringify({ file_key: fileKey, target_path: targetPath, format }),
    });
  }

  async generateCode(fileKey: string, componentName: string, framework: string = 'react'): Promise<{
    success: boolean;
    component: string;
    framework: string;
    code: string;
  }> {
    return this.request('/figma/generate-code', {
      method: 'POST',
      body: JSON.stringify({ file_key: fileKey, component_name: componentName, framework }),
    });
  }

  async getProjects(): Promise<Array<{
    id: string;
    name: string;
    figma_file_key: string;
    status: string;
  }>> {
    return this.request('/projects');
  }

  async createProject(data: {
    name: string;
    description?: string;
    figma_file_key?: string;
  }): Promise<{ id: string; name: string }> {
    return this.request('/projects', {
      method: 'POST',
      body: JSON.stringify(data),
    });
  }
}

// Singleton instance
let apiClient: DSSApiClient | null = null;

export function getApiClient(options?: ApiOptions): DSSApiClient {
  if (!apiClient || options) {
    apiClient = new DSSApiClient(options);
  }
  return apiClient;
}
