"use client";

/**
 * Technical-drawing glyphs (ISO / P&ID linework).
 *
 * Design rules — one language for every part:
 *  - structure drawn in a single ink, one stroke weight, butt caps
 *  - no colour blobs: liquid = section hatch, valves/pumps = open triangles
 *  - the `color` prop is a functional accent only (duty arrows, fluid detail)
 *  - each HX family has a distinct, standards-inspired silhouette
 */

import type { ReactElement, ReactNode } from "react";
import { hxGlyphKey, type HxVisualOpts } from "@/lib/hxFamily";

type IconProps = { color: string; secondaryFluid?: string | null };

const INK = "#2f3e52";
const INK_FAINT = "rgba(47,62,82,0.34)";

function Frame({ children }: { children: ReactNode }) {
  return (
    <svg
      viewBox="0 0 100 100"
      width="100%"
      height="100%"
      fill="none"
      preserveAspectRatio="xMidYMid meet"
      aria-hidden
    >
      {children}
    </svg>
  );
}

const line = (w = 2) => ({
  stroke: INK,
  strokeWidth: w,
  strokeLinecap: "butt" as const,
  strokeLinejoin: "miter" as const,
});

const accent = (c: string, w = 2) => ({
  stroke: c,
  strokeWidth: w,
  strokeLinecap: "butt" as const,
  strokeLinejoin: "miter" as const,
});

/** Section hatch — the engineering way to say "liquid here". */
function Hatch({ xs, yBottom, yTop, run = 9 }: { xs: number[]; yBottom: number; yTop: number; run?: number }) {
  return (
    <g stroke={INK} strokeWidth={1}>
      {xs.map((x) => (
        <line key={x} x1={x} y1={yBottom} x2={x + run} y2={yTop} />
      ))}
    </g>
  );
}

/** Up arrow (heat duty). */
function DutyArrow({ x, y1, y2, c }: { x: number; y1: number; y2: number; c: string }) {
  const head = y2 < y1 ? 4 : -4;
  return (
    <g {...accent(c, 1.8)}>
      <line x1={x} y1={y1} x2={x} y2={y2} />
      <path d={`M${x - 3.2} ${y2 + head} L${x} ${y2} L${x + 3.2} ${y2 + head}`} fill="none" />
    </g>
  );
}

