/* global React */
// ====================================================================
// FACILITY CARDS — three visual directions for the T2 rescue→building
// identity. Each renders the SAME enriched record (`view`) so they can be
// compared 1:1 by toggling the card-style switch in the screen.
//
//   view = {
//     id, name, role, effect, zoneName,
//     element:  { key, name, color, glyph, primal },
//     category: { key, label },
//     kind:     'convince' | 'physical',
//     gate:      human gate string  ('Nature ≥ 110' | 'Band 12–45')
//     gateNote:  one-line rule note
//     prereqs:  [{ id, name, met }],
//     base:     { role, label, line },   // node identity while unclaimed
//     wave:     maturity wave string,
//     discovery:'visible' | 'hidden',
//     status:   'built' | 'ready' | 'locked' | 'hidden',
//   }
//
// Every direction expresses the rescue→building DUALITY: while unclaimed a
// plot pays its BASE role (forage / offering / scout); claimed, it becomes
// the BUILDING. Cards lean on the shared status vocabulary below.
// ====================================================================

const STATUS_META = {
  built:  { stamp: 'PLOT RAISED',     color: 'var(--ink)',        cls: 'stamp-blue'  },
  ready:  { stamp: 'READY TO CLAIM',  color: 'var(--stamp-amber)',cls: 'stamp-amber' },
  locked: { stamp: 'CLAIM SEALED',    color: 'var(--sepia)',      cls: ''            },
  hidden: { stamp: 'UNCHARTED',       color: 'var(--ink-faded)',  cls: ''            },
};

// A dotted-leader ledger row (label · · · · value) — used across directions.
function FacRow({ label, value, mono, color }) {
  return (
    <div className="row" style={{ alignItems: 'baseline', padding: '1px 0' }}>
      <span className="label" style={{ fontSize: 9, whiteSpace: 'nowrap', flexShrink: 0 }}>{label}</span>
      <span style={{ flex: '1 1 auto', minWidth: 6, borderBottom: '1px dotted var(--ink-ghost)', margin: '0 7px', transform: 'translateY(-3px)' }} />
      <span className={mono ? 'mono' : 'elite'} style={{
        fontSize: mono ? 11 : 12, color: color || 'var(--ink)', whiteSpace: 'nowrap',
        flexShrink: 0, textAlign: 'right',
      }}>{value}</span>
    </div>
  );
}

