// Forage & Forests — shared UI atoms.

/* eslint-disable no-undef */

function SmallCaps({ children, className = "", style }) {
  return <span className={`hh-smallcaps ${className}`} style={style}>{children}</span>;
}

// Resource iconography — the same flame / tincture-flower / seed glyphs as the
// printed cards, so a season's yield reads as icons-with-counts instead of
// "3C 2B s1" letter codes.
const RES_ICON = {
  calories: "/assets/resource-icons/calories-flame.png",
  botanicals: "/assets/resource-icons/botanicals.png",
  seeds: "/assets/resource-icons/seed.png",
};
const RES_LABEL = { calories: "Calories", botanicals: "Botanicals", seeds: "Seeds" };

// Render a yield object {calories, botanicals, seeds} as a row of icon+count
// chips. Resources with no yield are skipped; an all-zero yield renders a dash.
function YieldIcons({ y = {}, dormantLabel = "—" }) {
  const present = ["calories", "botanicals", "seeds"].filter((k) => y[k]);
  if (!present.length) return <span className="yield-none">{dormantLabel}</span>;
  return (
    <span className="yield-icons">
      {present.map((k) => (
        <span key={k} className="yield-chip" title={`${y[k]} ${RES_LABEL[k]}`}>
          <img className="res-icon" src={RES_ICON[k]} alt={RES_LABEL[k]} />
          <span className="res-n">{y[k]}</span>
        </span>
      ))}
    </span>
  );
}

function RingMeeple({ rings = 3, exhausted = false, color, scale = 1 }) {
  const w = 22 * scale;
  const h = 30 * scale;
  return (
    <div className={`hh-meeple${exhausted ? " exhausted" : ""}`} title={`${rings}/3 rings`}>
      <div className="rings" style={{ width: w }}>
        {[0, 1, 2].map((i) => (
          <div key={i} className={`ring${i < rings ? " filled" : ""}`} style={{ width: w }} />
        ))}
      </div>
      <svg className="body" width={w} height={h} viewBox="0 0 22 30">
        <circle cx="11" cy="6" r="4.5" fill={color || "currentColor"} />
        <path d="M3 28 C3 18 19 18 19 28 Z" fill={color || "currentColor"} />
      </svg>
    </div>
  );
}

function BotIcon({ size = 18, color = "currentColor", title }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="1.6"
      strokeLinecap="round" strokeLinejoin="round" aria-label={title || "AI"}>
      <rect x="5" y="8" width="14" height="11" rx="2" />
      <path d="M12 3 v5 M9 12 v2 M15 12 v2" />
      <path d="M3 14 h2 M19 14 h2" />
      <circle cx="12" cy="3" r="1.2" fill={color} />
    </svg>
  );
}

function PencilIcon({ size = 16, color = "currentColor" }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="1.6"
      strokeLinecap="round" strokeLinejoin="round" aria-label="Edit">
      <path d="M16 3.5 L20.5 8 L8 20.5 L3 21 L3.5 16 Z" />
      <path d="M14 5.5 L18.5 10" />
    </svg>
  );
}

function PlusIcon({ size = 18 }) {
  return <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M12 5v14M5 12h14" /></svg>;
}

function MinusIcon({ size = 18 }) {
  return <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14" /></svg>;
}

function CloseIcon({ size = 18 }) {
  return <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M6 6 L18 18 M18 6 L6 18" /></svg>;
}

function BookIcon({ size = 18 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6"
      strokeLinecap="round" strokeLinejoin="round">
      <path d="M4 4 h7 a3 3 0 0 1 3 3 v13 a3 3 0 0 0 -3 -3 h-7 Z" />
      <path d="M20 4 h-7 a3 3 0 0 0 -3 3 v13 a3 3 0 0 1 3 -3 h7 Z" />
    </svg>
  );
}

function EyeIcon({ size = 16, closed = false }) {
  // Open eye for "reveal me", crossed eye for "hide me". Stroke uses
  // currentColor so callers can recolor via style/className.
  if (closed) {
    return (
      <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
        stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94" />
        <path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19" />
        <path d="M14.12 14.12a3 3 0 1 1-4.24-4.24" />
        <line x1="1" y1="1" x2="23" y2="23" />
      </svg>
    );
  }
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8S1 12 1 12z" />
      <circle cx="12" cy="12" r="3" />
    </svg>
  );
}

function Stepper({ value, min = 0, max = 6, onChange, label }) {
  return (
    <div className="hh-stepper" role="group" aria-label={label}>
      <button type="button" onClick={() => onChange(Math.max(min, value - 1))} disabled={value <= min} aria-label={`Decrease ${label}`}>
        <MinusIcon />
      </button>
      <div className="count" aria-live="polite">{value}</div>
      <button type="button" onClick={() => onChange(Math.min(max, value + 1))} disabled={value >= max} aria-label={`Increase ${label}`}>
        <PlusIcon />
      </button>
    </div>
  );
}

// Die showing 1..6
const DIE_PIPS = {
  1: [[1, 1]],
  2: [[0, 0], [2, 2]],
  3: [[0, 0], [1, 1], [2, 2]],
  4: [[0, 0], [0, 2], [2, 0], [2, 2]],
  5: [[0, 0], [0, 2], [2, 0], [2, 2], [1, 1]],
  6: [[0, 0], [0, 1], [0, 2], [2, 0], [2, 1], [2, 2]],
};
function Die({ value, rolling = false, size = 56 }) {
  return (
    <div className="hh-die" style={{
      width: size, height: size,
      animation: rolling ? "hh-die-roll 0.32s linear infinite" : "none",
    }}>
      {Array.from({ length: 9 }).map((_, i) => {
        const row = Math.floor(i / 3);
        const col = i % 3;
        const present = (DIE_PIPS[value] || []).some(([r, c]) => r === row && c === col);
        return present ? <span key={i} className="pip" /> : <span key={i} />;
      })}
    </div>
  );
}

