import { useMemo, useRef } from "react";
import type { Transcript } from "@/api/types";

type Sentence = Transcript["paragraphs"][number]["sentences"][number];
type Word = Transcript["words"][number];

const CHUNK_SIZE = 9;

/** Split an array of words into fixed-size display chunks */
function chunkWords(words: Word[]): Word[][] {
  const chunks: Word[][] = [];
  for (let i = 0; i < words.length; i += CHUNK_SIZE) {
    chunks.push(words.slice(i, i + CHUNK_SIZE));
  }
  return chunks;
}

interface TranscriptOverlayProps {
  transcript: Transcript;
  activeSentence: Sentence | null;
  activeWordIndex: number | null;
  /** Center captions vertically (e.g. for audio-only playback) */
  centered?: boolean;
}

export function TranscriptOverlay({
  transcript,
  activeSentence,
  activeWordIndex,
  centered = false,
}: TranscriptOverlayProps) {
  const sentenceWords = useMemo(() => {
    if (!activeSentence) return [];
    return transcript.words.filter(
      (w) => w.start >= activeSentence.start && w.end <= activeSentence.end,
    );
  }, [transcript.words, activeSentence]);

  const chunks = useMemo(() => chunkWords(sentenceWords), [sentenceWords]);

  const activeWord =
    activeWordIndex !== null ? transcript.words[activeWordIndex] : null;

  // Remember the last spoken word so highlights hold during pauses
  const lastSpokenWordRef = useRef<Word | null>(null);
  if (activeWord) {
    lastSpokenWordRef.current = activeWord;
  }
  const highlightWord = activeWord ?? lastSpokenWordRef.current;

  const lastChunkRef = useRef<Word[] | null>(null);

  // Find which chunk contains the active word, holding the last one during pauses
  const activeChunk = useMemo(() => {
    if (activeWord) {
      for (const chunk of chunks) {
        if (chunk.some((w) => w.start === activeWord.start && w.end === activeWord.end)) {
          lastChunkRef.current = chunk;
          return chunk;
        }
      }
    }
    // No active word (speaker pausing) — hold the last chunk
    if (lastChunkRef.current && chunks.some((c) => c === lastChunkRef.current)) {
      return lastChunkRef.current;
    }
    // Sentence changed, last chunk no longer valid — use first chunk
    const fallback = chunks[0] ?? null;
    lastChunkRef.current = fallback;
    return fallback;
  }, [chunks, activeWord]);

  if (!activeSentence || !activeChunk || activeChunk.length === 0) return null;

  return (
    <div className={centered
      ? "absolute inset-0 flex items-center justify-center px-6"
      : "absolute bottom-15 left-0 right-0 flex justify-center px-6"
    }>
      <p className="rounded-lg px-5 py-3 text-2xl text-center max-w-lg">
        {activeChunk.map((word, i) => {
          const isSpoken =
            highlightWord !== null && word.start <= highlightWord.end;

          return (
            <span
              key={`${word.start}-${i}`}
              className={
                isSpoken
                  ? "text-white font-medium transition-colors duration-150"
                  : "text-white/40 transition-colors duration-150"
              }
            >
              {i > 0 ? " " : ""}
              {word.word}
            </span>
          );
        })}
      </p>
    </div>
  );
}