// Claim action / status footer shared by all three (kept visually neutral so
// each card frame supplies its own chrome around it).
function ClaimAction({ view, onClaim }) {
  const { status, kind, lockReason } = view;
  // Capstone gate met, but the hearth upgrade that would let you claim it
  // doesn't exist yet — reachable-but-walled (necessary, not sufficient).
  if (status === 'ready' && lockReason === 'nyi') {
    return (
      <div className="row gap-8" style={{ padding: '9px 12px', border: '1.5px dashed var(--sepia)', background: 'rgba(107,74,43,0.05)' }}>
        <span style={{ color: 'var(--sepia)', fontSize: 13 }}>◈</span>
        <span className="elite" style={{ fontSize: 11, color: 'var(--ink-soft)', lineHeight: 1.4 }}>
          Gate met — the capstone awaits a hearth upgrade not yet built. <span className="mono" style={{ fontSize: 9 }}>NYI</span>
        </span>
      </div>
    );
  }
  if (status === 'ready') {
    return (
      <button className="btn btn-launch" style={{ width: '100%', padding: '11px 16px', fontSize: 15 }}
              onClick={onClaim}>
        {kind === 'physical' ? 'Carry Home ▸' : 'Meet the Gate ▸'}
      </button>
    );
  }
  if (status === 'built') {
    return (
      <div className="row gap-8" style={{ padding: '9px 12px', border: '1.5px solid var(--ok)', background: 'rgba(77,110,63,0.10)' }}>
        <span style={{ color: 'var(--ok)', fontSize: 13 }}>●</span>
        <span className="elite" style={{ fontSize: 11.5, color: 'var(--ink)' }}>Raised — its effect stands in the Hearth.</span>
      </div>
    );
  }
  if (status === 'locked') {
    // The keyed band itself isn't open yet — rescue Zone 0's Gateway crew.
    if (lockReason === 'band') {
      return (
        <div className="row gap-8" style={{ padding: '9px 12px', border: '1.5px dashed var(--sepia)', background: 'rgba(107,74,43,0.05)' }}>
          <span style={{ color: 'var(--sepia)', fontSize: 13 }}>⌬</span>
          <span className="elite" style={{ fontSize: 11, color: 'var(--ink-soft)', lineHeight: 1.4 }}>
            The keyed band is uncharted — rescue the Gateway crew at the end of Zone 0 to open it.
          </span>
        </div>
      );
    }
    // Maturity gate — prereqs are met, but the roster can't hold the gate yet.
    if (lockReason === 'maturity') {
      return (
        <div className="row gap-8" style={{ padding: '9px 12px', border: '1.5px dashed var(--sepia)', background: 'rgba(107,74,43,0.05)' }}>
          <span style={{ color: 'var(--sepia)', fontSize: 13 }}>↟</span>
          <span className="elite" style={{ fontSize: 11, color: 'var(--ink-soft)', lineHeight: 1.4 }}>
            Awaiting a {view.waveLabel} — raise your roster to hold this gate.
          </span>
        </div>
      );
    }
    const blockers = view.prereqs.filter(p => !p.met).map(p => p.name);
    return (
      <div className="row gap-8" style={{ padding: '9px 12px', border: '1.5px dashed var(--sepia)', background: 'rgba(107,74,43,0.05)' }}>
        <span style={{ color: 'var(--sepia)', fontSize: 13 }}>◇</span>
        <span className="elite" style={{ fontSize: 11, color: 'var(--ink-soft)', lineHeight: 1.4 }}>
          Bank {blockers.join(' & ')} to break the seal.
        </span>
      </div>
    );
  }
  // hidden
  return (
    <div className="row gap-8" style={{ padding: '9px 12px', border: '1.5px dashed var(--ink-faded)', background: 'rgba(26,46,74,0.03)' }}>
      <span style={{ color: 'var(--ink-faded)', fontSize: 13 }}>?</span>
      <span className="elite" style={{ fontSize: 11, color: 'var(--ink-faded)', lineHeight: 1.4 }}>
        No survey on file. A later finding may chart this plot.
      </span>
    </div>
  );
}

// Element seal — a small inked medallion, reused.
function ElemSeal({ element, size = 46, dim }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%', flexShrink: 0,
      border: `1.5px solid ${dim ? 'var(--ink-faded)' : element.color}`,
      background: dim ? 'transparent' : `${element.color}1c`,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontFamily: 'IM Fell English SC, serif', fontSize: size * 0.46,
      color: dim ? 'var(--ink-faded)' : element.color,
      boxShadow: dim ? 'none' : `inset 0 0 0 3px ${element.color}10`,
    }}>{element.glyph}</div>
  );
}

