/**
 * Design System Server (DSS) - Figma Service
 *
 * Client-side interface to Figma API tools.
 * No mocks - requires backend connection.
 */
import notificationService from './notification-service.js';

class FigmaService {
  constructor() {
    this.apiBase = '/api/figma';
    this.connected = null; // null = unknown, true/false = checked
    this.listeners = new Set();
  }

  // === Connection ===

  async checkConnection() {
    try {
      const response = await fetch('/health', { method: 'GET' });
      this.connected = response.ok;
    } catch {
      this.connected = false;
    }
    return this.connected;
  }

  _requireConnection() {
    if (this.connected === false) {
      throw new Error('API unavailable. Start DSS server first.');
    }
  }

  // === Event System ===

  on(event, callback) {
    this.listeners.add({ event, callback });
    return () => this.listeners.delete({ event, callback });
  }

  emit(event, data) {
    this.listeners.forEach(l => {
      if (l.event === event) l.callback(data);
    });
  }

  // === API Methods ===

  async extractVariables(fileKey, format = 'css') {
    this._requireConnection();
    this.emit('loading', { operation: 'extractVariables' });

    try {
      const response = await fetch(`${this.apiBase}/extract-variables`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ file_key: fileKey, format })
      });

      if (!response.ok) {
        const err = await response.json().catch(() => ({}));
        throw new Error(err.detail || 'Failed to extract variables');
      }

      const result = await response.json();
      this.emit('complete', { operation: 'extractVariables', result });

      notificationService.create({
        title: 'Variables Extracted',
        message: `Successfully extracted ${result.variable_count || 'variables'} from Figma.`,
        type: 'success',
        source: 'Figma',
        actions: [
          { label: 'View Tokens', event: 'navigate', payload: { page: 'tokens' } }
        ]
      });

      return result;
    } catch (error) {
      notificationService.create({
        title: 'Extraction Failed',
        message: error.message,
        type: 'error',
        source: 'Figma'
      });
      throw error;
    }
  }

  async extractComponents(fileKey) {
    this._requireConnection();
    this.emit('loading', { operation: 'extractComponents' });

    const response = await fetch(`${this.apiBase}/extract-components`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ file_key: fileKey })
    });

    if (!response.ok) {
      const err = await response.json().catch(() => ({}));
      throw new Error(err.detail || 'Failed to extract components');
    }

    const result = await response.json();
    this.emit('complete', { operation: 'extractComponents', result });
    return result;
  }

  async extractStyles(fileKey) {
    this._requireConnection();
    this.emit('loading', { operation: 'extractStyles' });

    const response = await fetch(`${this.apiBase}/extract-styles`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ file_key: fileKey })
    });

    if (!response.ok) {
      const err = await response.json().catch(() => ({}));
      throw new Error(err.detail || 'Failed to extract styles');
    }

    return response.json();
  }

  async syncTokens(fileKey, targetPath, format = 'css') {
    this._requireConnection();
    this.emit('loading', { operation: 'syncTokens' });

    try {
      const response = await fetch(`${this.apiBase}/sync-tokens`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ file_key: fileKey, target_path: targetPath, format })
      });

      if (!response.ok) {
        const err = await response.json().catch(() => ({}));
        throw new Error(err.detail || 'Sync failed');
      }

      const result = await response.json();
      this.emit('complete', { operation: 'syncTokens', result });

      notificationService.create({
        title: 'Tokens Synced',
        message: `Tokens successfully written to ${result.path || targetPath}.`,
        type: 'success',
        source: 'Figma',
        actions: [
          { label: 'View Tokens', event: 'navigate', payload: { page: 'tokens' } }
        ]
      });

      return result;
    } catch (error) {
      notificationService.create({
        title: 'Token Sync Failed',
        message: error.message,
        type: 'error',
        source: 'Figma',
        actions: [
          { label: 'Retry', event: 'figma:sync', payload: { fileKey } }
        ]
      });
      throw error;
    }
  }

  async visualDiff(fileKey, baselineVersion = 'latest') {
    this._requireConnection();
    this.emit('loading', { operation: 'visualDiff' });

    const response = await fetch(`${this.apiBase}/visual-diff`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ file_key: fileKey, baseline_version: baselineVersion })
    });

    if (!response.ok) {
      const err = await response.json().catch(() => ({}));
      throw new Error(err.detail || 'Visual diff failed');
    }

    return response.json();
  }

  async validateComponents(fileKey) {
    this._requireConnection();
    this.emit('loading', { operation: 'validateComponents' });

    const response = await fetch(`${this.apiBase}/validate-components`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ file_key: fileKey })
    });

    if (!response.ok) {
      const err = await response.json().catch(() => ({}));
      throw new Error(err.detail || 'Validation failed');
    }

    return response.json();
  }

  async generateCode(fileKey, componentName, framework = 'webcomponent') {
    this._requireConnection();
    this.emit('loading', { operation: 'generateCode' });

    const response = await fetch(`${this.apiBase}/generate-code`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ file_key: fileKey, component_name: componentName, framework })
    });

    if (!response.ok) {
      const err = await response.json().catch(() => ({}));
      throw new Error(err.detail || 'Code generation failed');
    }

    return response.json();
  }
}

const figmaService = new FigmaService();
export { FigmaService };
export default figmaService;
