/* eslint-disable */
// Odd Hours — Character Sheet (Step 7).
// Faithful recreation of the official Form OH-1 from the published game.
// Two-column landscape layout. Stat-bubble circles you click to fill.
// Pure black-ink aesthetic that prints identically to what's on screen.

(function () {

const {
  ATTRIBUTES, SKILLS, BACKGROUNDS, REACTIONS, COMMON_RITUALS, STATION_REMARKS,
} = window;

function getBackgroundLabel(char) {
  if (char.background === 'custom') return char.customBackgroundName || '';
  const bg = BACKGROUNDS.find((b) => b.key === char.background);
  return bg ? bg.name : '';
}

function mentalState(sanity, absurdity) {
  if (sanity >= 4 && absurdity < 5) return 'Holding On';
  if (sanity < 4 && absurdity < 5) return 'Unraveling';
  if (sanity >= 4 && absurdity >= 5) return 'Cool Under the Weird';
  return 'Lost & Laughing';
}

// ============================================================
// Circle bubble row — click to fill/unfill
// ============================================================
function Bubbles({ count, value, max, onChange, size }) {
  const sz = size || 'md';
  const bubbles = [];
  for (let i = 1; i <= count; i++) {
    const filled = i <= value;
    bubbles.push(
      <button
        key={i}
        type="button"
        className={`bubble bubble--${sz} ${filled ? 'is-filled' : ''}`}
        aria-label={`${i} of ${count}`}
        onClick={() => {
          if (!onChange) return;
          // Click on already-last-filled = clear it; otherwise set to i
          if (i === value) onChange(i - 1);
          else onChange(i);
        }}
      />
    );
  }
  return <div className={`bubbles bubbles--${sz}`}>{bubbles}</div>;
}

// ============================================================
// Underlined fillable line — looks printed
// ============================================================
function UnderLine({ value, onChange, placeholder, size, width }) {
  return (
    <input
      type="text"
      className={`underline ${size === 'lg' ? 'underline--lg' : ''} ${size === 'italic' ? 'underline--italic' : ''}`}
      style={width ? { width } : null}
      value={value || ''}
      placeholder={placeholder || ''}
      onChange={(e) => onChange && onChange(e.target.value)}
      readOnly={!onChange}
    />
  );
}

// A column of underlined text lines (used by Rituals, Strange Ability, Inventory, Notes)
function LineBlock({ value, onChange, lines }) {
  // Split value into N lines; pad to `lines` rows
  const parts = (value || '').split('\n');
  while (parts.length < lines) parts.push('');

  const set = (i, v) => {
    const next = [...parts];
    next[i] = v;
    // trim trailing empty rows when serializing but keep array length here
    const serialized = next.join('\n').replace(/\n+$/, '');
    onChange(serialized);
  };

  return (
    <div className="lineblock">
      {parts.slice(0, lines).map((p, i) => (
        <input
          key={i}
          type="text"
          className="lineblock__line"
          value={p}
          onChange={(e) => set(i, e.target.value)}
        />
      ))}
    </div>
  );
}

// ============================================================
// Weapons rows — name underline + small damage box
// ============================================================
function WeaponsBlock({ value, onChange, rows: rowCount }) {
  const lines = (value || '').split('\n');
  const rows = lines.map((l) => {
    const [name = '', damage = ''] = l.split('|').map((s) => s.trim());
    return { name, damage };
  });
  while (rows.length < rowCount) rows.push({ name: '', damage: '' });

  const update = (i, key, v) => {
    const next = rows.map((r, idx) => (idx === i ? { ...r, [key]: v } : r));
    const serialized = next
      .map((r) => (r.name || r.damage) ? `${r.name}${r.damage ? ' | ' + r.damage : ''}` : '')
      .join('\n')
      .replace(/\n+$/, '');
    onChange(serialized);
  };

  return (
    <div className="weapons-block">
      {rows.slice(0, rowCount).map((r, i) => (
        <div className="weapons-block__row" key={i}>
          <input
            type="text"
            className="underline"
            value={r.name}
            onChange={(e) => update(i, 'name', e.target.value)}
          />
          <input
            type="text"
            className="weapons-block__dmg"
            value={r.damage}
            onChange={(e) => update(i, 'damage', e.target.value)}
          />
        </div>
      ))}
    </div>
  );
}

// ============================================================
// MAIN SHEET
// ============================================================
function CharacterSheet({ char, bonuses, stationRemark, setChar, onBack, onSave, onPrint, onReset }) {
  const grit = char.attrs.grit + (bonuses.attr.grit || 0);
  const wit = char.attrs.wit + (bonuses.attr.wit || 0);
  const strangeness = char.attrs.strangeness + (bonuses.attr.strangeness || 0);
  const maxHp = 10 + grit;
  const sanity = char.sanity != null ? char.sanity : 6;
  const absurdity = char.absurdity != null ? char.absurdity : 0;
  const currentHealth = char.currentHealth != null ? char.currentHealth : maxHp;

  const skillVal = (key) => (char.skills[key] || 0) + (bonuses.skills[key] || 0);
  const state = mentalState(sanity, absurdity);

  // Specialty text per skill (for the colon-line after each skill name)
  const specialtyFor = (skillKey) => {
    if (char.specialty?.skill === skillKey) return char.specialty.name || '';
    return '';
  };
  const setSpecialty = (skillKey, name) => {
    setChar({ specialty: { skill: skillKey, name } });
  };

  return (
    <React.Fragment>
      <article className="oh-sheet" data-screen-label="07 Character Sheet">

        {/* ===== Top row: ODD HOURS logo + Employee Name | Background + Appearance ===== */}
        <header className="oh-sheet__header">
          <div className="oh-sheet__logo-name">
            <div className="oh-logo">
              <div className="oh-logo__odd">ODD</div>
              <div className="oh-logo__hours">HOURS</div>
            </div>
            <div className="oh-sheet__name-wrap">
              <span className="oh-sheet__name-label">Employee Name:</span>
              <input
                type="text"
                className="oh-sheet__name-input"
                value={char.name || ''}
                onChange={(e) => setChar({ name: e.target.value })}
              />
            </div>
          </div>

          <div className="oh-sheet__bg-app">
            <div className="oh-sheet__bg-row">
              <span className="oh-label">BACKGROUND:</span>
              <input
                type="text"
                className="underline"
                value={getBackgroundLabel(char)}
                readOnly={char.background !== 'custom'}
                onChange={(e) => char.background === 'custom' && setChar({ customBackgroundName: e.target.value })}
              />
            </div>
            <div className="oh-sheet__app-row">
              <span className="oh-label">APPEARANCE:</span>
              <LineBlock
                value={char.appearance}
                onChange={(v) => setChar({ appearance: v })}
                lines={2}
              />
            </div>
          </div>
        </header>

        {/* ===== Body: two columns ===== */}
        <div className="oh-sheet__body">

          {/* ---------- LEFT COLUMN ---------- */}
          <div className="oh-col oh-col--left">

            {/* ATTRIBUTES */}
            <section className="oh-block">
              <h2 className="oh-block__title">ATTRIBUTES:</h2>
              {ATTRIBUTES.map((attr) => {
                const value = char.attrs[attr.key] + (bonuses.attr[attr.key] || 0);
                return (
                  <div className="oh-stat-row oh-stat-row--centered" key={attr.key}>
                    <div className="oh-stat-row__name">{attr.name.toUpperCase()}:</div>
                    <Bubbles
                      count={6}
                      value={value}
                      onChange={(v) => {
                        // Edit raw value; bonus stays
                        const newRaw = Math.max(1, v - (bonuses.attr[attr.key] || 0));
                        setChar({ attrs: { ...char.attrs, [attr.key]: newRaw } });
                      }}
                    />
                  </div>
                );
              })}
            </section>

            {/* SKILLS */}
            <section className="oh-block">
              <h2 className="oh-block__title">
                SKILLS <span className="oh-block__title-sub">(&amp; SPECIALITIES):</span>
              </h2>
              {SKILLS.map((s) => {
                const v = skillVal(s.key);
                return (
                  <div className="oh-skill-row" key={s.key}>
                    <div className="oh-skill-row__name-line">
                      <span className="oh-skill-row__name">{s.name}:</span>
                      <input
                        type="text"
                        className="underline underline--italic"
                        value={specialtyFor(s.key)}
                        onChange={(e) => setSpecialty(s.key, e.target.value)}
                        placeholder=""
                      />
                    </div>
                    <Bubbles
                      count={5}
                      value={v}
                      onChange={(newV) => {
                        const newRaw = Math.max(0, newV - (bonuses.skills[s.key] || 0));
                        setChar({ skills: { ...char.skills, [s.key]: newRaw } });
                      }}
                    />
                  </div>
                );
              })}
            </section>

            {/* RITUALS */}
            <section className="oh-block">
              <div className="oh-line-section">
                <span className="oh-label">RITUALS:</span>
                <LineBlock
                  value={
                    char.rituals != null
                      ? char.rituals
                      : (strangeness >= 3
                        ? COMMON_RITUALS.slice(0, Math.min(strangeness - 1, COMMON_RITUALS.length)).map((r) => r.name).join('\n')
                        : '')
                  }
                  onChange={(v) => setChar({ rituals: v })}
                  lines={6}
                />
              </div>
            </section>

            {/* STRANGE ABILITY */}
            <section className="oh-block">
              <div className="oh-line-section">
                <span className="oh-label">STRANGE ABILITY:</span>
                <LineBlock
                  value={char.strangeAbility || ''}
                  onChange={(v) => setChar({ strangeAbility: v })}
                  lines={2}
                />
              </div>
            </section>

          </div>

          {/* ---------- RIGHT COLUMN ---------- */}
          <div className="oh-col oh-col--right">

            {/* HEALTH boxes */}
            <section className="oh-block">
              <h2 className="oh-block__title oh-block__title--inline">HEALTH:</h2>
              <div className="oh-health-boxes">
                <div className="oh-stat-box">
                  <input
                    type="text"
                    inputMode="numeric"
                    className="oh-stat-box__value"
                    value={currentHealth}
                    onChange={(e) => setChar({ currentHealth: clampInt(e.target.value, 0, 999) })}
                  />
                  <div className="oh-stat-box__label">CURRENT<br />HEALTH</div>
                </div>
                <div className="oh-stat-box">
                  <div className="oh-stat-box__value oh-stat-box__value--ro">{maxHp}</div>
                  <div className="oh-stat-box__label">MAXIMUM<br />HEALTH</div>
                </div>
              </div>
            </section>

            {/* INITIATIVE MODIFIER */}
            <section className="oh-block">
              <div className="oh-init-row">
                <span className="oh-label">INITIATIVE MODIFIER:</span>
                <div className="oh-init-box">+{grit}</div>
              </div>
            </section>

            {/* MENTAL STATE */}
            <section className="oh-block">
              <h2 className="oh-block__title oh-block__title--inline">MENTAL STATE:</h2>
              <div className="oh-mental-state">{state}</div>
            </section>

            {/* SANITY POINTS — 8 bubbles */}
            <section className="oh-block">
              <div className="oh-points-row">
                <span className="oh-label">SANITY POINTS:</span>
                <Bubbles
                  count={8}
                  value={sanity}
                  onChange={(v) => setChar({ sanity: clampInt(v, 0, 8) })}
                />
              </div>
            </section>

            {/* ABSURDITY POINTS — 10 bubbles */}
            <section className="oh-block">
              <div className="oh-points-row">
                <span className="oh-label">ABSURDITY POINTS:</span>
                <Bubbles
                  count={10}
                  value={absurdity}
                  onChange={(v) => setChar({ absurdity: clampInt(v, 0, 10) })}
                  size="sm"
                />
              </div>
            </section>

            {/* WEAPONS */}
            <section className="oh-block">
              <div className="oh-weapons-head">
                <span className="oh-label">WEAPONS:</span>
                <span className="oh-label oh-label--sm">(DAMAGE)</span>
              </div>
              <WeaponsBlock
                value={char.weapons}
                onChange={(v) => setChar({ weapons: v })}
                rows={4}
              />
            </section>

            {/* INVENTORY */}
            <section className="oh-block">
              <div className="oh-line-section">
                <span className="oh-label">INVENTORY:</span>
                <LineBlock
                  value={char.inventory}
                  onChange={(v) => setChar({ inventory: v })}
                  lines={6}
                />
              </div>
            </section>

            {/* NOTES */}
            <section className="oh-block">
              <div className="oh-line-section">
                <span className="oh-label">NOTES:</span>
                <LineBlock
                  value={char.notes || ''}
                  onChange={(v) => setChar({ notes: v })}
                  lines={5}
                />
              </div>
            </section>

          </div>
        </div>

        {/* ===== Easter-egg footer (screen only) ===== */}
        {stationRemark && (
          <div className="oh-sheet__footer-egg">
            <span className="oh-sheet__footer-egg-label">Filed From Last Shift — Station Use Only</span>
            <span className="oh-sheet__footer-egg-text">{stationRemark}</span>
          </div>
        )}

      </article>

      <div className="sheet__actions">
        <button className="btn btn--ghost-dark" onClick={onBack}>← Edit</button>
        <button className="btn btn--ghost-dark" onClick={onSave}>Save to Browser</button>
        <button className="btn btn--primary" onClick={onPrint}>Print / Save PDF</button>
        <button className="btn btn--ghost-dark" onClick={onReset}>New Character</button>
      </div>
    </React.Fragment>
  );
}

function clampInt(v, min, max) {
  const n = parseInt(v, 10);
  if (isNaN(n)) return min;
  return Math.max(min, Math.min(max, n));
}

Object.assign(window, { CharacterSheet, mentalState });

})();