// ====================================================================
// DIRECTION 1 — SURVEY PLATE
// The house idiom: a riveted engineering catalogue plate. Corner brackets,
// monospace plot ID, element left-rail, dotted-leader ledger.
// ====================================================================
function FacCardPlate({ view, onClaim }) {
  const el = view.element;
  const sm = STATUS_META[view.status];
  const hide = view.status === 'hidden';
  return (
    <div className="panel brackets" style={{
      position: 'relative', background: 'rgba(244,236,214,0.62)',
      borderColor: 'var(--ink)', display: 'flex', flexDirection: 'column', overflow: 'hidden',
    }}>
      {/* element left rail */}
      <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: 5,
        background: hide ? 'var(--ink-ghost)' : el.color }} />

      {/* head bar */}
      <div className="row" style={{ justifyContent: 'space-between', alignItems: 'center',
        padding: '8px 14px 8px 18px', borderBottom: '1px solid var(--ink-faded)' }}>
        <span className="mono" style={{ fontSize: 10.5, letterSpacing: '0.12em', color: 'var(--sepia)' }}>
          PLOT · {view.id}
        </span>
        <span className="label" style={{ fontSize: 9, color: hide ? 'var(--ink-faded)' : el.color }}>
          {view.category.label}
        </span>
      </div>

      <div style={{ padding: '14px 18px 16px' }}>
        {/* stamp */}
        <div style={{ marginBottom: 11 }}>
          <span className={`stamp ${sm.cls}`} style={{ fontSize: 10,
            ...(sm.cls ? {} : { borderColor: sm.color, color: sm.color }) }}>{sm.stamp}</span>
        </div>

        {/* title + seal */}
        <div className="row" style={{ gap: 13, alignItems: 'flex-start', marginBottom: 12 }}>
          <ElemSeal element={el} dim={hide} />
          <div className="col" style={{ flex: 1, minWidth: 0 }}>
            <div className="fell" style={{ fontSize: 23, lineHeight: 1.05 }}>
              {hide ? 'Uncharted Plot' : view.name}
            </div>
            <div className="label" style={{ marginTop: 3 }}>
              {hide ? `${el.name} band` : `${el.name} · ${view.role}`}
            </div>
          </div>
        </div>

        {/* effect / yield */}
        <div className="panel panel-tight" style={{ padding: '9px 12px', marginBottom: 12,
          borderColor: hide ? 'var(--ink-faded)' : el.color, borderWidth: 1.5,
          background: hide ? 'transparent' : `${el.color}0e` }}>
          <div className="label" style={{ fontSize: 8.5, marginBottom: 3 }}>EFFECT WHEN RAISED</div>
          <div className="elite" style={{ fontSize: 12.5, lineHeight: 1.45, color: hide ? 'var(--ink-faded)' : 'var(--ink)' }}>
            {hide ? '— unknown until charted —' : view.effect}
          </div>
        </div>

        {/* ledger */}
        <div style={{ marginBottom: 13 }}>
          <FacRow label="KIND" value={view.kind === 'physical' ? 'Physical (haul)' : 'Convince (gate)'} />
          <FacRow label={view.kind === 'physical' ? 'BAND' : 'GATE'} mono value={hide ? '— sealed —' : view.gate} color={hide ? 'var(--ink-faded)' : 'var(--ink)'} />
          <FacRow label="PREREQ" value={view.prereqs.length ? view.prereqs.map(p => p.id + (p.met ? ' ✓' : ' ·')).join('  ') : 'none'} mono />
          <FacRow label="UNCLAIMED" value={view.base.role} color="var(--sepia)" />
          <FacRow label="MATURITY" value={view.wave} />
        </div>

        <ClaimAction view={view} onClaim={onClaim} />
      </div>
    </div>
  );
}