const GLYPHS: Record<string, (c: string) => ReactElement> = {
  // ── Compressor — ISO circle + converging flow lines ────────
  compressor: (c) => (
    <Frame>
      <circle cx="50" cy="50" r="34" {...line(2.2)} />
      <path d="M28 30 L74 44 M28 70 L74 56" {...line(2)} />
      <path d="M74 44 V56" {...accent(c, 2.2)} />
    </Frame>
  ),

  // ── Shell & tube condenser — vessel, tubesheets, heat out ──
  hx_shell_cond: (c) => (
    <Frame>
      <rect x="8" y="34" width="84" height="36" rx="18" {...line(2.2)} />
      <line x1="22" y1="36" x2="22" y2="68" {...line(1.4)} />
      <line x1="78" y1="36" x2="78" y2="68" {...line(1.4)} />
      <path d="M22 44 H78 M22 52 H78 M22 60 H78" {...line(1.2)} />
      <DutyArrow x={35} y1={28} y2={14} c={c} />
      <DutyArrow x={50} y1={28} y2={12} c={c} />
      <DutyArrow x={65} y1={28} y2={14} c={c} />
    </Frame>
  ),

  // ── Shell & tube evaporator — heat in from below ───────────
  hx_shell_evap: (c) => (
    <Frame>
      <rect x="8" y="30" width="84" height="36" rx="18" {...line(2.2)} />
      <line x1="22" y1="32" x2="22" y2="64" {...line(1.4)} />
      <line x1="78" y1="32" x2="78" y2="64" {...line(1.4)} />
      <path d="M22 40 H78 M22 48 H78 M22 56 H78" {...line(1.2)} />
      <DutyArrow x={35} y1={88} y2={74} c={c} />
      <DutyArrow x={50} y1={90} y2={72} c={c} />
      <DutyArrow x={65} y1={88} y2={74} c={c} />
    </Frame>
  ),

  // ── Flooded evaporator — horizontal drum, level + hatch ────
  hx_flooded: (c) => (
    <Frame>
      {/* vapour outlet stub */}
      <path d="M46 20 V28 M54 20 V28" {...line(1.4)} />
      <rect x="10" y="28" width="80" height="44" rx="22" {...line(2.2)} />
      {/* liquid level */}
      <line x1="13" y1="42" x2="87" y2="42" {...accent(c, 1.6)} />
      {/* section hatch = liquid */}
      <Hatch xs={[20, 27, 34, 41, 48, 55, 62, 69, 76]} yBottom={66} yTop={46} />
      {/* submerged tube nest */}
      {[26, 38, 50, 62, 74].map((x) => (
        <circle key={`r1-${x}`} cx={x} cy="52" r="4" fill="#fff" {...line(1.3)} />
      ))}
      {[32, 44, 56, 68].map((x) => (
        <circle key={`r2-${x}`} cx={x} cy="61" r="4" fill="#fff" {...line(1.3)} />
      ))}
    </Frame>
  ),

  // ── Brazed plate — plate pack diagonals + 4 ports ──────────
  hx_plate: (c) => (
    <Frame>
      <rect x="30" y="10" width="40" height="80" {...line(2.2)} />
      <line x1="35" y1="10" x2="35" y2="90" {...line(1.2)} />
      <line x1="65" y1="10" x2="65" y2="90" {...line(1.2)} />
      {[32, 41, 50, 59, 68, 77, 86].map((y) => (
        <line key={y} x1="35" y1={y} x2="65" y2={y - 18} {...line(1.1)} />
      ))}
      <circle cx="41" cy="19" r="3.4" fill="#fff" {...accent(c, 1.6)} />
      <circle cx="59" cy="19" r="3.4" fill="#fff" {...accent(c, 1.6)} />
      <circle cx="41" cy="81" r="3.4" fill="#fff" {...accent(c, 1.6)} />
      <circle cx="59" cy="81" r="3.4" fill="#fff" {...accent(c, 1.6)} />
    </Frame>
  ),

  // ── DX coil — serpentine through fin pack ──────────────────
  hx_dx: (c) => (
    <Frame>
      <rect x="14" y="26" width="72" height="50" {...line(2.2)} />
      {[22, 30, 38, 46, 54, 62, 70, 78].map((x) => (
        <line key={x} x1={x} y1="26" x2={x} y2="76" stroke={INK_FAINT} strokeWidth={1} />
      ))}
      <path
        d="M6 36 H72 a8 8 0 0 1 0 15 H28 a8 8 0 0 0 0 15 H94"
        {...accent(c, 2.2)}
        fill="none"
      />
    </Frame>
  ),

  // ── Fin coil — radiator zigzag + air through ───────────────
  hx_coil: (c) => (
    <Frame>
      <rect x="12" y="28" width="76" height="48" {...line(2.2)} />
      <path
        d="M12 52 L21 36 L30 68 L39 36 L48 68 L57 36 L66 68 L75 36 L84 68 L88 52"
        {...line(1.6)}
        fill="none"
      />
      <DutyArrow x={30} y1={92} y2={82} c={c} />
      <DutyArrow x={50} y1={92} y2={82} c={c} />
      <DutyArrow x={70} y1={92} y2={82} c={c} />
      <DutyArrow x={30} y1={22} y2={12} c={c} />
      <DutyArrow x={50} y1={22} y2={12} c={c} />
      <DutyArrow x={70} y1={22} y2={12} c={c} />
    </Frame>
  ),

  // ── MCHX — headers + flat multiport tubes ──────────────────
  hx_mchx: (c) => (
    <Frame>
      <rect x="12" y="26" width="76" height="50" {...line(2.2)} />
      <line x1="21" y1="26" x2="21" y2="76" {...line(1.4)} />
      <line x1="79" y1="26" x2="79" y2="76" {...line(1.4)} />
      {[33, 40, 47, 54, 61, 68].map((y) => (
        <line key={y} x1="21" y1={y} x2="79" y2={y} {...line(1.1)} />
      ))}
      <path d="M6 32 H12 M88 32 H94" {...accent(c, 2)} />
    </Frame>
  ),

  // ── Generic HX — ISO circle with wavy element ──────────────
  hx: (c) => (
    <Frame>
      <circle cx="50" cy="50" r="32" {...line(2.2)} />
      <path d="M18 50 C28 36 39 64 50 50 S 72 36 82 50" {...accent(c, 2)} fill="none" />
    </Frame>
  ),

  // ── Valve — ISO bowtie + actuator stem ─────────────────────
  valve: (c) => (
    <Frame>
      <path d="M12 32 L12 68 L50 50 Z" {...line(2)} fill="none" />
      <path d="M88 32 L88 68 L50 50 Z" {...line(2)} fill="none" />
      <line x1="50" y1="50" x2="50" y2="28" {...line(1.6)} />
      <line x1="38" y1="28" x2="62" y2="28" {...accent(c, 2.2)} />
    </Frame>
  ),

  // ── Reversing valve (4-way heat-pump) — body + two-way arrows ⇄ ──
  reversing: (c) => (
    <Frame>
      <rect x="24" y="32" width="52" height="36" rx="3" {...line(2)} fill="none" />
      <line x1="6" y1="50" x2="24" y2="50" {...line(2)} />
      <line x1="76" y1="50" x2="94" y2="50" {...line(2)} />
      <line x1="36" y1="44" x2="60" y2="44" {...accent(c, 1.8)} />
      <path d="M57 41 L60 44 L57 47" {...accent(c, 1.8)} fill="none" />
      <line x1="60" y1="56" x2="36" y2="56" {...accent(c, 1.8)} />
      <path d="M39 53 L36 56 L39 59" {...accent(c, 1.8)} fill="none" />
    </Frame>
  ),

  // ── Pump — circle + filled flow triangle ───────────────────
  pump: (c) => (
    <Frame>
      <circle cx="50" cy="50" r="32" {...line(2.2)} />
      <path d="M38 32 L70 50 L38 68 Z" fill={c} stroke="none" />
    </Frame>
  ),

  // ── Fan — circle + two blades ──────────────────────────────
  fan: (c) => (
    <Frame>
      <circle cx="50" cy="50" r="32" {...line(2.2)} />
      <path d="M50 50 C36 42 38 24 56 28 M50 50 C64 58 62 76 44 72" {...accent(c, 2.2)} fill="none" />
      <circle cx="50" cy="50" r="3" fill={INK} />
    </Frame>
  ),

  // ── Pipe — double line + flanges ───────────────────────────
  pipe: (c) => (
    <Frame>
      <path d="M6 44 H94 M6 56 H94" {...line(1.8)} />
      <path d="M14 38 V62 M86 38 V62" {...line(1.6)} />
      <path d="M42 50 H58 M53 45 L58 50 L53 55" {...accent(c, 1.6)} fill="none" />
    </Frame>
  ),

  // ── Separator drum — vertical vessel, level + hatch ────────
  drum: (c) => (
    <Frame>
      <rect x="30" y="8" width="40" height="84" rx="20" {...line(2.2)} />
      <line x1="32" y1="56" x2="68" y2="56" {...accent(c, 1.6)} />
      <Hatch xs={[36, 44, 52]} yBottom={82} yTop={62} run={8} />
    </Frame>
  ),

  splitter: (c) => (
    <Frame>
      <path d="M8 50 H42 M42 50 L88 26 M42 50 L88 74" {...line(2.2)} />
      <circle cx="42" cy="50" r="4" fill={INK} />
      <path d="M80 30 L88 26 L86 35" {...accent(c, 1.6)} fill="none" />
    </Frame>
  ),

  merger: (c) => (
    <Frame>
      <path d="M12 26 L58 50 M12 74 L58 50 M58 50 H92" {...line(2.2)} />
      <circle cx="58" cy="50" r="4" fill={INK} />
      <path d="M84 45 L92 50 L84 55" {...accent(c, 1.6)} fill="none" />
    </Frame>
  ),

  // ── Boundary source — circle + hatched ground + arrow ──────
  source: (c) => (
    <Frame>
      <circle cx="40" cy="50" r="24" {...line(2.2)} />
      <Hatch xs={[26, 33, 40]} yBottom={62} yTop={40} run={8} />
      <path d="M66 50 H92 M84 42 L92 50 L84 58" {...accent(c, 2.2)} fill="none" />
    </Frame>
  ),

  sink: (c) => (
    <Frame>
      <circle cx="60" cy="50" r="24" {...line(2.2)} />
      <Hatch xs={[46, 53, 60]} yBottom={62} yTop={40} run={8} />
      <path d="M8 50 H34 M26 42 L34 50 L26 58" {...accent(c, 2.2)} fill="none" />
    </Frame>
  ),

  placeholder: (c) => (
    <Frame>
      <rect
        x="14"
        y="24"
        width="72"
        height="52"
        stroke={c}
        strokeWidth={1.8}
        strokeDasharray="5 4"
      />
    </Frame>
  ),

  control: (c) => (
    <Frame>
      <rect x="8" y="24" width="84" height="52" {...line(2)} />
      <path d="M16 60 C26 34 38 34 48 60 S 70 78 84 52" {...accent(c, 2)} fill="none" />
    </Frame>
  ),

  // ── Probe — small measurement tap on a connection line ─────────
  // A filled circle with a thin ring + a small dot inside. Deliberately
  // compact (the 36×36 node footprint makes it read as a tap, not a block).
  // The four short ticks hint at a sensor crosshair.
  probe: (c) => (
    <Frame>
      <circle cx="50" cy="50" r="34" {...line(2)} />
      <circle cx="50" cy="50" r="20" {...accent(c, 1.6)} />
      <circle cx="50" cy="50" r="6" fill={c} stroke="none" />
      <path
        d="M50 8 V22 M50 78 V92 M8 50 H22 M78 50 H92"
        {...line(1.4)}
      />
    </Frame>
  ),
};

function glyphKey(type?: string, opts?: HxVisualOpts): keyof typeof GLYPHS {
  const t = String(type || "");
  const hx = hxGlyphKey(t, opts);
  if (hx && hx in GLYPHS) return hx as keyof typeof GLYPHS;

  if (t === "SaturatedController") return "control";
  if (t === "Probe") return "probe";
  if (t.includes("Compressor")) return "compressor";
  if (t === "HeatExchanger") return "hx";
  if (t === "ReversingValve") return "reversing";
  if (t.includes("Valve")) return "valve";
  if (t === "Pump") return "pump";
  if (t === "Fan") return "fan";
  if (t === "Pipe" || t.includes("Pipe") || t === "AirDuct") return "pipe";
  if (t === "Drum") return "drum";
  if (t === "FlowSplitter") return "splitter";
  if (t === "FlowMerger") return "merger";
  if (t.endsWith("Source")) return "source";
  if (t.endsWith("Sink")) return "sink";
  return "placeholder";
}

export function ComponentIcon({
  type,
  color,
  secondaryFluid,
}: { type?: string } & IconProps) {
  const draw = GLYPHS[glyphKey(type, { secondaryFluid })] ?? GLYPHS.placeholder;
  return draw(color);
}
