// ============================================================
// SCREEN 2 · COMBAT (priority — most-used in session)
// ============================================================

const DND_ACTIONS = [
  { type: 'action',   name: 'Атака',                desc: 'Одна чи більше атак зброєю або без неї' },
  { type: 'action',   name: 'Ривок',                desc: 'Швидкість руху подвоюється цього ходу' },
  { type: 'action',   name: 'Вивільнення',           desc: 'Рух не провокує атаки можливості' },
  { type: 'action',   name: 'Ухилення',              desc: 'Атаки по тобі з перешкодою; Dex-ряткуби з перевагою' },
  { type: 'action',   name: 'Допомога',              desc: 'Союзник отримує перевагу на атаку або перевірку' },
  { type: 'action',   name: 'Сховатися',             desc: 'Перевірка Непомітності — стаєш схованим' },
  { type: 'action',   name: 'Готовність',            desc: 'Обери тригер і дію, виконай як реакцію' },
  { type: 'action',   name: 'Пошук',                 desc: 'Перевірка Уважності або Розслідування' },
  { type: 'action',   name: 'Використати предмет',   desc: 'Активувати предмет, випити зілля тощо' },
  { type: 'action',   name: 'Кинути заклинання',     desc: 'Закляття з часом каста «1 дія»' },
  { type: 'bonus',    name: 'Друга атака',            desc: 'Two-Weapon Fighting: удар другою легкою зброєю' },
  { type: 'bonus',    name: 'Кинути заклинання',     desc: 'Закляття з часом каста «бонусна дія»' },
  { type: 'bonus',    name: 'Здібність класу',       desc: 'Кунінг-Екшн, Бойовий дух, Рвучкий удар тощо' },
  { type: 'reaction', name: 'Атака можливості',      desc: 'Ворог залишає зону досяжності без Вивільнення' },
  { type: 'reaction', name: 'Закляття-реакція',      desc: 'Shield, Counterspell та ін. — при тригері' },
  { type: 'free',     name: 'Спілкування',           desc: 'Кілька слів або коротка фраза' },
  { type: 'free',     name: 'Опустити предмет',      desc: 'Відпустити щось із рук' },
  { type: 'free',     name: 'Взаємодія з предметом', desc: 'Одна взаємодія: відчинити двері, дістати зілля' },
];

const DND_ACTION_TYPES = {
  action:   { label: 'ДІЯ',     fg: 'var(--gold-1)' },
  bonus:    { label: 'БОНУС',   fg: 'var(--azure-1)' },
  reaction: { label: 'РЕАКЦІЯ', fg: 'var(--violet-1)' },
  free:     { label: 'ВІЛЬНА',  fg: 'var(--ink-3)' },
};

