"use client";

import { useEffect, useRef, useState } from "react";
import { Check, ChevronUp, Minus, Pause, Play, Plus, RotateCcw, X } from "lucide-react";
import { cn } from "@/lib/utils";
import { useTimerStore, type TimerPreset } from "@/stores/timer-store";

const RING_COLOR = "#7c3aed";
const RING_SIZE  = 152;
const RING_CX    = RING_SIZE / 2;
const RING_R     = 58;
const RING_CIRC  = 2 * Math.PI * RING_R;

/* ── Audio helpers (component-local, bypasses store) ──────────────────────── */

type NoteSpec = { freq: number; vol: number; delay: number; dur: number };

function playNotes(audioCtxRef: React.MutableRefObject<AudioContext | null>, notes: NoteSpec[]) {
  if (typeof window === "undefined") return;
  try {
    if (!audioCtxRef.current) {
      const Ctor =
        (window as Window & typeof globalThis & { webkitAudioContext?: typeof AudioContext })
          .AudioContext ?? (window as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext;
      if (!Ctor) return;
      audioCtxRef.current = new Ctor();
    }
    const ctx = audioCtxRef.current;
    const doPlay = () => {
      for (const { freq, vol, delay, dur } of notes) {
        const osc  = ctx.createOscillator();
        const gain = ctx.createGain();
        osc.connect(gain);
        gain.connect(ctx.destination);
        osc.type = "sine";
        osc.frequency.value = freq;
        const t = ctx.currentTime + delay + 0.01;
        gain.gain.setValueAtTime(0.0001, t);
        gain.gain.linearRampToValueAtTime(vol, t + 0.015);
        gain.gain.exponentialRampToValueAtTime(0.0001, t + dur);
        osc.start(t);
        osc.stop(t + dur + 0.05);
      }
    };
    if (ctx.state === "suspended") {
      void ctx.resume().then(doPlay).catch(() => {});
    } else {
      doPlay();
    }
  } catch { /* AudioContext blocked */ }
}

const SOUND_START: NoteSpec[] = [
  { freq: 523.25, vol: 0.09, delay: 0,    dur: 0.28 }, // C5
  { freq: 783.99, vol: 0.10, delay: 0.14, dur: 0.38 }, // G5
];

const SOUND_COMPLETE: NoteSpec[] = [
  { freq: 783.99, vol: 0.13, delay: 0,    dur: 0.90 }, // G5
  { freq: 659.25, vol: 0.13, delay: 0.22, dur: 0.85 }, // E5
  { freq: 523.25, vol: 0.15, delay: 0.44, dur: 1.20 }, // C5 — sustained
];

/* ── Ring SVG ─────────────────────────────────────────────────────────────── */

function fmt(s: number) {
  return `${Math.floor(s / 60).toString().padStart(2, "0")}:${(s % 60).toString().padStart(2, "0")}`;
}

function Ring({ seconds, total }: { seconds: number; total: number }) {
  const offset = total > 0 ? RING_CIRC * (1 - seconds / total) : 0;
  return (
    <svg
      width={RING_SIZE} height={RING_SIZE}
      viewBox={`0 0 ${RING_SIZE} ${RING_SIZE}`}
      style={{ transform: "rotate(-90deg)", position: "absolute", inset: 0 }}
    >
      <circle cx={RING_CX} cy={RING_CX} r={RING_R} fill="none" stroke="currentColor"
        strokeWidth="4" className="text-border/60" />
      <circle
        cx={RING_CX} cy={RING_CX} r={RING_R} fill="none"
        stroke={RING_COLOR} strokeWidth="4" strokeLinecap="round"
        strokeDasharray={RING_CIRC} strokeDashoffset={offset}
        style={{ transition: "stroke-dashoffset 0.9s linear" }}
      />
    </svg>
  );
}

/* ── Add-preset inline form ───────────────────────────────────────────────── */

function AddPresetForm({ onAdd, onCancel }: {
  onAdd:   (name: string, minutes: number) => void;
  onCancel: () => void;
}) {
  const [name,    setName]    = useState("");
  const [minutes, setMinutes] = useState(25);

  const submit = () => { if (minutes >= 1) onAdd(name, minutes); };

  return (
    <div className="mt-2.5 flex items-center gap-1.5">
      <input
        type="text"
        placeholder="Name"
        value={name}
        onChange={(e) => setName(e.target.value)}
        onKeyDown={(e) => e.key === "Enter" && submit()}
        className="min-w-0 flex-1 rounded-xl border border-border bg-background px-2.5 py-1.5 text-xs text-foreground outline-none focus:border-violet-500/50 placeholder:text-muted-foreground/40"
        maxLength={18}
        autoFocus
      />
      <input
        type="number"
        min={1} max={99}
        value={minutes}
        onChange={(e) => setMinutes(Number(e.target.value))}
        onKeyDown={(e) => e.key === "Enter" && submit()}
        className="w-14 rounded-xl border border-border bg-background px-2 py-1.5 text-center text-xs font-bold text-foreground outline-none focus:border-violet-500/50"
      />
      <button onClick={submit}
        className="flex h-7 w-7 items-center justify-center rounded-lg bg-violet-500 text-white hover:bg-violet-400 transition-colors">
        <Check className="h-3.5 w-3.5" />
      </button>
      <button onClick={onCancel}
        className="flex h-7 w-7 items-center justify-center rounded-lg border border-border text-muted-foreground hover:text-foreground transition-colors">
        <X className="h-3.5 w-3.5" />
      </button>
    </div>
  );
}

/* ── Preset chip ──────────────────────────────────────────────────────────── */

function PresetChip({ preset, active, disabled, onLoad, onRemove }: {
  preset:   TimerPreset;
  active:   boolean;
  disabled: boolean;
  onLoad:   () => void;
  onRemove: () => void;
}) {
  const isDefault = preset.id.startsWith("default-");
  return (
    <div className="group flex items-center">
      <button
        onClick={onLoad}
        disabled={disabled}
        className={cn(
          "rounded-xl border px-3 py-1 text-[11px] font-semibold transition-all disabled:opacity-40 disabled:pointer-events-none",
          active
            ? "border-violet-500/40 bg-violet-500/10 text-violet-500 dark:text-violet-300"
            : "border-border bg-background text-muted-foreground hover:border-violet-500/25 hover:text-foreground",
        )}
      >
        {preset.name}
      </button>
      {!isDefault && !disabled && (
        <button
          onClick={onRemove}
          className="ml-0.5 flex h-3.5 w-3.5 items-center justify-center rounded-full text-muted-foreground/30 opacity-0 transition-all group-hover:opacity-100 hover:text-rose-400"
        >
          <X className="h-2.5 w-2.5" />
        </button>
      )}
    </div>
  );
}

/* ── Main widget ──────────────────────────────────────────────────────────── */

export function FloatingTimer() {
  const {
    presets, activePresetId, secondsLeft, secondsTotal, isRunning, isVisible, isMinimized,
    completionCount,
    hide, toggleMinimize, loadPreset, addPreset, removePreset, start, pause, restart, syncTick,
  } = useTimerStore();

  const intervalRef    = useRef<ReturnType<typeof setInterval> | null>(null);
  const audioCtxRef    = useRef<AudioContext | null>(null);
  const prevCompletion = useRef(completionCount);
  const [flash, setFlash]             = useState(false);
  const [showAddForm, setShowAddForm] = useState(false);

  /* Tick */
  useEffect(() => {
    if (isRunning) {
      intervalRef.current = setInterval(() => syncTick(Date.now()), 500);
    } else {
      if (intervalRef.current) clearInterval(intervalRef.current);
    }
    return () => { if (intervalRef.current) clearInterval(intervalRef.current); };
  }, [isRunning, syncTick]);

  /* Completion detection — play sound from component (not store) */
  useEffect(() => {
    if (completionCount > prevCompletion.current) {
      prevCompletion.current = completionCount;
      playNotes(audioCtxRef, SOUND_COMPLETE);
      // queueMicrotask: react-hooks/set-state-in-effect flags calling
      // setFlash directly in the effect body — defer by one tick.
      queueMicrotask(() => setFlash(true));
      const t = setTimeout(() => setFlash(false), 900);
      return () => clearTimeout(t);
    }
  }, [completionCount]);

  if (!isVisible) return null;

  const total   = secondsTotal;
  const pct     = total > 0 ? Math.round((secondsLeft / total) * 100) : 100;
  const isAtMax = secondsLeft >= secondsTotal && !isRunning;

  function handlePlayPause() {
    if (isRunning) {
      pause();
    } else {
      // Resume/unlock AudioContext during user gesture, then play start sound
      if (typeof window !== "undefined") {
        try {
          if (!audioCtxRef.current) {
            const Ctor =
              (window as Window & typeof globalThis & { webkitAudioContext?: typeof AudioContext })
                .AudioContext ?? (window as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext;
            if (Ctor) audioCtxRef.current = new Ctor();
          }
          if (audioCtxRef.current) {
            void audioCtxRef.current.resume().then(() => {
              playNotes(audioCtxRef, SOUND_START);
            }).catch(() => {});
          }
        } catch { /* ignore */ }
      }
      start();
    }
  }

  /* ── Minimized pill ── */
  if (isMinimized) {
    return (
      <div className="fixed bottom-24 right-6 z-[9999] flex items-center gap-2 md:bottom-6">
        <button
          onClick={handlePlayPause}
          className="flex items-center gap-2.5 rounded-2xl border border-border bg-card px-3.5 py-2.5 shadow-lg transition-all hover:border-border/80"
        >
          <div className={cn("h-2 w-2 shrink-0 rounded-full bg-violet-500", isRunning && "animate-pulse")} />
          <span className="font-mono text-[15px] font-bold tabular-nums text-violet-500 dark:text-violet-300">
            {fmt(secondsLeft)}
          </span>
          <span className="text-[10px] font-medium text-muted-foreground">Timer</span>
          {isRunning
            ? <Pause className="h-3.5 w-3.5 text-muted-foreground" />
            : <Play  className="h-3.5 w-3.5 text-muted-foreground" />}
        </button>
        <button
          onClick={toggleMinimize}
          className="flex h-9 w-9 items-center justify-center rounded-xl border border-border bg-card text-muted-foreground shadow-lg hover:text-foreground transition-colors"
        >
          <ChevronUp className="h-4 w-4" />
        </button>
      </div>
    );
  }

  /* ── Full widget ── */
  return (
    <div
      className={cn(
        "fixed bottom-24 right-6 z-[9999] w-[292px] overflow-hidden rounded-3xl border border-border bg-card shadow-xl transition-all duration-300 md:bottom-6",
        flash && "outline outline-2 outline-violet-500/50 outline-offset-1",
      )}
    >
      {/* Header */}
      <div className="flex items-center justify-between px-5 pt-4 pb-2">
        <div className="flex items-center gap-2">
          <div className={cn("h-2 w-2 shrink-0 rounded-full bg-violet-500", isRunning && "animate-pulse")} />
          <span className="text-[11px] font-bold uppercase tracking-[0.15em] text-violet-500 dark:text-violet-300">
            Timer
          </span>
        </div>
        <div className="flex items-center gap-0.5">
          <button onClick={toggleMinimize}
            className="flex h-7 w-7 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground transition-colors">
            <Minus className="h-3.5 w-3.5" />
          </button>
          <button onClick={hide}
            className="flex h-7 w-7 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-rose-500 transition-colors">
            <X className="h-3.5 w-3.5" />
          </button>
        </div>
      </div>

      {/* Ring */}
      <div className="flex items-center justify-center py-3">
        <div style={{ width: RING_SIZE, height: RING_SIZE, position: "relative" }}>
          <Ring seconds={secondsLeft} total={total} />
          <div style={{ position: "absolute", inset: 0 }}
            className="flex flex-col items-center justify-center">
            <span className="font-mono font-black tabular-nums leading-none text-violet-500 dark:text-violet-300"
              style={{ fontSize: "30px" }}>
              {fmt(secondsLeft)}
            </span>
            <span className="mt-1.5 text-[10px] font-medium text-muted-foreground">{pct}%</span>
          </div>
        </div>
      </div>

      {/* Controls */}
      <div className="flex items-center justify-center gap-3 px-5 pb-4">
        <button
          onClick={restart}
          disabled={isAtMax}
          className="flex h-10 w-10 items-center justify-center rounded-xl border border-border bg-background text-muted-foreground hover:border-rose-500/30 hover:text-rose-500 hover:bg-rose-500/[0.06] disabled:opacity-25 disabled:pointer-events-none transition-all"
          title="Neustart"
        >
          <RotateCcw className="h-4 w-4" />
        </button>

        <button
          onClick={handlePlayPause}
          className="flex h-14 w-14 items-center justify-center rounded-2xl border text-white shadow-lg transition-all"
          style={{
            background:  isRunning ? "rgba(124,58,237,0.15)" : "#7c3aedcc",
            borderColor: isRunning ? "rgba(124,58,237,0.25)" : "#7c3aed80",
          }}
        >
          {isRunning
            ? <Pause className="h-5 w-5 text-violet-300" />
            : <Play  className="h-5 w-5 translate-x-0.5" />}
        </button>

        <div className="h-10 w-10" />
      </div>

      {/* Progress bar */}
      <div className="mx-5 mb-4 h-[3px] overflow-hidden rounded-full bg-muted">
        <div
          className="h-full rounded-full transition-all duration-1000"
          style={{ width: `${100 - pct}%`, background: RING_COLOR, opacity: 0.7 }}
        />
      </div>

      {/* Saved presets */}
      <div className="border-t border-border px-4 pb-4 pt-3">
        <p className="mb-2.5 text-[10px] font-bold uppercase tracking-[0.15em] text-muted-foreground">
          Gespeicherte Timer
        </p>
        <div className="flex flex-wrap gap-1.5">
          {presets.map((preset) => (
            <PresetChip
              key={preset.id}
              preset={preset}
              active={activePresetId === preset.id}
              disabled={isRunning}
              onLoad={() => loadPreset(preset.id)}
              onRemove={() => removePreset(preset.id)}
            />
          ))}
          {!showAddForm && (
            <button
              onClick={() => setShowAddForm(true)}
              disabled={isRunning}
              className="flex h-[28px] w-[28px] items-center justify-center rounded-xl border border-dashed border-border text-muted-foreground hover:border-violet-500/40 hover:text-violet-500 disabled:opacity-25 disabled:pointer-events-none transition-all"
              title="Timer hinzufügen"
            >
              <Plus className="h-3 w-3" />
            </button>
          )}
        </div>

        {showAddForm && (
          <AddPresetForm
            onAdd={(name, minutes) => { addPreset(name, minutes); setShowAddForm(false); }}
            onCancel={() => setShowAddForm(false)}
          />
        )}
      </div>
    </div>
  );
}
