"use client";

import { useState, useEffect, useRef, useCallback } from "react";
import { useRouter } from "next/navigation";
import { X, ChevronLeft, ChevronRight, List, Mic, MicOff, Play, Square, HelpCircle, Clock } from "lucide-react";
import { cn } from "@/lib/utils";
import { useTranslations } from "next-intl";
import { useLocale } from "@/lib/i18n/provider";
import { formatIngredientQuantity, type UnitPref } from "@/lib/unit-conversion";
import { useWakeLock } from "@/lib/hooks/use-wake-lock";

type Step = { id: string; instruction: string; timerSeconds: number | null; appliesTo?: string[] };
type Ingredient = { rawName: string; quantity: string | null; unit: string | null };

type TimerState = {
  remaining: number;
  running: boolean;
  initial: number;
};

const VOICE_COMMANDS: Record<string, Record<string, string[]>> = {
  en: {
    next: ["next", "continue"],
    prev: ["previous", "back", "go back"],
    timer: ["timer", "start"],
    stop: ["stop", "pause"],
    reset: ["reset"],
    repeat: ["repeat", "again"],
  },
  fr: {
    next: ["suivant", "continuer", "prochain"],
    prev: ["précédent", "retour", "reculer"],
    timer: ["minuteur", "démarrer", "lancer"],
    stop: ["arrêter", "pause", "stop"],
    reset: ["réinitialiser", "recommencer"],
    repeat: ["répéter", "encore"],
  },
};

const SPEECH_LANG: Record<string, string> = {
  en: "en-US",
  fr: "fr-FR",
};

function beep(freq = 880, duration = 0.15, vol = 0.3) {
  try {
    const ctx = new AudioContext();
    const osc = ctx.createOscillator();
    const gain = ctx.createGain();
    osc.connect(gain);
    gain.connect(ctx.destination);
    osc.frequency.value = freq;
    gain.gain.setValueAtTime(vol, ctx.currentTime);
    gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + duration);
    osc.start(ctx.currentTime);
    osc.stop(ctx.currentTime + duration);
  } catch {}
}

function formatTime(s: number) {
  const m = Math.floor(s / 60);
  const sec = s % 60;
  return m > 0 ? `${m}:${sec.toString().padStart(2, "0")}` : `${sec}s`;
}