// ====================================================================
// DIRECTION 2 — SPECIMEN FOLIO
// A naturalist's catalogue / index card. Ruled paper lines, a pressed wax
// seal, hand-ruled title underline, a two-column register, marginalia for
// status. Quieter and more typographic.
// ====================================================================
function FacCardSpecimen({ view, onClaim }) {
  const el = view.element;
  const sm = STATUS_META[view.status];
  const hide = view.status === 'hidden';
  // faint horizontal rule lines, index-card style
  const ruled = {
    backgroundImage: 'repeating-linear-gradient(transparent 0, transparent 27px, rgba(26,46,74,0.07) 27px, rgba(26,46,74,0.07) 28px)',
    backgroundPosition: '0 8px',
  };
  return (
    <div className="panel" style={{
      position: 'relative', background: 'rgba(248,242,226,0.7)', borderColor: 'var(--ink)',
      display: 'flex', flexDirection: 'column', overflow: 'hidden', ...ruled,
    }}>
      {/* red margin line + catalogue no. */}
      <div style={{ position: 'absolute', left: 40, top: 0, bottom: 0, width: 1, background: 'rgba(161,43,34,0.28)' }} />
      <div className="mono" style={{ position: 'absolute', top: 10, left: 0, width: 40, textAlign: 'center',
        fontSize: 9, color: 'var(--sepia)', letterSpacing: '0.05em', transform: 'rotate(-90deg) translateX(-6px)', transformOrigin: 'center' }}>
        {view.id}
      </div>

      <div style={{ padding: '16px 18px 16px 52px' }}>
        {/* header line: zone + status marginnote */}
        <div className="row" style={{ justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 10 }}>
          <span className="label" style={{ fontSize: 9 }}>FOLIO · {view.zoneName}</span>
          <span className="fell" style={{ fontSize: 11, color: sm.color, letterSpacing: '0.06em',
            borderBottom: `1px solid ${sm.color}`, paddingBottom: 1 }}>{sm.stamp.toLowerCase()}</span>
        </div>

        {/* seal + title */}
        <div className="row" style={{ gap: 14, alignItems: 'flex-start', marginBottom: 6 }}>
          <div style={{ position: 'relative' }}>
            <ElemSeal element={el} size={54} dim={hide} />
            <span className="label" style={{ position: 'absolute', top: '100%', left: '50%', transform: 'translateX(-50%)',
              fontSize: 7.5, marginTop: 3, color: hide ? 'var(--ink-faded)' : el.color, whiteSpace: 'nowrap' }}>{el.name}</span>
          </div>
          <div className="col" style={{ flex: 1, minWidth: 0, paddingTop: 2 }}>
            <div className="fell" style={{ fontSize: 25, lineHeight: 1.04 }}>{hide ? 'Plot Uncharted' : view.name}</div>
            <div style={{ height: 1, background: hide ? 'var(--ink-faded)' : el.color, opacity: 0.55, margin: '5px 0 4px', width: '72%' }} />
            <div className="label" style={{ fontSize: 9 }}>{hide ? `${el.name} · unknown` : `${view.category.label} · ${view.role}`}</div>
          </div>
        </div>

        {/* description — field-note italic */}
        <div className="elite" style={{ fontSize: 12, fontStyle: 'italic', lineHeight: 1.55, color: 'var(--ink-soft)', margin: '12px 0 14px' }}>
          {hide ? 'No entry. The survey ledger holds only a blank leaf where this plot should be — perhaps a later finding fills it in.' : view.effect}
        </div>

        {/* register — two columns */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '2px 18px', marginBottom: 14,
          borderTop: '1px solid var(--ink-faded)', borderBottom: '1px solid var(--ink-faded)', padding: '9px 0' }}>
          <FacRow label="KIND" value={view.kind === 'physical' ? 'Physical' : 'Convince'} />
          <FacRow label={view.kind === 'physical' ? 'BAND' : 'GATE'} mono value={hide ? '—' : view.gate} color={hide ? 'var(--ink-faded)' : 'var(--ink)'} />
          <FacRow label="UNCLAIMED" value={view.base.role} color="var(--sepia)" />
          <FacRow label="MATURITY" value={view.wave.split(' ')[0]} />
        </div>

        {/* base-identity footnote — the duality */}
        <div className="elite" style={{ fontSize: 10.5, color: 'var(--sepia)', lineHeight: 1.45, marginBottom: 14 }}>
          <span style={{ color: 'var(--ink-faded)' }}>※ </span>{view.base.line}
        </div>

        <ClaimAction view={view} onClaim={onClaim} />
      </div>
    </div>
  );
}