const ScreenCombat = ({ ch, setCh, allChars }) => {
  const { push } = useToast();
  if (!ch) return null;
  const [hpDelta, setHpDelta] = useState(1);
  const [hpSet, setHpSet] = useState('');
  const [concInput, setConcInput] = useState('');
  const [addAttackOpen, setAddAttackOpen] = useState(false);

  // Бойовий стан — зберігається у ch щоб не скидатись при навігації між екранами
  const _cs = ch.combatState || {};
  const concSpell       = _cs.concSpell ?? null;
  const round           = _cs.round ?? 1;
  const activeInitName  = typeof _cs.activeInitName === 'string' ? _cs.activeInitName : null;
  const extraInit       = Array.isArray(_cs.extraInit) ? _cs.extraInit : [];
  const playerRolledInit = _cs.playerRolledInit ?? null;
  const _setCS = (updater) => setCh(c => ({
    ...c,
    combatState: typeof updater === 'function'
      ? updater(c.combatState || { concSpell: null, round: 1, activeInit: 0, extraInit: [], playerRolledInit: null })
      : { ...(c.combatState || {}), ...updater },
  }));
  const setConcSpell       = (v) => _setCS(s => ({ ...s, concSpell:        typeof v === 'function' ? v(s.concSpell)        : v }));
  const setRound           = (v) => _setCS(s => ({ ...s, round:            typeof v === 'function' ? v(s.round)            : v }));
  const setActiveInitName  = (v) => _setCS(s => ({ ...s, activeInitName:   typeof v === 'function' ? v(s.activeInitName)   : v }));
  const setExtraInit       = (v) => _setCS(s => ({ ...s, extraInit:        typeof v === 'function' ? v(s.extraInit)        : v }));
  const setPlayerRolledInit = (v) => _setCS(s => ({ ...s, playerRolledInit: typeof v === 'function' ? v(s.playerRolledInit) : v }));
  const [newAtk, setNewAtk] = useState({ name: '', bonus: 0, dice: '1d6', type: 'к', note: '', actionType: 'action' });
  const [addNPCOpen, setAddNPCOpen] = useState(false);
  const [npcDraft, setNpcDraft] = useState({ name: '', init: 0, hp: 0, enemy: false });
  const [canDoOnly, setCanDoOnly] = useState(false);

  // ── Spell slots & prepared spells (mirrors ScreenSpells logic) ──
  const _defaultSlots = useMemo(() =>
    SPELLS_GROUPED.reduce((acc, g) => { if (g.slots) acc[g.level] = { ...g.slots }; return acc; }, {}),
  []);
  const slots = (ch.spellSlots && Object.keys(ch.spellSlots).length) ? ch.spellSlots : _defaultSlots;
  const setSlots = (updater) => setCh(c => ({
    ...c,
    spellSlots: typeof updater === 'function'
      ? updater((c.spellSlots && Object.keys(c.spellSlots).length) ? c.spellSlots : _defaultSlots)
      : updater,
  }));
  const toggleSlot = (level, idx) => {
    setSlots(s => {
      const cur = s[level];
      const newUsed = idx < (cur.total - cur.used) ? cur.used + 1 : cur.used - 1;
      return { ...s, [level]: { ...cur, used: Math.max(0, Math.min(cur.total, newUsed)) } };
    });
  };
  const domainSlots = ch.domainSlots || {};
  const setDomainSlots = (updater) => setCh(c => ({
    ...c,
    domainSlots: typeof updater === 'function' ? updater(c.domainSlots || {}) : updater,
  }));
  const hasMagic = SPELLS_GROUPED.length > 0 || (ch.customSpells || []).length > 0;
  const preparedSpells = [
    ...SPELLS_GROUPED.flatMap(g =>
      g.spells.filter(s => s.prepared || g.level === 0).map(s => ({ ...s, level: g.level }))),
    ...(ch.customSpells || []).map(s => ({ ...s })),
  ];

  const applyDamage = () => {
    // обчислити результат синхронно, щоб тост показував правильні значення
    let dmgAfterTemp = hpDelta;
    let tempAfter = ch.hpTemp;
    if (tempAfter > 0) {
      const absorb = Math.min(tempAfter, dmgAfterTemp);
      tempAfter -= absorb;
      dmgAfterTemp -= absorb;
    }
    const hpAfter = Math.max(0, ch.hp - dmgAfterTemp);
    setCh(c => {
      let d = hpDelta, t = c.hpTemp;
      if (t > 0) { const a = Math.min(t, d); t -= a; d -= a; }
      return { ...c, hp: Math.max(0, c.hp - d), hpTemp: t };
    });
    const detail = ch.hpTemp > 0
      ? `HP ${ch.hp} → ${hpAfter} · тимч. ${ch.hpTemp} → ${tempAfter}`
      : `HP ${ch.hp} → ${hpAfter}`;
    setHpDelta(1);
    push({ icon: 'heart', label: 'Дамаг', value: `−${hpDelta}`, detail });
    if (concSpell) {
      const dc = Math.max(10, Math.floor(hpDelta / 2));
      push({ icon: 'rune', label: `⚠ Концентрація: ${concSpell}`, detail: `Ряткуб КОН ≥ ${dc}` });
    }
  };
  const applyHeal = () => {
    setCh(c => ({
      ...c,
      hp: Math.min(c.hpMax, c.hp + hpDelta),
      deathSuccess: 0,
      deathFail: 0,
    }));
    setHpDelta(1);
    push({ icon: 'heart', label: 'Лікування', value: `+${hpDelta}` });
  };
  const applyTemp = () => {
    setCh(c => ({ ...c, hpTemp: Math.max(c.hpTemp, hpDelta) }));
    setHpDelta(1);
    push({ label: 'Тимч. HP', value: `+${hpDelta}` });
  };

  const rollAttack = (a) => {
    const r = rollDie(20);
    const total = r + (a.bonus || 0);
    const crit = r === 20;
    push({ icon: 'sword', label: `${a.name}`, value: total, detail: `d20[${r}] +${a.bonus} → vs КЗ`, crit });
  };
  const rollDamage = (a) => {
    const match = (a.dice || '').match(/^(\d+)d(\d+)([+-]\d+)?/i);
    if (match) {
      const count = parseInt(match[1], 10);
      const sides = parseInt(match[2], 10);
      const bonus = parseInt(match[3] || '0', 10);
      const rolls = rollDice(count, sides);
      const total = rolls.reduce((s, v) => s + v, 0) + bonus;
      push({ icon: 'flame', label: `${a.name} (дамаг)`, value: total,
        detail: `[${rolls.join('+')}]${bonus ? (bonus > 0 ? '+' : '') + bonus : ''} · ${a.type}` });
    } else {
      push({ icon: 'flame', label: `${a.name} (дамаг)`, value: a.dice, detail: a.type });
    }
  };

  const hpPct = Math.min(100, Math.max(0, (ch.hp / ch.hpMax) * 100));
  const ringCirc = 2 * Math.PI * 76;
  const ringOffset = ringCirc * (1 - Math.min(1, Math.max(0, ch.hp / ch.hpMax)));

  const playerBadges = [];
  if (concSpell) playerBadges.push({ k: 'conc', label: 'Конц', tip: `Концентрація: ${concSpell}`, icon: 'rune' });
  if (ch.inspiration) playerBadges.push({ k: 'insp', label: 'Натх', tip: 'Натхнення', icon: 'star' });
  const allInitiatives = [
    { name: ch.name + ' (ви)', init: playerRolledInit ?? ch.initiative, you: true, hp: `${ch.hp}/${ch.hpMax}`, badges: playerBadges },
    ...extraInit,
  ];
  const sortedInitiatives = [...allInitiatives].sort((a, b) => b.init - a.init);
  const effectiveActiveName = activeInitName ?? sortedInitiatives[0]?.name ?? null;

  return (
    <>
      <SectionHeader
        title="Бій"
        eyebrow={`раунд ${round} · ваш хід`}
        action={
          <div className="flex ig-6">
            <Btn ghost sm onClick={() => {
              if (!window.confirm('Тривалий відпочинок? HP, слоти та стани будуть відновлені.')) return;
              setCh(c => ({ ...c, hp: c.hpMax, hpTemp: 0, deathSuccess: 0, deathFail: 0, conditions: {}, actionUsed: { action: false, bonus: false, reaction: false }, hitDiceUsed: 0, featureCharges: {},
                spellSlots: Object.fromEntries(Object.entries(c.spellSlots || {}).map(([l, v]) => [l, { ...v, used: 0 }])),
                domainSlots: Object.fromEntries(Object.entries(c.domainSlots || {}).map(([t, v]) => [t, { ...v, used: 0 }])),
                combatState: { ...(c.combatState || {}), concSpell: null, round: 1, activeInitName: null, extraInit: [], playerRolledInit: null },
              }));
              push({ icon: 'sun', label: 'Тривалий відпочинок', detail: 'HP, слоти, доменні слоти, здібності та стани очищено' });
            }}>
              <Icon name="sun" size={12}/> Long rest
            </Btn>
            <Btn primary sm onClick={() => {
              setCh(c => ({ ...c, actionUsed: { action: false, bonus: false, reaction: false } }));
              setRound(r => r + 1);
              setActiveInitName(null);
              push({ icon: 'hourglass', label: `Новий раунд: ${round + 1}` });
            }}>
              <Icon name="arrowR" size={12}/> Новий раунд
            </Btn>
          </div>
        }
      />

      <div className="combat-grid">
        {/* === LEFT COLUMN === */}
        <div className="icol ig-16">
          {/* HP RING + Controls */}
          <Card title="Здоров'я" tag="кільце — поточне HP">
            <div className="hp-ring-card" style={{ padding: 0 }}>
              <div className="hp-ring">
                <svg viewBox="0 0 180 180">
                  <circle cx="90" cy="90" r="76" fill="none" strokeWidth="10" className="hp-ring-track"/>
                  <circle cx="90" cy="90" r="76" fill="none" strokeWidth="10" strokeLinecap="round"
                    className={`hp-ring-fill ${hpPct < 30 ? 'low' : ''}`}
                    strokeDasharray={ringCirc}
                    strokeDashoffset={ringOffset}
                  />
                </svg>
                <div className="hp-ring-inner">
                  <div className="hp-ring-num">{ch.hp}</div>
                  <div className="hp-ring-max">/ {ch.hpMax} HP</div>
                  {ch.hpTemp > 0 && <div className="hp-ring-temp">+{ch.hpTemp} тимч</div>}
                </div>
              </div>

              <div className="hp-controls">
                <div className="hp-input-row">
                  <div className="hp-amount">
                    <input type="number" value={hpDelta} onChange={(e) => setHpDelta(Math.max(0, Number(e.target.value) || 0))} min="0"/>
                    <div className="quick">
                      <button onClick={() => setHpDelta(1)}>1</button>
                      <button onClick={() => setHpDelta(5)}>5</button>
                      <button onClick={() => setHpDelta(10)}>10</button>
                    </div>
                  </div>
                </div>
                <div className="hp-action-row">
                  <Btn danger onClick={applyDamage}><Icon name="minus" size={12}/> Дамаг</Btn>
                  <Btn heal onClick={applyHeal}><Icon name="plus" size={12}/> Лікувати</Btn>
                </div>
                <Btn ghost sm onClick={applyTemp}><Icon name="shield" size={11}/> Дати тимч. HP</Btn>

                <div className="flex ig-4 ica" style={{ marginTop: 4 }}>
                  <input className="input" type="number" min="0" max={ch.hpMax} placeholder={`= HP`}
                    style={{ width: 64, height: 26, padding: '1px 6px', fontSize: 12, textAlign: 'center' }}
                    value={hpSet} onChange={e => setHpSet(e.target.value)}
                    onKeyDown={e => { if (e.key === 'Enter' && hpSet !== '') {
                      const v = Math.max(0, Math.min(ch.hpMax, Number(hpSet) || 0));
                      setCh(c => ({ ...c, hp: v }));
                      push({ icon: 'heart', label: 'HP встановлено', value: v });
                      setHpSet('');
                    }}}/>
                  <Btn sm ghost style={{ flex: 1 }} onClick={() => {
                    if (hpSet === '') return;
                    const v = Math.max(0, Math.min(ch.hpMax, Number(hpSet) || 0));
                    setCh(c => ({ ...c, hp: v }));
                    push({ icon: 'heart', label: 'HP встановлено', value: v });
                    setHpSet('');
                  }}>= Встановити</Btn>
                </div>

                <div className="hp-misc-row">
                  <div className="hp-misc-tile">
                    <div className="k">Hit Dice</div>
                    <div className="v">{ch.hitDiceTotal - ch.hitDiceUsed}/{ch.hitDiceTotal}<span style={{ fontSize: 11, color: 'var(--ink-3)' }}> d{ch.hitDie}</span></div>
                  </div>
                  <div className="hp-misc-tile" data-tooltip={`броня + інші бонуси = ${ch.ac}`}>
                    <div className="k">КЗ</div>
                    <div className="v">{ch.ac}</div>
                  </div>
                  <div className="hp-misc-tile" data-tooltip={`мод DEX = ${fmtMod(Math.floor(((ch.abilityScores?.DEX ?? 10)-10)/2))}`}>
                    <div className="k">Ініціатива</div>
                    <div className="v" style={{ color: 'var(--azure-1)' }}>{fmtMod(ch.initiative)}</div>
                  </div>
                </div>
              </div>
            </div>

            {/* Death saves — only show if HP = 0 OR by default for awareness */}
            {(ch.hp === 0 || ch.deathFail > 0 || ch.deathSuccess > 0) && (
              <div className="death-row mt-12">
                <div className="death-group">
                  <Icon name="check" size={14} style={{ color: 'var(--emerald-1)' }}/>
                  <span className="death-label">Успіх</span>
                  {[0,1,2].map(i => (
                    <Dot key={i} color="emerald" on={i < ch.deathSuccess}
                      onClick={() => {
                        const next = i + 1 === ch.deathSuccess ? 0 : i + 1;
                        if (next >= 3) {
                          setCh(c => ({ ...c, deathSuccess: 0, deathFail: 0 }));
                          push({ icon: 'check', label: '✦ Стабілізовано!', detail: '3 успіхи — персонаж вижив (HP 0)', crit: true });
                        } else {
                          setCh(c => ({ ...c, deathSuccess: next }));
                        }
                      }}/>
                  ))}
                </div>
                <div style={{ width: 1, height: 18, background: 'var(--line-1)' }}/>
                <div className="death-group">
                  <Icon name="x" size={14} style={{ color: 'var(--crimson-1)' }}/>
                  <span className="death-label">Провал</span>
                  {[0,1,2].map(i => (
                    <Dot key={i} color="crimson" on={i < ch.deathFail}
                      onClick={() => {
                        const next = i + 1 === ch.deathFail ? 0 : i + 1;
                        if (next >= 3) {
                          setCh(c => ({ ...c, deathFail: 3 }));
                          push({ icon: 'x', label: '💀 Персонаж загинув', detail: '3 провали' });
                        } else {
                          setCh(c => ({ ...c, deathFail: next }));
                        }
                      }}/>
                  ))}
                </div>
                <div className="igrow"/>
                <Btn sm onClick={() => {
                  const r = rollDie(20);
                  if (r === 20) {
                    setCh(c => ({ ...c, hp: 1, deathSuccess: 0, deathFail: 0 }));
                    push({ icon: 'heart', label: 'Death save', value: 20, detail: '★ ВСТАЄШ З 1 HP', crit: true });
                  } else if (r >= 10) {
                    const newSuccess = Math.min(3, ch.deathSuccess + 1);
                    if (newSuccess >= 3) {
                      setCh(c => ({ ...c, deathSuccess: 0, deathFail: 0 }));
                      push({ icon: 'check', label: '✦ Стабілізовано!', value: r, detail: '3 успіхи — персонаж вижив (HP 0)', crit: true });
                    } else {
                      setCh(c => ({ ...c, deathSuccess: newSuccess }));
                      push({ icon: 'check', label: 'Death save', value: r, detail: `успіх ${newSuccess}/3` });
                    }
                  } else if (r === 1) {
                    const newFail = Math.min(3, ch.deathFail + 2);
                    setCh(c => ({ ...c, deathFail: newFail }));
                    if (newFail >= 3) push({ icon: 'x', label: '💀 Персонаж загинув', value: 1, detail: '3 провали' });
                    else push({ icon: 'x', label: 'Death save', value: 1, detail: `−2 провали (${newFail}/3)` });
                  } else {
                    const newFail = Math.min(3, ch.deathFail + 1);
                    setCh(c => ({ ...c, deathFail: newFail }));
                    if (newFail >= 3) push({ icon: 'x', label: '💀 Персонаж загинув', value: r, detail: '3 провали' });
                    else push({ icon: 'x', label: 'Death save', value: r, detail: `провал ${newFail}/3` });
                  }
                }}>Кинути</Btn>
              </div>
            )}
          </Card>

          {/* Attacks table */}
          <Card title="Атаки та закляття-атаки" tag="клік → ролл"
            action={
              <div className="flex ig-6 ica">
                <Chip active={canDoOnly} onClick={() => setCanDoOnly(v => !v)} title="Тільки атаки, доступні зараз">
                  <Icon name="bolt" size={10}/> Що я можу?
                </Chip>
                <Btn ghost sm onClick={() => setAddAttackOpen(true)}><Icon name="plus" size={11}/> атака</Btn>
              </div>
            }>
            {canDoOnly && (
              <div className="filter-banner mb-12">
                <Icon name="bolt" size={12}/>
                <span>Тільки атаки, доступні <b>зараз</b>. Натисни щоб переключити:</span>
                <span className="igrow"/>
                <div className="flex ig-6">
                  {[
                    { key: 'action',   label: 'Дія' },
                    { key: 'bonus',    label: 'Бонус' },
                    { key: 'reaction', label: 'Реакція' },
                  ].map(({ key, label }) => {
                    const used = ch.actionUsed?.[key];
                    return (
                      <Chip key={key} sm fill={!used} muted={used}
                        onClick={() => setCh(c => ({
                          ...c,
                          actionUsed: { ...(c.actionUsed || {}), [key]: !(c.actionUsed?.[key]) },
                        }))}>
                        {used ? '✗' : '✓'} {label}
                      </Chip>
                    );
                  })}
                </div>
              </div>
            )}
            <div className="attacks-row head">
              <div>Назва</div><div>Бонус</div><div>Куб</div><div>Тип</div><div>Деталі</div><div></div>
            </div>
            {(() => {
              const allAttacks = [...ATTACKS, ...(ch.customAttacks || [])];
              const visible = allAttacks
                .map((a, globalIdx) => ({ a, globalIdx }))
                .filter(({ a }) => {
                  if (!canDoOnly) return true;
                  const atype = a.actionType || (() => {
                    const note = (a.note || '').toLowerCase();
                    return note.includes('bonus') || note.includes('бонус') ? 'bonus'
                      : note.includes('reaction') || note.includes('реакція') ? 'reaction'
                      : 'action';
                  })();
                  return !(ch.actionUsed?.[atype]);
                });
              if (visible.length === 0 && canDoOnly) return (
                <div className="mono dim" style={{ textAlign: 'center', padding: '14px 0', fontSize: 12 }}>
                  Всі дії вичерпано — натисни «Новий раунд» щоб відновити
                </div>
              );
              return visible.map(({ a, globalIdx }, i) => {
                // Індекс у customAttacks (враховуємо зміщення на ATTACKS.length)
                const customIdx = globalIdx - ATTACKS.length;
                const isCustom = customIdx >= 0;
                return (
                  <div key={i} className="attacks-row">
                    <div className="atk-name">
                      <Icon name={a.dice.includes('d') && (a.note||'').includes('cantrip') ? 'spell' : 'sword'} size={13} style={{ color: 'var(--gold-0)' }}/>
                      {a.name}
                    </div>
                    <div className="atk-bonus">{a.bonus ? fmtMod(a.bonus) : '—'}</div>
                    <div className="atk-dice">{a.dice}</div>
                    <div className="mono" style={{ fontSize: 11, color: 'var(--ink-2)' }}>{a.type}</div>
                    <div className="mono" style={{ fontSize: 11, color: 'var(--ink-3)' }}>{a.note}</div>
                    <div className="flex ig-4" style={{ justifyContent: 'flex-end' }}>
                      {a.bonus !== null && <Btn sm onClick={() => rollAttack(a)}>атака</Btn>}
                      <Btn sm danger onClick={() => rollDamage(a)}>дамаг</Btn>
                      {isCustom && <IconBtn name="trash" size={12} title="Видалити атаку" onClick={() => {
                        setCh(c => ({ ...c, customAttacks: (c.customAttacks || []).filter((_, j) => j !== customIdx) }));
                        push({ label: `Видалено: ${a.name}` });
                      }}/>}
                    </div>
                  </div>
                );
              });
            })()}
          </Card>

          {/* ── Clickable D&D Actions ── */}
          <Card title="Дії D&D" tag="клік → використати"
            action={
              <Chip active={canDoOnly} onClick={() => setCanDoOnly(v => !v)} title="Тільки доступні дії">
                <Icon name="bolt" size={10}/> Що я можу?
              </Chip>
            }>
            {DND_ACTIONS.filter(a => {
              if (!canDoOnly) return true;
              if (a.type === 'free') return true;
              return !(ch.actionUsed?.[a.type]);
            }).map((a, i) => {
              const info = DND_ACTION_TYPES[a.type];
              const isUsed = a.type !== 'free' && !!(ch.actionUsed?.[a.type]);
              return (
                <div key={i} className="flex ica ig-8" style={{
                  padding: '6px 0',
                  borderBottom: '1px solid var(--line-0)',
                  opacity: isUsed ? 0.35 : 1,
                }}>
                  <span style={{
                    fontSize: 9, fontFamily: 'var(--font-mono)', letterSpacing: 0.8,
                    textTransform: 'uppercase', padding: '2px 6px', borderRadius: 4,
                    border: `1px solid ${info.fg}`, color: info.fg,
                    flexShrink: 0, minWidth: 54, textAlign: 'center',
                  }}>
                    {info.label}
                  </span>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, fontWeight: 500, color: 'var(--ink-1)' }}>{a.name}</div>
                    <div style={{ fontSize: 10, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)' }}>{a.desc}</div>
                  </div>
                  <Btn sm disabled={isUsed} onClick={() => {
                    if (a.type !== 'free') {
                      setCh(c => ({ ...c, actionUsed: { ...(c.actionUsed || {}), [a.type]: true } }));
                    }
                    push({ icon: 'check', label: a.name,
                      detail: a.type === 'free'     ? 'Вільна дія' :
                              a.type === 'action'   ? 'Дію витрачено' :
                              a.type === 'bonus'    ? 'Бонусну дію витрачено' :
                                                     'Реакцію витрачено' });
                  }}>
                    {a.type === 'free' ? 'вільна' : 'вик.'}
                  </Btn>
                </div>
              );
            })}
          </Card>
        </div>

        {/* === RIGHT COLUMN === */}
        <div className="icol ig-16">
          {/* Initiative tracker */}
          <Card title="Турн-трекер" tag={`раунд ${round}`}
            action={
              <div className="flex ig-4">
                <Btn ghost sm onClick={() => setAddNPCOpen(true)}><Icon name="plus" size={11}/> NPC</Btn>
                <Btn sm onClick={() => { setRound(1); setActiveInitName(null); setPlayerRolledInit(null); }}>скинути</Btn>
              </div>
            }>
            <div className="mb-12 flex ig-6">
              <Btn primary sm onClick={() => {
                const r = rollDie(20);
                const total = r + ch.initiative;
                setPlayerRolledInit(total);
                push({ icon: 'bolt', label: 'Ініціатива', value: total, detail: `d20[${r}] ${fmtMod(ch.initiative)}` });
              }}><Icon name="dice" size={11}/> Кинути ініціативу</Btn>
              <Btn ghost sm onClick={() => {
                const curIdx = sortedInitiatives.findIndex(p => p.name === effectiveActiveName);
                const nextIdx = (curIdx + 1) % Math.max(1, sortedInitiatives.length);
                if (nextIdx === 0) setRound(r => r + 1);
                setActiveInitName(sortedInitiatives[nextIdx]?.name ?? null);
              }}>
                <Icon name="arrowR" size={11}/> наступний
              </Btn>
            </div>
            {sortedInitiatives.map((p, i) => (
              <div key={i} className={`init-row ${p.name === effectiveActiveName ? 'active' : ''} ${p.enemy ? 'enemy' : ''}`} onClick={() => setActiveInitName(p.name)}>
                <div className="init-num">{p.init}</div>
                <div className="init-name">
                  <div className="flex ica ig-6">
                    <span>{p.name}</span>
                    {p.enemy && <span className="mono" style={{ fontSize: 10, color: 'var(--crimson-1)' }}>ворог</span>}
                    {p.you && <span className="mono" style={{ fontSize: 10, color: 'var(--gold-1)' }}>★ ВИ</span>}
                  </div>
                  {p.badges && p.badges.length > 0 && (
                    <div className="init-badges">
                      {p.badges.map((b, j) => (
                        <span key={j} className={`init-badge ${b.k}`} title={b.tip}>
                          <Icon name={b.icon} size={10}/>
                          <span>{b.label}</span>
                        </span>
                      ))}
                    </div>
                  )}
                </div>
                <div className="flex ica ig-4" onClick={e => e.stopPropagation()}>
                  {!p.you && typeof p.hpMax === 'number' && p.hpMax > 0 ? (
                    <>
                      <Btn sm danger style={{ padding: '1px 6px', fontSize: 11 }} onClick={() =>
                        setExtraInit(es => es.map(e => e === p ? { ...e, hpCur: Math.max(0, (e.hpCur ?? e.hpMax) - 1) } : e))
                      }>−</Btn>
                      <span className="mono" style={{ fontSize: 11, minWidth: 36, textAlign: 'center' }}>
                        {p.hpCur ?? p.hpMax}/{p.hpMax}
                      </span>
                      <Btn sm style={{ padding: '1px 6px', fontSize: 11 }} onClick={() =>
                        setExtraInit(es => es.map(e => e === p ? { ...e, hpCur: Math.min(e.hpMax, (e.hpCur ?? e.hpMax) + 1) } : e))
                      }>+</Btn>
                    </>
                  ) : (
                    <span className="init-hp">{p.hp}</span>
                  )}
                  {!p.you && (
                    <IconBtn name="x" size={11} title="Видалити з трекера"
                      onClick={() => {
                        if (effectiveActiveName === p.name) setActiveInitName(null);
                        setExtraInit(es => es.filter(e => e !== p));
                      }}/>
                  )}
                </div>
              </div>
            ))}
          </Card>

          {/* Concentration */}
          <Card title="Концентрація" tag="↻ авто-перевірка при дамазі">
            {concSpell ? (
              <div className="conc-active">
                <div className="conc-icon"><Icon name="rune" size={18}/></div>
                <div className="igrow">
                  <div className="display" style={{ fontSize: 14, color: 'var(--violet-1)' }}>{concSpell}</div>
                  <div className="mono" style={{ fontSize: 10, color: 'var(--ink-3)' }}>активна концентрація</div>
                </div>
                <Btn sm onClick={() => { setConcSpell(null); push({ icon: 'rune', label: 'Концентрацію розірвано' }); }}>розірвати</Btn>
              </div>
            ) : (
              <>
                <div className="mono" style={{ fontSize: 12, color: 'var(--ink-3)', padding: '8px 0' }}>
                  Немає активної концентрації
                </div>
                <div className="flex ig-6 mt-8">
                  <input className="input" placeholder="Назва закляття…"
                    value={concInput} onChange={e => setConcInput(e.target.value)}
                    onKeyDown={e => {
                      if (e.key === 'Enter' && concInput.trim()) {
                        setConcSpell(concInput.trim());
                        push({ icon: 'rune', label: `Концентрація: ${concInput.trim()}` });
                        setConcInput('');
                      }
                    }}
                    style={{ flex: 1, fontSize: 12 }}/>
                  <Btn sm onClick={() => {
                    if (!concInput.trim()) return;
                    setConcSpell(concInput.trim());
                    push({ icon: 'rune', label: `Концентрація: ${concInput.trim()}` });
                    setConcInput('');
                  }}>Активувати</Btn>
                </div>
              </>
            )}
            <div className="mono mt-8" style={{ fontSize: 10, color: 'var(--ink-3)' }}>
              <Icon name="bolt" size={10}/> При отриманні дамагу — авто-нагадування ряткуба TIL save · DC max(10, ½×дамаг)
            </div>
          </Card>

          {/* Conditions */}
          <Card title="Стани" tag={`активно: ${Object.values(ch.conditions).filter(Boolean).length}`}>
            <div className="conditions-cloud">
              {Object.keys(ch.conditions).filter(k => ch.conditions[k]).map(c => (
                <Chip key={c} fill color={c.includes('Натхнення') ? '' : 'violet'} onClick={() => {
                  setCh(c2 => ({ ...c2, conditions: { ...c2.conditions, [c]: false } }));
                }}>
                  ● {c}
                </Chip>
              ))}
              {CONDITIONS.map(c => (
                <Chip key={c} onClick={() => {
                  setCh(c2 => ({ ...c2, conditions: { ...c2.conditions, [c]: !c2.conditions[c] } }));
                }} active={ch.conditions[c]}>
                  {c}
                </Chip>
              ))}
            </div>
          </Card>

        </div>
      </div>


      {/* ===== MAGIC IN COMBAT ===== */}
      {hasMagic && (
        <div className="mt-16">
          <Card
            title="Магія в бою"
            tag={`${ch.spellAbility} · атака +${ch.spellAttack} · СК ${ch.spellSaveDC}`}>
            <div style={{ display: 'grid', gridTemplateColumns: '220px 1fr', gap: 24, alignItems: 'start' }}>
              {/* Slot tracker */}
              <div>
                <div className="caps mono" style={{ fontSize: 9, color: 'var(--ink-2)', letterSpacing: 1, marginBottom: 8 }}>Слоти заклять · клік → витратити</div>
                {SPELLS_GROUPED.map(g => (
                  <div key={g.level} className="slot-row">
                    <div className="slot-row-label">{g.level === 0 ? 'Трюки' : `Рів. ${g.level}`}</div>
                    <div className="slot-row-dots">
                      {g.level === 0 ? (
                        <span className="display" style={{ fontSize: 16, color: 'var(--violet-1)' }}>∞</span>
                      ) : g.slots ? (
                        Array.from({ length: g.slots.total }).map((_, i) => {
                          const full = i < (g.slots.total - (slots[g.level]?.used || 0));
                          return <Slot key={i} full={full} used={!full} onClick={() => toggleSlot(g.level, i)}/>;
                        })
                      ) : <span className="mono dim">—</span>}
                    </div>
                    {g.slots && (
                      <div className="mono dim" style={{ fontSize: 10 }}>
                        {(slots[g.level]?.total || 0) - (slots[g.level]?.used || 0)}/{slots[g.level]?.total || 0}
                      </div>
                    )}
                  </div>
                ))}
                {Object.keys(domainSlots).length > 0 && (
                  <>
                    <div className="caps mono" style={{ fontSize: 9, color: 'var(--azure-1)', letterSpacing: 1, margin: '10px 0 6px' }}>Доменні слоти</div>
                    {Object.entries(domainSlots).sort(([a], [b]) => +a - +b).map(([tier, slot]) => (
                      <div key={tier} className="slot-row">
                        <div className="slot-row-label" style={{ color: 'var(--azure-1)' }}>Тір {tier}</div>
                        <div className="slot-row-dots">
                          {Array.from({ length: slot.total }).map((_, i) => {
                            const full = i < (slot.total - slot.used);
                            return <Slot key={i} full={full} used={!full} color="azure"
                              onClick={() => setDomainSlots(s => {
                                const cur = s[tier];
                                const newUsed = i < (cur.total - cur.used) ? cur.used + 1 : cur.used - 1;
                                return { ...s, [tier]: { ...cur, used: Math.max(0, Math.min(cur.total, newUsed)) } };
                              })}/>;
                          })}
                        </div>
                        <div className="mono dim" style={{ fontSize: 10 }}>
                          {slot.total - slot.used}/{slot.total}
                        </div>
                      </div>
                    ))}
                  </>
                )}
              </div>
              {/* Prepared spells */}
              <div>
                <div className="caps mono" style={{ fontSize: 9, color: 'var(--ink-2)', letterSpacing: 1, marginBottom: 8 }}>Підготовлені закляття</div>
                {preparedSpells.length === 0 ? (
                  <div style={{ fontSize: 12, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)' }}>Немає підготовлених заклять</div>
                ) : preparedSpells.map((sp, i) => {
                  const spLevel = sp.level ?? 0;
                  const isDomain = sp.desc && sp.desc.includes('[ДОМЕН]');
                  const domainTier = isDomain && spLevel > 0 ? ([9, 7, 5, 3, 1].find(t => spLevel >= t) || 1) : null;
                  const slotsFree = spLevel === 0 ? Infinity
                    : isDomain && domainTier != null
                      ? (domainSlots[domainTier]?.total || 0) - (domainSlots[domainTier]?.used || 0)
                      : (slots[spLevel]?.total || 0) - (slots[spLevel]?.used || 0);
                  const canCast = slotsFree > 0 || spLevel === 0;
                  return (
                    <div key={i} className="flex ica ig-8" style={{
                      padding: '5px 0',
                      borderBottom: '1px solid var(--line-0)',
                      opacity: canCast ? 1 : 0.45,
                    }}>
                      <Icon name="spell" size={12} style={{ color: isDomain ? 'var(--azure-1)' : 'var(--violet-1)', flexShrink: 0 }}/>
                      <span style={{ fontSize: 13, flex: 1 }}>{sp.name}</span>
                      <span style={{ fontSize: 10, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)' }}>
                        {spLevel === 0 ? 'трюк' : isDomain ? `домен т.${domainTier}` : `рів.${spLevel}`}
                      </span>
                      {sp.school && (
                        <span style={{ fontSize: 10, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)', width: 80, textAlign: 'right' }}>{sp.school}</span>
                      )}
                      <Btn sm disabled={!canCast} onClick={() => {
                        if (spLevel > 0) {
                          if (isDomain && domainTier != null) {
                            setDomainSlots(s => ({
                              ...s,
                              [domainTier]: { ...s[domainTier], used: Math.min(s[domainTier].total, s[domainTier].used + 1) },
                            }));
                          } else if (slots[spLevel]) {
                            setSlots(s => ({
                              ...s,
                              [spLevel]: { ...s[spLevel], used: Math.min(s[spLevel].total, s[spLevel].used + 1) },
                            }));
                          }
                        }
                        push({ icon: 'spell', label: `Каст: ${sp.name}`, detail: `${sp.school || ''}${spLevel > 0 ? (isDomain ? ` · домен тір ${domainTier}` : ` · рів.${spLevel}`) : ' · трюк'}` });
                      }}>каст</Btn>
                    </div>
                  );
                })}
              </div>
            </div>
          </Card>
        </div>
      )}

      {/* ===== MODAL: Додати NPC ===== */}
      {addNPCOpen && (
        <div className="dice-overlay-backdrop" onClick={() => setAddNPCOpen(false)}>
          <div className="dice-overlay" style={{ width: 400, minHeight: 420 }} onClick={e => e.stopPropagation()}>
            <div className="dice-overlay-head">
              <Icon name="character" size={18} style={{ color: 'var(--gold-1)' }}/>
              <h2>Додати учасника</h2>
              <div className="igrow"/>
              <IconBtn name="x" onClick={() => setAddNPCOpen(false)}/>
            </div>
            <div className="dice-overlay-body">
              <div className="icol ig-12">
                <div>
                  <div className="field-label mb-4">Ім'я</div>
                  <input className="input" autoFocus placeholder="Гоблін, Стражник…"
                    value={npcDraft.name} onChange={e => setNpcDraft(v => ({ ...v, name: e.target.value }))}/>
                </div>
                <div className="flex ig-8">
                  <div style={{ width: 100 }}>
                    <div className="field-label mb-4">Ініціатива</div>
                    <input className="input" type="number" value={npcDraft.init}
                      onChange={e => setNpcDraft(v => ({ ...v, init: parseInt(e.target.value) || 0 }))}/>
                  </div>
                  <div className="igrow">
                    <div className="field-label mb-4">HP (макс)</div>
                    <input className="input" type="number" min="0" placeholder="0 = невідомо"
                      value={npcDraft.hp} onChange={e => setNpcDraft(v => ({ ...v, hp: parseInt(e.target.value) || 0 }))}/>
                  </div>
                </div>
                <label className="flex ica ig-8" style={{ cursor: 'pointer', userSelect: 'none' }}>
                  <input type="checkbox" checked={npcDraft.enemy}
                    onChange={e => setNpcDraft(v => ({ ...v, enemy: e.target.checked }))}/>
                  <span style={{ fontSize: 13 }}>Ворог (червона мітка)</span>
                </label>
                <div className="flex ig-8 mt-4">
                  <Btn primary onClick={() => {
                    if (!npcDraft.name.trim()) return;
                    const hpVal = npcDraft.hp > 0 ? { hpMax: npcDraft.hp, hpCur: npcDraft.hp } : { hp: '?' };
                    setExtraInit(es => [...es, { name: npcDraft.name.trim(), init: npcDraft.init, enemy: npcDraft.enemy, badges: [], ...hpVal }]);
                    setNpcDraft({ name: '', init: 0, hp: 0, enemy: false });
                    setAddNPCOpen(false);
                    push({ icon: 'character', label: `Додано: ${npcDraft.name.trim()}` });
                  }}><Icon name="plus" size={12}/> Додати</Btn>
                  <Btn ghost onClick={() => setAddNPCOpen(false)}>Скасувати</Btn>
                </div>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* ===== MODAL: Нова атака ===== */}
      {addAttackOpen && (
        <div className="dice-overlay-backdrop" onClick={() => setAddAttackOpen(false)}>
          <div className="dice-overlay" style={{ width: 480, minHeight: 440 }} onClick={e => e.stopPropagation()}>
            <div className="dice-overlay-head">
              <Icon name="sword" size={18} style={{ color: 'var(--gold-1)' }}/>
              <h2>Нова атака</h2>
              <div className="igrow"/>
              <IconBtn name="x" onClick={() => setAddAttackOpen(false)}/>
            </div>
            <div className="dice-overlay-body">
              <div className="icol ig-12">
                <div className="flex ig-8">
                  <div className="igrow">
                    <div className="field-label mb-4">Назва</div>
                    <input className="input" placeholder="Довгий меч" autoFocus
                      value={newAtk.name} onChange={e => setNewAtk(v => ({ ...v, name: e.target.value }))}/>
                  </div>
                  <div style={{ width: 80 }}>
                    <div className="field-label mb-4">Бонус атаки</div>
                    <input className="input" type="number" value={newAtk.bonus}
                      onChange={e => setNewAtk(v => ({ ...v, bonus: Number(e.target.value) || 0 }))}/>
                  </div>
                </div>
                <div className="flex ig-8">
                  <div style={{ width: 100 }}>
                    <div className="field-label mb-4">Куб дамагу</div>
                    <input className="input" placeholder="1d8+3"
                      value={newAtk.dice} onChange={e => setNewAtk(v => ({ ...v, dice: e.target.value }))}/>
                  </div>
                  <div className="igrow">
                    <div className="field-label mb-4">Тип дамагу</div>
                    <input className="input" placeholder="рубаючий"
                      value={newAtk.type} onChange={e => setNewAtk(v => ({ ...v, type: e.target.value }))}/>
                  </div>
                  <div className="igrow">
                    <div className="field-label mb-4">Нотатка</div>
                    <input className="input" placeholder="фінесс, метання..."
                      value={newAtk.note} onChange={e => setNewAtk(v => ({ ...v, note: e.target.value }))}/>
                  </div>
                  <div style={{ width: 110 }}>
                    <div className="field-label mb-4">Тип дії</div>
                    <select className="input" value={newAtk.actionType} onChange={e => setNewAtk(v => ({ ...v, actionType: e.target.value }))} style={{ cursor: 'pointer' }}>
                      <option value="action">Дія</option>
                      <option value="bonus">Бонусна</option>
                      <option value="reaction">Реакція</option>
                      <option value="free">Вільна</option>
                    </select>
                  </div>
                </div>
                <div className="flex ig-8 mt-4">
                  <Btn primary onClick={() => {
                    if (!newAtk.name.trim()) return;
                    setCh(c => ({ ...c, customAttacks: [...(c.customAttacks || []), { ...newAtk, name: newAtk.name.trim() }] }));
                    setNewAtk({ name: '', bonus: 0, dice: '1d6', type: 'к', note: '', actionType: 'action' });
                    setAddAttackOpen(false);
                    push({ icon: 'sword', label: `Атаку додано: ${newAtk.name.trim()}` });
                  }}><Icon name="plus" size={12}/> Додати</Btn>
                  <Btn ghost onClick={() => setAddAttackOpen(false)}>Скасувати</Btn>
                </div>
              </div>
            </div>
          </div>
        </div>
      )}
    </>
  );
};

window.ScreenCombat = ScreenCombat;
