"use client";

import { useEffect, useRef, useState } from "react";
import { Droplets, Flame, Lock, Moon, Snowflake, Sparkles, Sun, Swords, type LucideIcon } from "lucide-react";
import { ABILITY_BY_ID } from "@/game/data";
import type { CastView } from "@/game/Game";
import { SpellIcon } from "./SpellIcon";
import "./unitframe.css";

const SCHOOL_ICON: Record<string, LucideIcon> = { frost: Snowflake, fire: Flame, shadow: Moon, holy: Sun, arcane: Sparkles, physical: Swords };

/** A finished cast lingers for a moment: green flash when it landed, red "Interrupted" and a shake when it did not. */
interface Ghost {
  cast: CastView;
  ok: boolean;
  why: string;
}

function Icon({ cast }: { cast: CastView }) {
  const ab = ABILITY_BY_ID[cast.id];
  if (ab) return <SpellIcon id={ab.id} school={ab.school} size={26} />;
  const I = SCHOOL_ICON[cast.school] ?? Droplets;
  return <I className="h-[70%] w-[70%]" aria-hidden="true" />;
}

/**
 * The big cast bar. `tone` player = centred above the action bar, target = under the target frame.
 * Channels drain right to left; a pushback (time added) flashes the bar; locked (cannot be kicked) enemy casts go grey with a lock.
 */
export function BigCastBar({ cast, tone }: { cast: CastView | null; tone: "player" | "target" }) {
  const last = useRef<CastView | null>(null);
  const [ghost, setGhost] = useState<Ghost | null>(null);
  const [push, setPush] = useState(0);

  useEffect(() => {
    const prev = last.current;
    if (cast) {
      if (prev && prev.id === cast.id && cast.left > prev.left + 0.04) setPush((n) => n + 1);
      last.current = cast;
      setGhost(null);
      return;
    }
    if (!prev) return;
    last.current = null;
    const ok = prev.left <= Math.max(0.12, prev.total * 0.06);
    setGhost({ cast: prev, ok, why: ok ? "" : "Interrupted" });
    const t = window.setTimeout(() => setGhost(null), ok ? 380 : 1100);
    return () => window.clearTimeout(t);
  }, [cast]);

  const c = cast ?? ghost?.cast;
  if (!c) return null;
  const channel = c.kind === "channel";
  const raw = channel ? c.left / c.total : 1 - c.left / c.total;
  const pct = ghost ? (ghost.ok ? 100 : Math.max(0, Math.min(100, raw * 100))) : Math.max(0, Math.min(100, raw * 100));
  const locked = tone === "target" && !c.interruptible;
  const state = ghost ? (ghost.ok ? "ok" : "fail") : "";
  return (
    <div
      key={ghost ? "g" : "c"}
      className={`cb cb-${tone} cb-${c.school} ${channel ? "chan" : ""} ${locked ? "locked" : ""} ${state}`}
      role="progressbar"
      aria-label={`Casting ${c.name}`}
      aria-valuemin={0}
      aria-valuemax={100}
      aria-valuenow={Math.round(pct)}
    >
      <span className="cb-icon">
        <Icon cast={c} />
        {locked && <Lock className="cb-lock" aria-hidden="true" />}
      </span>
      <span className="cb-track">
        <i className={push ? "push" : ""} key={push} style={{ width: `${pct}%` }} />
        <em style={{ left: `${pct}%` }} />
        <span className="cb-name">{ghost && !ghost.ok ? ghost.why : c.name}</span>
        {!ghost && <span className="cb-time">{c.left.toFixed(1)} s</span>}
      </span>
    </div>
  );
}
