/**
 * Global sync progress tracker
 * Allows tracking progress of long-running sync operations
 * Can be polled from the UI to show real-time progress
 */

export interface SyncProgressState {
  syncId: string;
  entityType: string;
  status: 'idle' | 'running' | 'completed' | 'failed';
  currentPage: number;
  totalRecords: number;
  estimatedTotal?: number;
  startTime: number;
  endTime?: number;
  error?: string;
  phase: 'fetching' | 'mapping' | 'upserting' | 'deleting' | 'completed';
}

class SyncProgressTracker {
  private progressMap: Map<string, SyncProgressState> = new Map();

  /**
   * Start tracking a new sync operation
   */
  startSync(syncId: string, entityType: string): void {
    this.progressMap.set(syncId, {
      syncId,
      entityType,
      status: 'running',
      currentPage: 0,
      totalRecords: 0,
      startTime: Date.now(),
      phase: 'fetching',
    });
  }

  /**
   * Update progress for a sync operation
   */
  updateProgress(
    syncId: string,
    updates: Partial<Omit<SyncProgressState, 'syncId' | 'entityType' | 'startTime'>>
  ): void {
    const current = this.progressMap.get(syncId);
    if (!current) return;

    this.progressMap.set(syncId, {
      ...current,
      ...updates,
    });
  }

  /**
   * Mark sync as completed
   */
  completeSync(syncId: string, totalRecords: number): void {
    const current = this.progressMap.get(syncId);
    if (!current) return;

    this.progressMap.set(syncId, {
      ...current,
      status: 'completed',
      totalRecords,
      endTime: Date.now(),
      phase: 'completed',
    });
  }

  /**
   * Mark sync as failed
   */
  failSync(syncId: string, error: string): void {
    const current = this.progressMap.get(syncId);
    if (!current) return;

    this.progressMap.set(syncId, {
      ...current,
      status: 'failed',
      endTime: Date.now(),
      error,
    });
  }

  /**
   * Get progress for a specific sync
   */
  getProgress(syncId: string): SyncProgressState | null {
    return this.progressMap.get(syncId) || null;
  }

  /**
   * Get all active syncs
   */
  getActiveSyncs(): SyncProgressState[] {
    return Array.from(this.progressMap.values()).filter(
      (p) => p.status === 'running'
    );
  }

  /**
   * Get the most recent sync for an entity type
   */
  getLatestSync(entityType: string): SyncProgressState | null {
    const syncs = Array.from(this.progressMap.values())
      .filter((p) => p.entityType === entityType)
      .sort((a, b) => b.startTime - a.startTime);
    
    return syncs[0] || null;
  }

  /**
   * Clean up old completed/failed syncs (keep last 10 per entity)
   */
  cleanup(): void {
    const byEntity = new Map<string, SyncProgressState[]>();
    
    // Group by entity type
    for (const progress of this.progressMap.values()) {
      if (!byEntity.has(progress.entityType)) {
        byEntity.set(progress.entityType, []);
      }
      byEntity.get(progress.entityType)!.push(progress);
    }

    // Keep only the 10 most recent per entity
    for (const [entityType, syncs] of byEntity.entries()) {
      const sorted = syncs.sort((a, b) => b.startTime - a.startTime);
      const toKeep = sorted.slice(0, 10);
      const toRemove = sorted.slice(10);
      
      for (const sync of toRemove) {
        this.progressMap.delete(sync.syncId);
      }
    }
  }
}

// Global singleton instance
export const syncProgressTracker = new SyncProgressTracker();