// Plant card — used in hand, market, and deck.
function PlantCard({ plant, season = "Fall", kind = "hand", onAction, biomeMatches = false }) {
  const yields = plant.yields || {};
  const seasons = window.HH.SEASONS;
  const active = plant.active_yield || yields[season] || {};
  const produces = (active.calories || 0) + (active.botanicals || 0) + (active.seeds || 0) > 0;
  const seasonShort = { Spring: "Spr", Summer: "Sum", Fall: "Fal", Winter: "Win" };
  return (
    <article className="hh-card">
      <div className="head">
        <div>
          <div className="name">{plant.name}</div>
          <div className="sci">{plant.scientific_name || ""}</div>
        </div>
        {plant.layer_affinity && <span className="layer-tag">{plant.layer_affinity}</span>}
      </div>
      <div className="hh-art-frame" style={{ aspectRatio: "5 / 4" }}>
        {plant.art_path ? (
          <img src={plant.art_path} alt={`${plant.name} botanical illustration`} loading="lazy" />
        ) : (
          <SmallCaps>plate · {plant.name}</SmallCaps>
        )}
      </div>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", fontSize: 11 }}>
        <SmallCaps className="muted">{plant.biome}{biomeMatches ? " · matches camp" : ""}</SmallCaps>
        <span className="hh-mono" style={{ color: produces ? "var(--ink)" : "var(--ink-faded)", fontSize: 11, fontWeight: 600 }}>
          {produces ? <YieldIcons y={active} /> : "dormant"}
        </span>
      </div>
      {plant.yields && (
        <div className="yields">
          {seasons.map((s) => (
            <div key={s} className={`col${s === season ? " active" : ""}`}>
              <span className="s">{seasonShort[s]}</span>
              <YieldIcons y={yields[s] || {}} />
            </div>
          ))}
        </div>
      )}
      {plant.id_feature && (
        <div className="id-note">
          <strong className="hh-smallcaps" style={{ marginRight: 4 }}>ID</strong>{plant.id_feature}
        </div>
      )}
      {kind === "hand" && onAction && (
        <div className="controls">
          <button className="hh-btn primary" onClick={() => onAction("harvest")}>Harvest</button>
          <button className="hh-btn" onClick={() => onAction("build")}>{plant.card_type === "mushroom" ? "Play" : "Build"}</button>
          <button className="hh-btn ghost" onClick={() => onAction("seeds")}>Seeds</button>
        </div>
      )}
      {kind === "market" && onAction && (
        <div className="controls">
          <button className="hh-btn primary" onClick={() => onAction("claim")}>Claim</button>
        </div>
      )}
    </article>
  );
}

// Topbar
function Topbar({ left, right, screen }) {
  return (
    <header className="hh-topbar">
      <div className="brand">
        <h1>Forage <span style={{ color: "var(--sepia)" }}>&amp;</span> Forests</h1>
        <span className="sub">a foraging & food-forest game</span>
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: 14 }}>
        {screen && <SmallCaps className="muted">{screen}</SmallCaps>}
        {right}
      </div>
    </header>
  );
}

// Toast / notice line
function Notice({ children, tone = "info" }) {
  const bg = tone === "warn" ? "rgba(184, 77, 63, 0.08)" : tone === "good" ? "rgba(79, 122, 63, 0.08)" : "var(--paper-warm)";
  const bd = tone === "warn" ? "var(--accent)" : tone === "good" ? "var(--good)" : "var(--rule)";
  return (
    <div style={{
      borderLeft: `3px solid ${bd}`,
      background: bg,
      padding: "8px 14px",
      font: "italic 400 14px/1.4 'EB Garamond', serif",
      color: "var(--ink-soft)",
    }}>{children}</div>
  );
}

// Animated dice keyframes — injected once.
(function injectKeyframes() {
  if (document.getElementById("hh-die-keyframes")) return;
  const s = document.createElement("style");
  s.id = "hh-die-keyframes";
  s.textContent = `
    @keyframes hh-die-roll {
      0%   { transform: rotate(0deg)   translateY(0); }
      25%  { transform: rotate(90deg)  translateY(-3px); }
      50%  { transform: rotate(180deg) translateY(0); }
      75%  { transform: rotate(270deg) translateY(-3px); }
      100% { transform: rotate(360deg) translateY(0); }
    }
    @keyframes hh-pulse {
      0%, 100% { opacity: 1; }
      50%      { opacity: 0.45; }
    }
    @keyframes hh-place-pop {
      0%   { transform: scale(0.3); opacity: 0; }
      60%  { transform: scale(1.2); opacity: 1; }
      100% { transform: scale(1);   opacity: 1; }
    }
  `;
  document.head.appendChild(s);
})();

Object.assign(window, {
  SmallCaps, RingMeeple, BotIcon, PencilIcon, PlusIcon, MinusIcon, CloseIcon, BookIcon, EyeIcon,
  Stepper, Die, PlantCard, Topbar, Notice,
});
