export interface VTTCue {
  startTime: number; // seconds
  endTime: number;   // seconds
  text: string;
  identifier?: string;
}

export class VTTParser {
  static parse(vttContent: string): VTTCue[] {
    const lines = vttContent.trim().split('\n');
    const cues: VTTCue[] = [];
    
    let i = 0;
    while (i < lines.length) {
      const line = lines[i].trim();
      
      // Skip WEBVTT header, empty lines, and NOTE lines
      if (line === 'WEBVTT' || line === '' || line.startsWith('NOTE')) {
        i++;
        continue;
      }
      
      // Check if this line is a cue identifier (optional)
      let identifier: string | undefined;
      if (!line.includes(' --> ') && i + 1 < lines.length && lines[i + 1].includes(' --> ')) {
        identifier = line;
        i++;
      }
      
      // Parse timing line
      const currentLine = lines[i].trim();
      if (currentLine.includes(' --> ')) {
        const timingMatch = currentLine.match(/([\d:.,]+)\s+-->\s+([\d:.,]+)/);
        if (timingMatch) {
          const startTime = this.parseTimestamp(timingMatch[1]);
          const endTime = this.parseTimestamp(timingMatch[2]);
          
          // Collect text lines until empty line or next cue
          i++;
          const textLines: string[] = [];
          while (i < lines.length && lines[i].trim() !== '') {
            textLines.push(lines[i].trim());
            i++;
          }
          
          if (textLines.length > 0) {
            cues.push({
              startTime,
              endTime,
              text: textLines.join('\n'),
              identifier
            });
          }
        }
      } else {
        i++;
      }
    }
    
    return cues;
  }
  
  static build(cues: VTTCue[]): string {
    const lines = ['WEBVTT', ''];
    
    for (const cue of cues) {
      // Add identifier if present
      if (cue.identifier) {
        lines.push(cue.identifier);
      }
      
      // Add timing line
      const startTimestamp = this.formatTimestamp(cue.startTime);
      const endTimestamp = this.formatTimestamp(cue.endTime);
      lines.push(`${startTimestamp} --> ${endTimestamp}`);
      
      // Add text (can be multi-line)
      lines.push(cue.text);
      lines.push(''); // Empty line between cues
    }
    
    return lines.join('\n');
  }
  
  private static parseTimestamp(timestamp: string): number {
    // Clean up timestamp (handle both . and , as decimal separator)
    timestamp = timestamp.replace(',', '.');
    
    // Split by colon
    const parts = timestamp.split(':');
    
    let hours: string, minutes: string, seconds: string;
    
    if (parts.length === 3) { // HH:MM:SS.mmm
      [hours, minutes, seconds] = parts;
    } else if (parts.length === 2) { // MM:SS.mmm (legacy format)
      [hours, minutes, seconds] = ['0', parts[0], parts[1]];
    } else if (parts.length === 1) { // SS.mmm (very short format)
      [hours, minutes, seconds] = ['0', '0', parts[0]];
    } else {
      throw new Error(`Invalid timestamp format: ${timestamp}`);
    }
    
    // Parse seconds and decimal part
    const secParts = seconds.split('.');
    const wholeSeconds = parseInt(secParts[0]);
    const decimalPart = secParts[1] ? parseInt(secParts[1].padEnd(3, '0').slice(0, 3)) : 0;
    
    // Convert to total seconds
    return (
      parseInt(hours) * 3600 + 
      parseInt(minutes) * 60 + 
      wholeSeconds + 
      decimalPart / 1000.0
    );
  }
  
  private static formatTimestamp(seconds: number): string {
    const hours = Math.floor(seconds / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    const secs = seconds % 60;
    
    const wholeSeconds = Math.floor(secs);
    const milliseconds = Math.round((secs - wholeSeconds) * 1000);
    
    return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${wholeSeconds.toString().padStart(2, '0')}.${milliseconds.toString().padStart(3, '0')}`;
  }
}

export class VTTValidator {
  static validate(vttContent: string): { isValid: boolean; errors: string[] } {
    const errors: string[] = [];
    
    if (!vttContent.trim().startsWith('WEBVTT')) {
      errors.push('VTT must start with "WEBVTT"');
    }
    
    try {
      const cues = VTTParser.parse(vttContent);
      
      // Check timing consistency
      for (let i = 0; i < cues.length; i++) {
        const cue = cues[i];
        
        if (cue.startTime >= cue.endTime) {
          errors.push(`Cue ${i + 1}: Start time must be before end time`);
        }
        
        if (i > 0 && cue.startTime < cues[i - 1].endTime) {
          errors.push(`Cue ${i + 1}: Overlapping with previous cue`);
        }
        
        if (!cue.text.trim()) {
          errors.push(`Cue ${i + 1}: Empty text content`);
        }
      }
    } catch (error) {
      errors.push(`Parse error: ${error instanceof Error ? error.message : 'Unknown error'}`);
    }
    
    return {
      isValid: errors.length === 0,
      errors
    };
  }
}