/**
 * Sync Manager for offline actions
 * Handles synchronization of queued actions when connection is restored
 */

import { offlineStorage, type QueuedAction } from './offline-storage';
import { secureAuthService } from './secure-auth';

class SyncManager {
  private isSyncing = false;
  private syncInProgress = false;

  /**
   * Start sync process
   */
  async startSync(): Promise<void> {
    if (this.syncInProgress) {
      console.log('Sync already in progress');
      return;
    }

    this.syncInProgress = true;
    console.log('Starting sync of offline actions...');

    try {
      // Get all pending actions
      const actions = await offlineStorage.getAll<QueuedAction>('queued_actions');
      const pendingActions = actions.filter((a) => a.status === 'pending');

      console.log(`Found ${pendingActions.length} pending actions to sync`);

      // Process each action
      for (const action of pendingActions) {
        await this.processAction(action);
      }

      console.log('Sync completed successfully');
    } catch (error) {
      console.error('Sync failed:', error);
      throw error;
    } finally {
      this.syncInProgress = false;
    }
  }

  /**
   * Process a single action
   */
  private async processAction(action: QueuedAction): Promise<void> {
    try {
      console.log(`Processing action ${action.id} of type ${action.type}`);

      // Update status to processing
      await offlineStorage.update('queued_actions', {
        ...action,
        status: 'processing',
      });

      // Execute action based on type
      let success = false;
      switch (action.type) {
        case 'send_message':
          success = await this.syncMessage(action);
          break;
        case 'upload_track':
          success = await this.syncUpload(action);
          break;
        case 'update_profile':
          success = await this.syncProfileUpdate(action);
          break;
        default:
          console.warn(`Unknown action type: ${action.type}`);
      }

      if (success) {
        // Mark as completed and remove from queue
        await offlineStorage.update('queued_actions', {
          ...action,
          status: 'completed',
        });
        console.log(`Action ${action.id} synced successfully`);
      } else {
        throw new Error('Action failed');
      }
    } catch (error) {
      console.error(`Failed to sync action ${action.id}:`, error);

      // Increment retry count
      await offlineStorage.update('queued_actions', {
        ...action,
        retries: action.retries + 1,
        status: action.retries + 1 >= 3 ? 'failed' : 'pending',
      });

      if (action.retries >= 3) {
        console.error(`Action ${action.id} failed after 3 retries`);
      }
    }
  }

  /**
   * Sync a message action
   */
  private async syncMessage(action: QueuedAction): Promise<boolean> {
    const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8080/api/v1';

    try {
      const response = await fetch(`${API_BASE_URL}/chat/messages`, {
        method: 'POST',
        credentials: 'include',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(action.payload),
      });

      return response.ok;
    } catch (error) {
      console.error('Failed to sync message:', error);
      return false;
    }
  }

  /**
   * Sync an upload action
   */
  private async syncUpload(action: QueuedAction): Promise<boolean> {
    const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8080/api/v1';

    try {
      // Get file from storage
      const fileData = await offlineStorage.get('uploaded_files', action.payload.fileId);
      if (!fileData) {
        console.error('File not found in storage');
        return false;
      }

      // Upload file
      const formData = new FormData();
      formData.append('file', fileData.file);
      formData.append('title', action.payload.title);
      formData.append('artist', action.payload.artist);

      const response = await fetch(`${API_BASE_URL}/upload`, {
        method: 'POST',
        credentials: 'include',
        body: formData,
      });

      return response.ok;
    } catch (error) {
      console.error('Failed to sync upload:', error);
      return false;
    }
  }

  /**
   * Sync a profile update action
   */
  private async syncProfileUpdate(action: QueuedAction): Promise<boolean> {
    const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8080/api/v1';

    try {
      const response = await fetch(`${API_BASE_URL}/profile`, {
        method: 'PATCH',
        credentials: 'include',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(action.payload),
      });

      return response.ok;
    } catch (error) {
      console.error('Failed to sync profile update:', error);
      return false;
    }
  }

  /**
   * Get sync status
   */
  async getSyncStatus(): Promise<{
    pending: number;
    processing: number;
    failed: number;
  }> {
    const actions = await offlineStorage.getAll<QueuedAction>('queued_actions');

    return {
      pending: actions.filter((a) => a.status === 'pending').length,
      processing: actions.filter((a) => a.status === 'processing').length,
      failed: actions.filter((a) => a.status === 'failed').length,
    };
  }

  /**
   * Clear failed actions
   */
  async clearFailed(): Promise<void> {
    const actions = await offlineStorage.getAll<QueuedAction>('queued_actions');
    const failedActions = actions.filter((a) => a.status === 'failed');

    for (const action of failedActions) {
      await offlineStorage.delete('queued_actions', action.id);
    }

    console.log(`Cleared ${failedActions.length} failed actions`);
  }
}

// Export singleton instance
export const syncManager = new SyncManager();