export function CookingMode({
  recipeId,
  recipeTitle,
  steps,
  ingredients,
  unitPref = "metric",
}: {
  recipeId: string;
  recipeTitle: string;
  steps: Step[];
  ingredients: Ingredient[];
  unitPref?: UnitPref;
}) {
  const router = useRouter();
  const t = useTranslations("cookingMode");
  const { locale } = useLocale();
  const [current, setCurrent] = useState(0);
  const [showIngredients, setShowIngredients] = useState(false);
  const [voiceActive, setVoiceActive] = useState(false);
  const [voiceStatus, setVoiceStatus] = useState("");
  const [showHelp, setShowHelp] = useState(false);

  // Parallel timers: keyed by step index
  const [timers, setTimers] = useState<Map<number, TimerState>>(() => new Map());

  const recognitionRef = useRef<InstanceType<typeof window.SpeechRecognition> | null>(null);

  const step = steps[current]!;
  const isLast = current === steps.length - 1;
  const isFirst = current === 0;

  const currentTimer = timers.get(current);
  const otherRunningTimers = [...timers.entries()].filter(([idx, t]) => idx !== current && t.running);

  useWakeLock();

  // Master tick: decrement all running timers once per second
  useEffect(() => {
    const id = setInterval(() => {
      setTimers((prev) => {
        let changed = false;
        const next = new Map(prev);
        for (const [stepIdx, timer] of next) {
          if (!timer.running) continue;
          changed = true;
          const rem = timer.remaining - 1;
          if (rem <= 3 && rem > 0) beep(660 + (3 - rem) * 110, 0.1);
          if (rem <= 0) {
            next.set(stepIdx, { ...timer, remaining: 0, running: false });
            beep(880, 0.3);
            setTimeout(() => beep(1100, 0.3), 350);
            setTimeout(() => beep(1320, 0.5), 700);
          } else {
            next.set(stepIdx, { ...timer, remaining: rem });
          }
        }
        return changed ? next : prev;
      });
    }, 1000);
    return () => clearInterval(id);
  }, []);

  function startTimer(stepIdx = current) {
    const s = steps[stepIdx];
    if (!s?.timerSeconds) return;
    setTimers((prev) => {
      const existing = prev.get(stepIdx);
      const remaining = existing && existing.remaining > 0 ? existing.remaining : s.timerSeconds!;
      if (existing?.running) return prev;
      const next = new Map(prev);
      next.set(stepIdx, { remaining, running: true, initial: s.timerSeconds! });
      return next;
    });
  }

  function stopTimer(stepIdx = current) {
    setTimers((prev) => {
      const t = prev.get(stepIdx);
      if (!t || !t.running) return prev;
      const next = new Map(prev);
      next.set(stepIdx, { ...t, running: false });
      return next;
    });
  }

  function resetTimer(stepIdx = current) {
    setTimers((prev) => {
      const s = steps[stepIdx];
      if (!s?.timerSeconds) return prev;
      const next = new Map(prev);
      next.delete(stepIdx);
      return next;
    });
  }

  function dismissTimer(stepIdx: number) {
    setTimers((prev) => {
      const next = new Map(prev);
      next.delete(stepIdx);
      return next;
    });
  }

  const goNext = useCallback(() => {
    if (!isLast) setCurrent((c) => c + 1);
  }, [isLast]);

  const goPrev = useCallback(() => {
    if (!isFirst) setCurrent((c) => c - 1);
  }, [isFirst]);

  // Keyboard navigation
  useEffect(() => {
    function onKey(e: KeyboardEvent) {
      if (e.target !== document.body) return;
      if (e.key === "?") { setShowHelp((v) => !v); return; }
      if (e.key === "Escape") { if (showHelp) { setShowHelp(false); return; } router.push(`/recipes/${recipeId}`); }
      if (showHelp) return;
      if (e.key === "ArrowRight" || e.key === " ") { e.preventDefault(); goNext(); }
      if (e.key === "ArrowLeft") goPrev();
      if (e.key === "t" || e.key === "T") startTimer();
    }
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [goNext, goPrev, recipeId, showHelp]);

  // Voice recognition
  function toggleVoice() {
    const SR = window.SpeechRecognition ?? window.webkitSpeechRecognition;
    if (!SR) { setVoiceStatus(t("voiceNotSupported")); return; }

    if (voiceActive) {
      recognitionRef.current?.stop();
      recognitionRef.current = null;
      setVoiceActive(false);
      setVoiceStatus("");
      return;
    }

    const rec = new SR();
    rec.continuous = true;
    rec.interimResults = false;
    rec.lang = SPEECH_LANG[locale] ?? "en-US";

    rec.onresult = (e: SpeechRecognitionEvent) => {
      const transcript = e.results[e.results.length - 1]![0]!.transcript.toLowerCase().trim();
      setVoiceStatus(`"${transcript}"`);
      const cmds = VOICE_COMMANDS[locale] ?? VOICE_COMMANDS.en!;
      if (cmds.next!.some(k => transcript.includes(k))) goNext();
      else if (cmds.prev!.some(k => transcript.includes(k))) goPrev();
      else if (cmds.timer!.some(k => transcript.includes(k))) startTimer();
      else if (cmds.stop!.some(k => transcript.includes(k))) stopTimer();
      else if (cmds.reset!.some(k => transcript.includes(k))) resetTimer();
      else if (cmds.repeat!.some(k => transcript.includes(k))) setVoiceStatus(t("stepRepeatPrefix", { n: current + 1 }) + step.instruction.slice(0, 60) + "…");
      setTimeout(() => setVoiceStatus(""), 3000);
    };
    rec.onerror = () => setVoiceStatus(t("voiceError"));
    rec.onend = () => { if (voiceActive) rec.start(); };

    rec.start();
    recognitionRef.current = rec;
    setVoiceActive(true);
  }

  return (
    <div className="fixed inset-0 z-50 bg-background flex flex-col select-none">
      {/* Top bar */}
      <div className="flex items-center justify-between px-6 py-4 border-b shrink-0">
        <div className="flex items-center gap-3">
          <button
            onClick={() => router.push(`/recipes/${recipeId}`)}
            className="rounded-full p-2 hover:bg-muted transition-colors"
            title="Exit (Esc)"
          >
            <X className="h-5 w-5" />
          </button>
          <div>
            <p className="text-xs text-muted-foreground uppercase tracking-wider">{t("cooking")}</p>
            <h1 className="font-semibold text-sm leading-tight">{recipeTitle}</h1>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={toggleVoice}
            className={cn("rounded-full p-2 transition-colors", voiceActive ? "bg-primary text-primary-foreground" : "hover:bg-muted")}
            title={voiceActive ? t("stopVoice") : t("enableVoice")}
          >
            {voiceActive ? <Mic className="h-5 w-5" /> : <MicOff className="h-5 w-5" />}
          </button>
          <button
            onClick={() => setShowIngredients((v) => !v)}
            className={cn("rounded-full p-2 transition-colors", showIngredients ? "bg-primary text-primary-foreground" : "hover:bg-muted")}
            title={t("toggleIngredients")}
          >
            <List className="h-5 w-5" />
          </button>
          <button
            onClick={() => setShowHelp((v) => !v)}
            className={cn("rounded-full p-2 transition-colors", showHelp ? "bg-primary text-primary-foreground" : "hover:bg-muted")}
            title="Shortcuts & voice commands (?)"
          >
            <HelpCircle className="h-5 w-5" />
          </button>
        </div>
      </div>

      {/* Progress bar */}
      <div className="h-1 bg-muted shrink-0">
        <div
          className="h-full bg-primary transition-all duration-300"
          style={{ width: `${((current + 1) / steps.length) * 100}%` }}
        />
      </div>

      {/* Main area */}
      <div className="flex flex-col sm:flex-row flex-1 overflow-hidden">
        {/* Step content */}
        <div className="flex-1 flex flex-col items-center justify-center px-4 sm:px-8 py-8 sm:py-12 gap-8 overflow-y-auto">
          {/* Step number */}
          <div className="text-sm font-medium text-muted-foreground">
            {t("stepOf", { current: current + 1, total: steps.length })}
          </div>

          {/* Batch-cook dish tag */}
          {step.appliesTo !== undefined && (
            <span className="text-xs font-semibold uppercase tracking-wide rounded-full bg-muted px-3 py-1">
              {step.appliesTo.length === 0 ? t("batchPrepLabel") : step.appliesTo.join(" + ")}
            </span>
          )}

          {/* Instruction */}
          <p className="text-2xl sm:text-3xl leading-relaxed text-center font-medium max-w-2xl">
            {step.instruction}
          </p>

          {/* Timer for current step */}
          {!!step.timerSeconds && (
            <div className="flex flex-col items-center gap-3">
              <div className={cn(
                "text-5xl font-mono font-bold tabular-nums",
                currentTimer?.running && currentTimer.remaining <= 10 && "text-destructive"
              )}>
                {formatTime(currentTimer?.remaining ?? step.timerSeconds)}
              </div>
              <div className="flex gap-2">
                {!currentTimer?.running ? (
                  <button
                    onClick={() => startTimer()}
                    disabled={currentTimer?.remaining === 0}
                    className="flex items-center gap-2 rounded-full px-5 py-2.5 bg-primary text-primary-foreground text-sm font-medium hover:bg-primary/90 disabled:opacity-40 transition-colors"
                    title="Start timer (T)"
                  >
                    <Play className="h-4 w-4" />
                    {currentTimer?.remaining === 0 ? t("timerDone") : t("startTimer")}
                  </button>
                ) : (
                  <button
                    onClick={() => stopTimer()}
                    className="flex items-center gap-2 rounded-full px-5 py-2.5 bg-muted text-sm font-medium hover:bg-muted/80 transition-colors"
                  >
                    <Square className="h-4 w-4" />
                    {t("pause")}
                  </button>
                )}
                {currentTimer && currentTimer.remaining !== step.timerSeconds && (
                  <button onClick={() => resetTimer()} className="rounded-full px-4 py-2.5 text-sm text-muted-foreground hover:bg-muted transition-colors">
                    {t("reset")}
                  </button>
                )}
              </div>
            </div>
          )}

          {/* Voice status */}
          {voiceStatus && (
            <p className="text-sm text-muted-foreground italic">{voiceStatus}</p>
          )}
        </div>

        {/* Ingredients drawer — stacks above the step on mobile instead of squeezing it horizontally */}
        {showIngredients && (
          <aside className="order-first sm:order-none w-full sm:w-72 max-h-40 sm:max-h-none border-b sm:border-b-0 sm:border-l bg-muted/20 overflow-y-auto py-4 sm:py-6 px-5 shrink-0">
            <h2 className="font-semibold mb-4 text-sm uppercase tracking-wider text-muted-foreground">{t("ingredients")}</h2>
            <ul className="space-y-2">
              {ingredients.map((ing, i) => (
                <li key={i} className="text-sm flex gap-2">
                  <span className="text-muted-foreground shrink-0 w-16 text-right">
                    {formatIngredientQuantity(ing.quantity, ing.unit, unitPref)}
                  </span>
                  <span>{ing.rawName}</span>
                </li>
              ))}
            </ul>
          </aside>
        )}
      </div>

      {/* Parallel timers dock */}
      {otherRunningTimers.length > 0 && (
        <div className="shrink-0 border-t bg-muted/30 px-4 py-3">
          <div className="flex items-center gap-2 overflow-x-auto">
            <Clock className="h-4 w-4 text-muted-foreground shrink-0" />
            <div className="flex gap-3">
              {otherRunningTimers.map(([stepIdx, timer]) => (
                <button
                  key={stepIdx}
                  onClick={() => setCurrent(stepIdx)}
                  className="flex items-center gap-2 rounded-full bg-background border px-3 py-1.5 text-xs font-mono hover:bg-muted transition-colors shrink-0"
                  title={`Step ${stepIdx + 1}: ${steps[stepIdx]?.instruction.slice(0, 50)}`}
                >
                  <span className={cn("font-bold tabular-nums", timer.remaining <= 10 && "text-destructive")}>
                    {formatTime(timer.remaining)}
                  </span>
                  <span className="text-muted-foreground">Step {stepIdx + 1}</span>
                  <button
                    onClick={(e) => { e.stopPropagation(); dismissTimer(stepIdx); }}
                    className="ml-1 text-muted-foreground hover:text-foreground"
                  >
                    <X className="h-3 w-3" />
                  </button>
                </button>
              ))}
            </div>
          </div>
        </div>
      )}

      {/* Help overlay */}
      {showHelp && (
        <div
          className="absolute inset-0 z-10 bg-background/80 backdrop-blur-sm flex items-center justify-center p-6"
          onClick={() => setShowHelp(false)}
        >
          <div
            className="bg-popover border rounded-2xl shadow-xl w-full max-w-lg max-h-[85vh] overflow-y-auto p-6 space-y-6"
            onClick={(e) => e.stopPropagation()}
          >
            <div className="flex items-center justify-between">
              <h2 className="font-semibold text-lg">{t("shortcutsTitle")}</h2>
              <button onClick={() => setShowHelp(false)} className="rounded-full p-1.5 hover:bg-muted transition-colors">
                <X className="h-4 w-4" />
              </button>
            </div>

            <div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
              <div className="space-y-3">
                <p className="text-xs font-medium uppercase tracking-wider text-muted-foreground">{t("keyboardSection")}</p>
                <div className="space-y-2 text-sm">
                  {[
                    ["→  /  Space", t("shortcuts.nextStep")],
                    ["←", t("shortcuts.prevStep")],
                    ["T", t("shortcuts.startTimer")],
                    ["?", t("shortcuts.toggleHelp")],
                    ["Esc", t("shortcuts.exitMode")],
                  ].map(([key, label]) => (
                    <div key={key} className="flex flex-wrap items-center justify-between gap-1.5">
                      <kbd className="font-mono text-xs bg-muted px-2 py-0.5 rounded border border-border">{key}</kbd>
                      <span className="text-muted-foreground text-right">{label}</span>
                    </div>
                  ))}
                </div>
              </div>

              <div className="space-y-3">
                <p className="text-xs font-medium uppercase tracking-wider text-muted-foreground">{t("voiceSection")}</p>
                <div className="space-y-2 text-sm">
                  {[
                    [t("voiceLabels.nextCmd"), t("voiceLabels.nextLabel")],
                    [t("voiceLabels.prevCmd"), t("voiceLabels.prevLabel")],
                    [t("voiceLabels.timerCmd"), t("voiceLabels.timerLabel")],
                    [t("voiceLabels.stopCmd"), t("voiceLabels.stopLabel")],
                    [t("voiceLabels.resetCmd"), t("voiceLabels.resetLabel")],
                    [t("voiceLabels.repeatCmd"), t("voiceLabels.repeatLabel")],
                  ].map(([cmd, label]) => (
                    <div key={cmd} className="flex flex-wrap items-center justify-between gap-1.5">
                      <span className="font-mono text-xs bg-muted px-2 py-0.5 rounded border border-border whitespace-nowrap">&ldquo;{cmd}&rdquo;</span>
                      <span className="text-muted-foreground text-right">{label}</span>
                    </div>
                  ))}
                </div>
                {!voiceActive && (
                  <p className="text-xs text-muted-foreground italic">{t("enableMicFirst")}</p>
                )}
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Bottom navigation */}
      <div className="flex items-center justify-between px-8 py-6 border-t shrink-0">
        <button
          onClick={goPrev}
          disabled={isFirst}
          className="flex items-center gap-2 rounded-full px-5 py-3 border text-sm font-medium hover:bg-muted disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
          title="Previous step (←)"
        >
          <ChevronLeft className="h-4 w-4" />
          {t("previous")}
        </button>

        {/* Step dots */}
        <div className="hidden sm:flex gap-1.5">
          {steps.map((_, i) => (
            <button
              key={i}
              onClick={() => setCurrent(i)}
              className={cn(
                "rounded-full transition-all",
                i === current ? "w-6 h-2.5 bg-primary" : "w-2.5 h-2.5 bg-muted-foreground/30 hover:bg-muted-foreground/60"
              )}
            />
          ))}
        </div>

        {isLast ? (
          <button
            onClick={() => router.push(`/recipes/${recipeId}`)}
            className="flex items-center gap-2 rounded-full px-5 py-3 bg-primary text-primary-foreground text-sm font-medium hover:bg-primary/90 transition-colors"
          >
            {t("finish")}
          </button>
        ) : (
          <button
            onClick={goNext}
            className="flex items-center gap-2 rounded-full px-5 py-3 bg-primary text-primary-foreground text-sm font-medium hover:bg-primary/90 transition-colors"
            title="Next step (→ or Space)"
          >
            {t("next")}
            <ChevronRight className="h-4 w-4" />
          </button>
        )}
      </div>
    </div>
  );
}
