// Detect silence segments across all audio tracks on the timeline.
// Translates source-time silence segments into timeline coordinates,
// intersecting with each clip's timeline range.

import { detectSilence as detectSilenceInBuffer } from '@/lib/audio';
import { useEditor } from '@/store/editor';
import type { ExportSettings, MediaAsset, Track } from '@/types';

interface Segment {
  id: string;
  trackId: string;
  start: number;
  end: number;
}

export async function detectAllSilences(opts: {
  tracks: Track[];
  clips: ReturnType<typeof useEditor.getState>['clips'];
  assets: MediaAsset[];
  settings: ExportSettings;
  setToast: (t: { message: string; level: 'info' | 'error' | 'success' }) => void;
}): Promise<Segment[]> {
  const { tracks, clips, assets, settings, setToast } = opts;
  const audioTracks = tracks.filter((t) => t.kind === 'audio');
  const audioClips = clips.filter((c) => audioTracks.some((t) => t.id === c.trackId));
  if (audioClips.length === 0) {
    setToast({ message: 'ไม่มีคลิปเสียงบนไทม์ไลน์', level: 'error' });
    return [];
  }

  const segs: Segment[] = [];
  for (const track of audioTracks) {
    const clipsOnTrack = clips.filter((c) => c.trackId === track.id);
    for (const c of clipsOnTrack) {
      const asset = assets.find((a) => a.id === c.assetId);
      if (!asset) continue;
      // For video assets without a decoded audio buffer, fall back to
      // extracting the built-in audio via FFmpeg.wasm so silence detection
      // works the same as it does for a separate audio file.
      let audioBuffer = asset.audioBuffer;
      if (!audioBuffer && asset.kind === 'video') {
        try {
          const { extractAudioFromVideo } = await import('@/lib/ffmpeg');
          const resp = await fetch(asset.url);
          const blob = await resp.blob();
          const file = new File([blob], asset.name, { type: blob.type || 'video/mp4' });
          const extracted = await extractAudioFromVideo(file);
          audioBuffer = extracted.audioBuffer;
        } catch {
          continue;
        }
      }
      if (!audioBuffer) continue;
      const trackSegs = detectSilenceInBuffer(audioBuffer, track.id, {
        thresholdDb: settings.silenceThresholdDb,
        minDurationMs: settings.silenceMinDurationMs,
      });
      const clipStart = c.start;
      const clipEnd = c.start + c.duration;
      const aDur = audioBuffer.duration;
      for (const seg of trackSegs) {
        const sStart = seg.start + c.sourceIn;
        const sEnd = seg.end + c.sourceIn;
        const cStart = Math.max(sStart, 0);
        const cEnd = Math.min(sEnd, aDur);
        if (cEnd - cStart < settings.silenceMinDurationMs / 1000) continue;
        const tlStart = clipStart + (cStart - c.sourceIn);
        const tlEnd = clipStart + (cEnd - c.sourceIn);
        if (tlEnd - tlStart < settings.silenceMinDurationMs / 1000) continue;
        const finalStart = Math.max(tlStart, clipStart);
        const finalEnd = Math.min(tlEnd, clipEnd);
        if (finalEnd - finalStart > 0.01) {
          segs.push({
            id: `${track.id}-${Math.random().toString(36).slice(2, 8)}-${segs.length}`,
            trackId: track.id,
            start: finalStart,
            end: finalEnd,
          });
        }
      }
    }
  }
  if (segs.length === 0) {
    setToast({ message: 'ไม่พบช่วงเงียบตามค่าที่ตั้งไว้', level: 'info' });
  } else {
    setToast({ message: `พบช่วงเงียบ ${segs.length} ช่วง`, level: 'success' });
  }
  return segs;
}