"use client";

import { useId } from "react";
import type { School } from "@/game/data";
import "./spellui.css";

/** School colours: frame, glow and the icon backdrop. */
export const SCHOOL_COLOUR: Record<School, { main: string; dark: string; glow: string }> = {
  frost: { main: "#5fe0ff", dark: "#0d2f5c", glow: "#9bf0ff" },
  arcane: { main: "#c58bff", dark: "#34145c", glow: "#e6c4ff" },
  fire: { main: "#ff8a2a", dark: "#5c1a0a", glow: "#ffd08a" },
  shadow: { main: "#9b4dff", dark: "#1d0c3d", glow: "#cfa6ff" },
  holy: { main: "#f2c14e", dark: "#4a3408", glow: "#fff0b3" },
  physical: { main: "#d6dbe8", dark: "#2b2f3d", glow: "#ffffff" },
};

const SPIKES = Array.from({ length: 10 }, (_, i) => (i * 36 * Math.PI) / 180);

/** The drawn art for one ability, 64 x 64 viewBox. Every shape shows what the spell does. */
function Art({ id, uid, school }: { id: string; uid: string; school: School }) {
  const c = SCHOOL_COLOUR[school];
  const g = (n: string) => `url(#${uid}-${n})`;
  const body = (() => {
    switch (id) {
      case "frostbolt":
        return (
          <g>
            {/* comet trail */}
            <path d="M6 54 L40 24 L46 30 Z" fill={g("trail")} />
            <path d="M12 46 L36 28 L40 32 Z" fill="#fff" opacity="0.55" />
            {/* crystal head */}
            <path d="M40 14 L54 22 L50 40 L36 46 L30 32 Z" fill={g("ice")} stroke="#e8fbff" strokeWidth="1.5" strokeLinejoin="round" />
            <path d="M40 14 L50 40 M40 14 L30 32 M54 22 L36 46" stroke="#fff" strokeWidth="1" opacity="0.7" fill="none" />
            <circle cx="41" cy="28" r="5" fill="#fff" opacity="0.85" />
            {/* snow sparks */}
            <circle cx="14" cy="38" r="1.8" fill="#fff" />
            <circle cx="22" cy="52" r="1.4" fill="#d9f7ff" />
            <circle cx="8" cy="46" r="1.2" fill="#fff" />
            <path d="M54 10 v6 M51 13 h6" stroke="#fff" strokeWidth="1.5" strokeLinecap="round" />
          </g>
        );
      case "icelance":
        return (
          <g>
            <path d="M6 58 L40 24" stroke="#bfefff" strokeWidth="5" strokeLinecap="round" />
            <path d="M6 58 L40 24" stroke="#fff" strokeWidth="1.5" strokeLinecap="round" opacity="0.9" />
            {/* faceted spearhead */}
            <path d="M36 28 L52 8 L56 12 L58 26 L40 34 Z" fill={g("ice")} stroke="#e8fbff" strokeWidth="1.5" strokeLinejoin="round" />
            <path d="M52 8 L40 34 M52 8 L58 26" stroke="#fff" strokeWidth="1" opacity="0.8" fill="none" />
            <path d="M30 34 L36 40 M24 40 L30 46" stroke="#5fe0ff" strokeWidth="3" strokeLinecap="round" />
            <circle cx="12" cy="30" r="1.6" fill="#fff" />
            <circle cx="22" cy="18" r="1.2" fill="#d9f7ff" />
            <circle cx="50" cy="52" r="1.5" fill="#fff" />
          </g>
        );
      case "nova":
        return (
          <g>
            <circle cx="32" cy="32" r="17" fill={g("glow")} />
            <circle cx="32" cy="32" r="13" fill="none" stroke="#e8fbff" strokeWidth="3" />
            {SPIKES.map((a, i) => {
              const r0 = 14, r1 = i % 2 ? 26 : 29, w = 0.16;
              const p = (r: number, da: number) => `${(32 + Math.sin(a + da) * r).toFixed(1)} ${(32 - Math.cos(a + da) * r).toFixed(1)}`;
              return <path key={i} d={`M${p(r0, -w)} L${p(r1, 0)} L${p(r0, w)} Z`} fill={g("ice")} stroke="#e8fbff" strokeWidth="1" strokeLinejoin="round" />;
            })}
            <circle cx="32" cy="32" r="5" fill="#fff" opacity="0.9" />
          </g>
        );
      case "polymorph":
        return (
          <g>
            {/* legs */}
            <path d="M24 44 v9 M30 46 v8 M38 46 v8 M44 44 v9" stroke="#2a2438" strokeWidth="3.4" strokeLinecap="round" />
            {/* wool */}
            {[[22, 38, 8], [31, 33, 9], [41, 36, 9], [47, 42, 6], [28, 44, 7], [38, 45, 7], [20, 45, 5]].map(([x, y, r], i) => (
              <circle key={i} cx={x} cy={y} r={r} fill="#fbf7ff" stroke="#d9cdf0" strokeWidth="1" />
            ))}
            {/* head */}
            <ellipse cx="15" cy="34" rx="6.5" ry="7.5" fill="#2a2438" />
            <circle cx="13.5" cy="32.5" r="1.6" fill="#fff" />
            <circle cx="13.5" cy="32.5" r="0.7" fill="#1a1428" />
            <path d="M9 28 q-5 -2 -3 4 M20 28 q4 -3 4 3" stroke="#2a2438" strokeWidth="3" strokeLinecap="round" fill="none" />
            {/* arcane sparkle */}
            <path d="M48 12 l2 5 5 2 -5 2 -2 5 -2 -5 -5 -2 5 -2 Z" fill="#f4dcff" />
            <path d="M16 12 l1.2 3 3 1.2 -3 1.2 -1.2 3 -1.2 -3 -3 -1.2 3 -1.2 Z" fill="#e6c4ff" />
          </g>
        );
      case "counterspell":
        return (
          <g>
            {/* rune ring, broken */}
            <path d="M32 8 A24 24 0 0 1 56 32" stroke="#e6c4ff" strokeWidth="3" fill="none" strokeLinecap="round" />
            <path d="M52 44 A24 24 0 0 1 20 54" stroke="#e6c4ff" strokeWidth="3" fill="none" strokeLinecap="round" />
            <path d="M12 46 A24 24 0 0 1 14 16" stroke="#c58bff" strokeWidth="3" fill="none" strokeLinecap="round" opacity="0.8" />
            <path d="M22 12 l3 4 M44 14 l-3 5 M10 30 h5" stroke="#f4dcff" strokeWidth="2" strokeLinecap="round" />
            {/* shards flying off */}
            <path d="M52 16 l6 -4 -2 7 Z" fill="#f4dcff" />
            <path d="M54 50 l5 2 -5 4 Z" fill="#c58bff" />
            {/* open palm */}
            <path d="M24 52 L22 38 Q21 34 24 34 L25 38 L25 24 Q25 21 28 21 Q30 21 30 24 L30 30 L31 20 Q31 17 34 17 Q36 17 36 20 L36 30 L38 22 Q39 19 42 20 Q44 21 43 24 L41 36 L44 33 Q47 31 48 34 Q48 36 46 38 L40 48 Q37 53 32 53 Z" fill={g("skin")} stroke="#2a1448" strokeWidth="1.6" strokeLinejoin="round" />
            <circle cx="33" cy="42" r="6" fill="#e6c4ff" opacity="0.5" />
          </g>
        );
      case "blink":
        return (
          <g>
            {/* afterimages */}
            {[[12, 0.22], [24, 0.45]].map(([x, o], i) => (
              <g key={i} opacity={o} transform={`translate(${x - 38} 0)`}>
                <circle cx="38" cy="18" r="6" fill="#e6c4ff" />
                <path d="M32 26 Q38 24 44 26 L46 44 L40 44 L38 36 L36 44 L30 44 Z" fill="#c58bff" />
              </g>
            ))}
            <path d="M6 20 h10 M4 30 h14 M8 40 h10" stroke="#f4dcff" strokeWidth="2" strokeLinecap="round" opacity="0.7" />
            {/* the mage, leaning into it */}
            <circle cx="44" cy="16" r="6.5" fill="#f1d9c4" />
            <path d="M37.5 13 Q44 7 51 13 Q46 12 38 17 Z" fill="#f2c14e" />
            <path d="M38 26 Q45 23 52 27 L54 46 L47 46 L45 38 L43 56 L36 56 L37 40 Z" fill={g("robe")} stroke="#e6c4ff" strokeWidth="1.2" strokeLinejoin="round" />
            <path d="M50 28 L60 20" stroke="#8a5b32" strokeWidth="2.4" strokeLinecap="round" />
            <circle cx="60" cy="19" r="2.6" fill="#9bf0ff" />
            <path d="M52 8 v5 M49.5 10.5 h5" stroke="#fff" strokeWidth="1.4" strokeLinecap="round" />
          </g>
        );
      case "barrier":
        return (
          <g>
            <path d="M32 6 L54 14 L52 36 Q50 50 32 59 Q14 50 12 36 L10 14 Z" fill={g("ice")} stroke="#e8fbff" strokeWidth="2" strokeLinejoin="round" />
            <path d="M32 6 L32 59 M10 14 L32 28 L54 14 M12 36 L32 28 L52 36" stroke="#fff" strokeWidth="1.2" opacity="0.7" fill="none" />
            <path d="M32 6 L54 14 L32 28 Z" fill="#fff" opacity="0.4" />
            <path d="M17 18 L23 20" stroke="#fff" strokeWidth="2.4" strokeLinecap="round" />
            <path d="M8 52 l3 -6 l3 6 Z M50 54 l3 -7 l3 7 Z" fill="#bfefff" opacity="0.9" />
          </g>
        );
      case "iceblock":
        return (
          <g>
            <path d="M32 6 L56 18 V44 L32 58 L8 44 V18 Z" fill={g("ice")} stroke="#e8fbff" strokeWidth="2" strokeLinejoin="round" />
            <path d="M8 18 L32 31 L56 18 M32 31 V58" stroke="#fff" strokeWidth="1.3" opacity="0.8" fill="none" />
            <path d="M32 6 L56 18 L32 31 L8 18 Z" fill="#fff" opacity="0.28" />
            {/* the mage frozen inside */}
            <g opacity="0.85">
              <circle cx="32" cy="29" r="5.5" fill="#0d2f5c" />
              <path d="M25 36 Q32 33 39 36 L40 49 L35 49 L32 43 L29 49 L24 49 Z" fill="#0d2f5c" />
              <path d="M24 38 L19 33 M40 38 L45 33" stroke="#0d2f5c" strokeWidth="3" strokeLinecap="round" />
            </g>
            <path d="M14 22 L20 25 M46 40 l3 4" stroke="#fff" strokeWidth="2" strokeLinecap="round" />
          </g>
        );
      case "orb":
        return (
          <g>
            <circle cx="32" cy="32" r="22" fill={g("glow")} />
            <circle cx="32" cy="32" r="15" fill={g("orb")} stroke="#e8fbff" strokeWidth="1.6" />
            {/* swirl */}
            <path d="M20 30 Q24 20 34 20 Q44 20 44 30" stroke="#fff" strokeWidth="2.4" fill="none" strokeLinecap="round" />
            <path d="M44 36 Q40 46 30 45 Q22 44 21 37" stroke="#bfefff" strokeWidth="2.4" fill="none" strokeLinecap="round" />
            <path d="M27 31 Q32 26 37 31 Q32 38 27 31" stroke="#fff" strokeWidth="1.6" fill="none" opacity="0.8" />
            {/* orbiting shards */}
            <path d="M8 22 l5 -3 1 6 Z" fill="#e8fbff" />
            <path d="M52 44 l5 1 -3 5 Z" fill="#e8fbff" />
            <path d="M50 12 l4 2 -3 4 Z" fill="#9bf0ff" />
            <circle cx="10" cy="46" r="2" fill="#fff" />
          </g>
        );
      case "blizzard":
        return (
          <g>
            {/* ground circle the storm lands in */}
            <ellipse cx="32" cy="50" rx="25" ry="8" fill={g("glow")} opacity="0.75" />
            <ellipse cx="32" cy="50" rx="24" ry="7.2" fill="none" stroke="#e8fbff" strokeWidth="2" />
            <ellipse cx="32" cy="50" rx="15" ry="4.2" fill="none" stroke="#9bf0ff" strokeWidth="1.2" strokeDasharray="4 3" />
            {/* storm cloud */}
            <path d="M12 26 Q8 26 8 21 Q8 15 15 15 Q17 8 25 9 Q31 4 38 10 Q47 8 48 16 Q56 17 55 23 Q54 27 48 27 Z" fill="#2a4a86" stroke="#bfefff" strokeWidth="1.6" strokeLinejoin="round" />
            <path d="M16 22 Q20 16 28 17 M34 15 Q42 13 46 19" stroke="#e8fbff" strokeWidth="1.4" fill="none" strokeLinecap="round" opacity="0.8" />
            {/* falling ice shards */}
            <path d="M18 30 L22 40 L16 38 Z" fill={g("ice")} stroke="#fff" strokeWidth="1" strokeLinejoin="round" />
            <path d="M31 31 L36 45 L28 42 Z" fill={g("ice")} stroke="#fff" strokeWidth="1" strokeLinejoin="round" />
            <path d="M44 30 L48 41 L42 39 Z" fill={g("ice")} stroke="#fff" strokeWidth="1" strokeLinejoin="round" />
            <circle cx="24" cy="34" r="1.5" fill="#fff" />
            <circle cx="39" cy="36" r="1.3" fill="#fff" />
            <circle cx="12" cy="42" r="1.2" fill="#d9f7ff" />
            <circle cx="52" cy="44" r="1.4" fill="#fff" />
          </g>
        );
      case "coldsnap":
        return (
          <g>
            {/* hourglass */}
            <path d="M18 8 H46 M18 56 H46" stroke="#e8fbff" strokeWidth="4" strokeLinecap="round" />
            <path d="M21 10 H43 V16 Q43 26 32 32 Q43 38 43 48 V54 H21 V48 Q21 38 32 32 Q21 26 21 16 Z" fill="#0d2f5c" fillOpacity="0.55" stroke="#bfefff" strokeWidth="2" strokeLinejoin="round" />
            <path d="M25 14 H39 Q38 22 32 27 Q26 22 25 14 Z" fill="#9bf0ff" opacity="0.8" />
            <path d="M32 34 V46" stroke="#e8fbff" strokeWidth="1.6" />
            <path d="M24 53 Q32 42 40 53 Z" fill="#e8fbff" />
            {/* frost */}
            <g stroke="#fff" strokeWidth="1.6" strokeLinecap="round">
              <path d="M52 20 v10 M47 25 h10 M48.5 21.5 l7 7 M55.5 21.5 l-7 7" />
              <path d="M10 34 v8 M6 38 h8 M7.2 35.2 l5.6 5.6 M12.8 35.2 l-5.6 5.6" />
            </g>
          </g>
        );
      case "dash":
        return (
          <g>
            <path d="M4 22 H30 M10 32 H34 M4 42 H28" stroke="#d6dbe8" strokeWidth="3" strokeLinecap="round" opacity="0.65" />
            <path d="M34 14 L44 14 L56 32 L44 50 L34 50 L44 32 Z" fill="#fff" opacity="0.92" />
            <path d="M24 14 L30 14 L42 32 L30 50 L24 50 L36 32 Z" fill="#9bf0ff" opacity="0.8" />
            <circle cx="52" cy="14" r="2" fill="#fff" />
          </g>
        );
      default:
        return <circle cx="32" cy="32" r="16" fill={c.main} />;
    }
  })();
  return (
    <>
      <defs>
        <radialGradient id={`${uid}-bg`} cx="50%" cy="40%" r="75%">
          <stop offset="0" stopColor={c.main} stopOpacity="0.55" />
          <stop offset="0.6" stopColor={c.dark} />
          <stop offset="1" stopColor="#070a16" />
        </radialGradient>
        <linearGradient id={`${uid}-ice`} x1="0" y1="0" x2="1" y2="1">
          <stop offset="0" stopColor="#ffffff" />
          <stop offset="0.45" stopColor="#8fe6ff" />
          <stop offset="1" stopColor="#2e86d8" />
        </linearGradient>
        <linearGradient id={`${uid}-trail`} x1="0" y1="1" x2="1" y2="0">
          <stop offset="0" stopColor="#5fe0ff" stopOpacity="0" />
          <stop offset="1" stopColor="#d9f7ff" stopOpacity="0.95" />
        </linearGradient>
        <radialGradient id={`${uid}-glow`}>
          <stop offset="0" stopColor="#9bf0ff" stopOpacity="0.9" />
          <stop offset="1" stopColor="#5fe0ff" stopOpacity="0" />
        </radialGradient>
        <radialGradient id={`${uid}-orb`} cx="40%" cy="35%" r="70%">
          <stop offset="0" stopColor="#ffffff" />
          <stop offset="0.5" stopColor="#7fdcff" />
          <stop offset="1" stopColor="#1c5fb8" />
        </radialGradient>
        <linearGradient id={`${uid}-skin`} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor="#f6dfcc" />
          <stop offset="1" stopColor="#d9a888" />
        </linearGradient>
        <linearGradient id={`${uid}-robe`} x1="0" y1="0" x2="1" y2="1">
          <stop offset="0" stopColor="#5a7bff" />
          <stop offset="1" stopColor="#1a2250" />
        </linearGradient>
      </defs>
      <rect x="0" y="0" width="64" height="64" fill={g("bg")} />
      {body}
    </>
  );
}

/** One ability picture. `size` in px. Pure art: the frame, sweep and labels come from the action slot. */
export function SpellIcon({ id, school, size = 48, className = "" }: { id: string; school: School; size?: number; className?: string }) {
  const uid = useId().replace(/:/g, "");
  return (
    <svg className={`spell-art ${className}`} width={size} height={size} viewBox="0 0 64 64" role="img" aria-hidden="true" focusable="false">
      <Art id={id} uid={uid} school={school} />
    </svg>
  );
}