// ====================================================================
// DIRECTION 3 — CARGO MANIFEST
// A bill-of-lading ticket. A solid element category band, a perforated tear
// that splits CLAIM (the building) from STUB (the base role it pays while
// unclaimed) — the rescue→building duality made literal. Bold rubber stamp.
// ====================================================================
function FacCardManifest({ view, onClaim }) {
  const el = view.element;
  const sm = STATUS_META[view.status];
  const hide = view.status === 'hidden';
  const notch = (pos) => ({
    position: 'absolute', width: 14, height: 14, borderRadius: '50%',
    background: 'var(--paper)', border: '1.5px solid var(--ink)', ...pos,
  });
  return (
    <div style={{ position: 'relative', display: 'flex', flexDirection: 'column',
      border: '1.5px solid var(--ink)', background: 'rgba(244,236,214,0.66)', overflow: 'hidden' }}>

      {/* category band (reversed-out) */}
      <div className="row" style={{ justifyContent: 'space-between', alignItems: 'center',
        padding: '7px 16px', background: hide ? 'var(--ink-faded)' : el.color }}>
        <span className="fell" style={{ fontSize: 13, letterSpacing: '0.14em', color: 'var(--paper-light)', textTransform: 'uppercase' }}>
          {view.category.label}
        </span>
        <span className="mono" style={{ fontSize: 10.5, color: 'rgba(244,236,214,0.85)', letterSpacing: '0.1em' }}>
          № {view.id}
        </span>
      </div>

      {/* CLAIM half — the building */}
      <div style={{ position: 'relative', padding: '14px 16px 16px' }}>
        {/* diagonal rubber stamp */}
        <div style={{ position: 'absolute', top: 12, right: 12, transform: 'rotate(-9deg)', zIndex: 2 }}>
          <span className="stamp" style={{ fontSize: 9.5, borderColor: sm.color, color: sm.color,
            borderWidth: 2, background: 'transparent', opacity: 0.92 }}>{sm.stamp}</span>
        </div>

        <div className="label" style={{ fontSize: 8.5, marginBottom: 5 }}>CLAIM · {el.name} {view.kind}</div>
        <div className="row" style={{ gap: 11, alignItems: 'center', marginBottom: 11, paddingRight: 70 }}>
          <ElemSeal element={el} size={38} dim={hide} />
          <div className="fell" style={{ fontSize: 21, lineHeight: 1.05 }}>{hide ? 'Uncharted' : view.name}</div>
        </div>

        <div className="elite" style={{ fontSize: 12, lineHeight: 1.45, color: hide ? 'var(--ink-faded)' : 'var(--ink)', marginBottom: 11 }}>
          {hide ? '— consignment not yet logged —' : view.effect}
        </div>

        <FacRow label={view.kind === 'physical' ? 'CARRY BAND' : 'GATE'} mono value={hide ? '— sealed —' : view.gate} color={hide ? 'var(--ink-faded)' : 'var(--ink)'} />
        <FacRow label="PREREQ" mono value={view.prereqs.length ? view.prereqs.map(p => p.id + (p.met ? '✓' : '·')).join('  ') : 'none'} />
      </div>

      {/* perforation */}
      <div style={{ position: 'relative', height: 0, borderTop: '2px dashed var(--ink-faded)' }}>
        <div style={notch({ left: -8, top: -8 })} />
        <div style={notch({ right: -8, top: -8 })} />
      </div>

      {/* STUB half — the base identity while unclaimed */}
      <div style={{ padding: '11px 16px 13px', background: 'rgba(107,74,43,0.06)' }}>
        <div className="label" style={{ fontSize: 8.5, color: 'var(--sepia)', marginBottom: 5 }}>STUB · PAYS WHILE UNCLAIMED</div>
        <div className="row" style={{ justifyContent: 'space-between', alignItems: 'baseline', gap: 12 }}>
          <span className="fell" style={{ fontSize: 15, color: 'var(--sepia)' }}>{view.base.role}</span>
          <span className="mono" style={{ fontSize: 9.5, color: 'var(--sepia)', whiteSpace: 'nowrap' }}>{view.wave}</span>
        </div>
      </div>

      <div style={{ padding: '0 16px 14px' }}>
        <ClaimAction view={view} onClaim={onClaim} />
      </div>
    </div>
  );
}

// expose to the screen module
Object.assign(window, { FacCardPlate, FacCardSpecimen, FacCardManifest });
