import type { IReportRepository, ReportMetadata } from '../../interfaces/repositories/report-repository';

export class ReportRepository implements IReportRepository {
  private readonly PREFIX = 'mochaSession__';

  generateResultKey(sessionLabel: string): string {
    return `${this.PREFIX}${sessionLabel.replace(/\s+/g, '_').replace(/-/g, '_')}`;
  }

  getReportData(resultKey: string): any | null {
    return this.getWindowVariable(resultKey);
  }

  hasReport(resultKey: string): boolean {
    return this.getWindowVariable(resultKey) !== undefined;
  }

  clearReport(resultKey: string): void {
    this.deleteWindowVariable(resultKey);
  }

  getAllReports(): Record<string, any> {
    const reports: Record<string, any> = {};
    
    // Get all window variables that match our prefix
    for (const key in window) {
      if (key.startsWith(this.PREFIX)) {
        const value = this.getWindowVariable(key);
        if (value) {
          reports[key] = value;
        }
      }
    }
    
    return reports;
  }

  getReportMetadata(resultKey: string): ReportMetadata | null {
    const data = this.getReportData(resultKey);
    if (!data) return null;

    const sessionLabel = resultKey.replace(this.PREFIX, '').replace(/_/g, '-');
    
    return {
      size: JSON.stringify(data).length,
      generatedAt: data.timestamp ? new Date(data.timestamp) : new Date(),
      sessionLabel,
      stats: data.stats || {},
      isValid: this.validateReport(data)
    };
  }

  async waitForReport(resultKey: string, timeoutMs: number = 30000): Promise<any> {
    return new Promise((resolve, reject) => {
      const startTime = Date.now();
      
      const checkInterval = setInterval(() => {
        const report = this.getReportData(resultKey);
        
        if (report) {
          clearInterval(checkInterval);
          resolve(report);
          return;
        }
        
        if (Date.now() - startTime > timeoutMs) {
          clearInterval(checkInterval);
          reject(new Error(`Timeout waiting for report: ${resultKey}`));
        }
      }, 100);
    });
  }

  watchReport(resultKey: string, callback: (report: any) => void): () => void {
    let isWatching = true;
    
    const checkInterval = setInterval(() => {
      if (!isWatching) {
        clearInterval(checkInterval);
        return;
      }
      
      const report = this.getReportData(resultKey);
      if (report) {
        callback(report);
        clearInterval(checkInterval);
        isWatching = false;
      }
    }, 100);
    
    // Return cleanup function
    return () => {
      isWatching = false;
      clearInterval(checkInterval);
    };
  }

  getWindowVariable(key: string): any {
    return (window as any)[key];
  }

  setWindowVariable(key: string, value: any): void {
    (window as any)[key] = value;
  }

  deleteWindowVariable(key: string): void {
    delete (window as any)[key];
  }

  getReportSize(resultKey: string): number {
    const data = this.getReportData(resultKey);
    return data ? JSON.stringify(data).length : 0;
  }

  validateReport(reportData: any): boolean {
    if (!reportData || typeof reportData !== 'object') return false;
    
    // Basic validation - check for required properties
    return !!(
      reportData.stats &&
      typeof reportData.stats === 'object' &&
      typeof reportData.stats.tests === 'number'
    );
  }
}
