// ──────────────────────────────────────────────────────────────────────────
// AI BARTENDER — UI-атомы и под-экраны (после переработки на тему half-empty)
// ──────────────────────────────────────────────────────────────────────────

const { useState, useEffect, useRef, useMemo } = React;

// ── СТАКАН — главная метрика «заполненности» персонажа ───────────────────
function Glass({ value, label = 'ЗАПОЛНЕННОСТЬ', size = 'md' }) {
  const pct = Math.max(0, Math.min(100, value));
  // визуально стакан наполняется снизу
  const w = size === 'sm' ? 36 : size === 'lg' ? 72 : 52;
  const h = size === 'sm' ? 52 : size === 'lg' ? 96 : 72;
  return (
    <div className={`glass-block glass-${size}`}>
      <div className="glass" style={{ width: w, height: h }}>
        <div className="glass-liquid" style={{ height: pct + '%' }}>
          <div className="glass-meniscus"></div>
        </div>
        <div className="glass-ticks"></div>
      </div>
      <div className="glass-meta">
        <div className="glass-lbl">{label}</div>
        <div className="glass-val">{Math.round(pct)}<span>%</span></div>
      </div>
    </div>
  );
}

// ── Карточка клиента (теперь со стаканом) ────────────────────────────────
function ClientCard({ character, state, fragmentDropped }) {
  if (!character) return null;
  return (
    <div className="panel-body client-card scroll-pretty">
      <div className="row"><span>ИМЯ</span><strong>{character.name}</strong></div>
      <div className="row"><span>СТАТУС</span><strong>{character.tag}</strong></div>
      <div className="row"><span>НАСТРОЕНИЕ</span><strong style={{ color: 'var(--accent-1)' }}>{character.mood}</strong></div>
      <hr style={{ border: 0, borderTop: '1px solid var(--panel-edge)', margin: '6px 0' }} />
      <p>{character.shortBio}</p>
      <div className="need-line"><span>хочет:</span> {character.need}</div>
      <Glass value={state.fill} label="ЗАПОЛНЕННОСТЬ" />
      {fragmentDropped && (
        <div className="fragment-hint">▸ ОН(А) РОНЯЛ ЗАЦЕПКУ ПРО ТЕБЯ · «КТО Я»</div>
      )}
      <hr style={{ border: 0, borderTop: '1px solid var(--panel-edge)', margin: '6px 0' }} />
      <div className="row" style={{ textTransform: 'none', letterSpacing: '0.04em', fontSize: 11 }}>
        <span style={{ color: 'var(--ink-dim)' }}>предпочтения</span>
      </div>
      <p style={{ fontSize: 11 }}>{character.drinkPref}</p>
    </div>
  );
}

// ── Портрет ──────────────────────────────────────────────────────────────
// Картинка грузится с бэкенда: GET /api/game/portrait/{id}. Если её нет (404)
// — показываем запасной процедурный портрет (по hue персонажа).
const PORTRAIT_BASE = (typeof window !== 'undefined' && window.BACKEND_BASE) || '';

function Portrait({ character }) {
  const [failed, setFailed] = useState(false);

  // при смене персонажа снова пробуем загрузить картинку
  useEffect(() => { setFailed(false); }, [character.id]);

  const src = `${PORTRAIT_BASE}/api/game/portrait/${encodeURIComponent(character.id)}`;

  return (
    <div className="portrait-wrap panel">
      <div className="panel-h"><span>СТОЙКА БАРА · ВИД 01</span><span>LIVE</span></div>
      <div className="portrait" style={{ '--hue': character.portraitHue }}>
        {!failed ? (
          <>
            {/* размытый фон-заполнитель, чтобы не было плоских полос по краям */}
            <img
              aria-hidden="true"
              src={src}
              onError={() => setFailed(true)}
              style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', filter: 'blur(26px) brightness(0.45) saturate(1.1)', transform: 'scale(1.12)', zIndex: 0 }}
            />
            {/* сам портрет целиком, без обрезки */}
            <img
              className="portrait-img"
              src={src}
              alt={character.name}
              onError={() => setFailed(true)}
              style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'contain', objectPosition: 'center', zIndex: 1 }}
            />
          </>
        ) : (
          <div className="drop-hint drop-hint--portrait">
            <div className="drop-hint__ring"></div>
            <div className="drop-hint__label">
              <span>NO SIGNAL</span>
              <strong>{character.name}</strong>
            </div>
          </div>
        )}
        <div className="portrait-crosshair"></div>
        <div className="portrait-mood">{character.mood}</div>
        <div className="portrait-tag">
          <span className="nm">{character.name}</span>
          {character.tag}
        </div>
      </div>
    </div>
  );
}

// ── ЧАТ ─────────────────────────────────────────────────────────────────
function ChatPanel({ character, messages, onSend, isThinking, playerName }) {
  const [text, setText] = useState('');
  const scrollRef = useRef(null);

  useEffect(() => {
    const el = scrollRef.current;
    if (el) el.scrollTop = el.scrollHeight;
  }, [messages, isThinking]);

  const submit = () => {
    const v = text.trim();
    if (!v || isThinking) return;
    onSend(v);
    setText('');
  };

  return (
    <div className="panel chat-panel">
      <div className="panel-h">
        <strong>ДИАЛОГ // {character.name}</strong>
        <span>ENC. AES-512</span>
      </div>
      <div className="chat-body scroll-pretty" ref={scrollRef}>
        {messages.map((m, i) => (
          <div key={i} className={`msg ${m.from}`}>
            <div className="role">
              <span>{m.from === 'me' ? (playerName || 'ТЫ').toUpperCase() : m.from === 'sys' ? 'СИСТ' : ''}</span>
              {m.from === 'them' && <span className="nm">{character.name}</span>}
            </div>
            <div className={`bubble ${m.kind === 'fragment' ? 'is-fragment' : ''} ${m.kind === 'help' ? 'is-help' : ''}`}>
              {m.kind === 'fragment' && <div className="bubble-tag">▸ ФРАГМЕНТ ПАМЯТИ</div>}
              {m.kind === 'help' && <div className="bubble-tag">▸ ПОМОЩЬ</div>}
              {m.text}
            </div>
          </div>
        ))}
        {isThinking && (
          <div className="msg them">
            <div className="role"><span className="nm">{character.name}</span></div>
            <div className="bubble"><span className="typing"><span></span><span></span><span></span></span></div>
          </div>
        )}
      </div>
      <div className="chat-input">
        <textarea
          value={text}
          onChange={e => setText(e.target.value)}
          onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); submit(); } }}
          placeholder={`Что ты скажешь? (Enter — отправить)`}
        />
        <button className="send" onClick={submit} disabled={isThinking || !text.trim()}>
          {isThinking ? '...' : 'SEND ▸'}
        </button>
      </div>
    </div>
  );
}

// ── ПАНЕЛЬ ПОМОЩИ ───────────────────────────────────────────────────────
function HelpPanel({ character, state, charStates, onHelp }) {
  if (!character?.helpActions?.length) return null;

  const evaluated = character.helpActions.map(act => {
    const done = (state.helpDone || []).includes(act.id);
    const secretsOk = (state.secretsRevealed || 0) >= (act.requiresSecrets || 0);
    let otherOk = true;
    if (act.requiresOther) {
      const other = charStates[act.requiresOther.id];
      otherOk = ((other && other.secretsRevealed) || 0) >= (act.requiresOther.secrets || 0);
    }
    return { act, done, ready: !done && secretsOk && otherOk };
  });

  // Заблокированные действия скрываем целиком: их подписи спойлерят то, чего
  // игрок ещё не узнал. Показываем только готовые и уже выполненные.
  const visible = evaluated.filter(e => e.done || e.ready);

  return (
    <div className="help-panel panel">
      <div className="panel-h"><strong>ПОМОЧЬ {character.name}</strong><span>{state.helpDone?.length || 0}/{character.helpActions.length}</span></div>
      <div className="panel-body scroll-pretty" style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {visible.map(({ act, done }) => (
          <div key={act.id} className={`help-action ${done ? 'done' : 'ready'}`}>
            <div className="help-action__row">
              <div className="help-action__label">{act.label}</div>
              {done
                ? <div className="help-action__badge done">ВЫПОЛНЕНО</div>
                : <div className="help-action__badge ready">ГОТОВО</div>}
            </div>
            <div className="help-action__tip">{act.tip}</div>
            {!done && (
              <button className="btn primary" onClick={() => onHelp(act)}>ПОМОЧЬ ▸</button>
            )}
          </div>
        ))}
        {visible.length === 0 && (
          <div className="help-action locked">
            <div className="help-action__tip">Узнай больше — и появится, чем помочь.</div>
          </div>
        )}
      </div>
    </div>
  );
}

// ── ПАНЕЛЬ КРАФТА НАПИТКОВ ───────────────────────────────────────────────
function CraftPanel({ data, draft, setDraft, onServe, difficulty }) {
  const { INGREDIENTS, GLASSWARE, METHODS, RECIPES } = data;

  const addIngredient = (id) => {
    if (draft.ingredients.length >= 5) return;
    setDraft({ ...draft, ingredients: [...draft.ingredients, id] });
  };
  const removeIngredient = (i) => {
    setDraft({ ...draft, ingredients: draft.ingredients.filter((_, idx) => idx !== i) });
  };

  const matched = useMemo(() => {
    if (!draft.glass || !draft.method || draft.ingredients.length === 0) return null;
    const sortedDraft = [...draft.ingredients].sort().join(',');
    return RECIPES.find(r => {
      if (r.glass !== draft.glass) return false;
      if (r.method !== draft.method) return false;
      const want = [...r.ingredients].sort().join(',');
      return want === sortedDraft;
    });
  }, [draft, RECIPES]);

  const looseMatched = useMemo(() => {
    if (difficulty !== 'easy') return null;
    if (!draft.glass || draft.ingredients.length === 0) return null;
    return RECIPES.find(r =>
      r.glass === draft.glass &&
      r.ingredients.every(i => draft.ingredients.includes(i))
    );
  }, [draft, difficulty, RECIPES]);

  const finalRecipe = matched || looseMatched;
  const canServe = draft.glass && draft.method && draft.ingredients.length > 0;

  return (
    <div className="panel craft">
      <div className="panel-h"><strong>КРАФТ</strong><span>STATION 01</span></div>
      <div className="panel-body scroll-pretty">

        <div className="micro-label">ПОЛКА</div>
        <div className="shelf-grid">
          {INGREDIENTS.map(i => (
            <button key={i.id} className="shelf-item" onClick={() => addIngredient(i.id)} title={i.hint}>
              <div className="vial" style={{ '--c': i.color }}></div>
              <span>{i.name}</span>
            </button>
          ))}
        </div>

        <div className="micro-label" style={{ marginTop: 14 }}>ПОСУДА</div>
        <div className="selector-row">
          {GLASSWARE.map(g => (
            <button
              key={g.id}
              className={`chip ${draft.glass === g.id ? 'active' : ''}`}
              onClick={() => setDraft({ ...draft, glass: draft.glass === g.id ? null : g.id })}
              title={g.hint}
            >{g.name}</button>
          ))}
        </div>

        <div className="micro-label" style={{ marginTop: 14 }}>МЕТОД</div>
        <div className="selector-row">
          {METHODS.map(m => (
            <button
              key={m.id}
              className={`chip ${draft.method === m.id ? 'active' : ''}`}
              onClick={() => setDraft({ ...draft, method: draft.method === m.id ? null : m.id })}
              title={m.hint}
            >{m.name}</button>
          ))}
        </div>

        <div className="micro-label" style={{ marginTop: 14 }}>В ШЕЙКЕРЕ</div>
        <div className="staged">
          {draft.ingredients.length === 0 && <div className="staged-empty">пусто</div>}
          {draft.ingredients.map((id, i) => {
            const ing = INGREDIENTS.find(x => x.id === id);
            return (
              <div key={i} className="staged-row">
                <div className="vial" style={{ '--c': ing?.color, width: 8, height: 14, background: ing?.color, borderRadius: '2px 2px 4px 4px', boxShadow: `0 0 6px ${ing?.color}` }}></div>
                <span>{ing?.name}</span>
                <button className="x" onClick={() => removeIngredient(i)}>✕</button>
              </div>
            );
          })}
        </div>

        {finalRecipe && (
          <div className="recipe-match">
            <span style={{ color: 'var(--accent-2)' }}>СОВПАДЕНИЕ:</span> {finalRecipe.name}
          </div>
        )}

        <div className="craft-actions" style={{ marginTop: 12 }}>
          <button className="btn ghost" onClick={() => setDraft({ ingredients: [], glass: null, method: null })}>СБРОС</button>
          <button className="btn primary" disabled={!canServe} onClick={() => onServe(finalRecipe)}>ПОДАТЬ ▸</button>
        </div>
      </div>
    </div>
  );
}

// ── ДОСЬЕ ────────────────────────────────────────────────────────────────
function DossierScreen({ characters, charStates, activeId, setActiveId }) {
  const active = characters.find(c => c.id === activeId) || characters[0];
  const charProgress = charStates[active.id] || { secretsRevealed: 0, drinksServed: 0, fill: 0 };
  return (
    <div className="dossier">
      <div className="dossier-list scroll-pretty">
        <div className="micro-label" style={{ padding: '4px 6px' }}>КЛИЕНТЫ · {characters.length}</div>
        {characters.map(c => {
          const st = charStates[c.id] || { fill: 0, secretsRevealed: 0 };
          return (
            <div key={c.id} className={`dossier-row ${c.id === active.id ? 'active' : ''}`} onClick={() => setActiveId(c.id)} style={{ '--hue': c.portraitHue }}>
              <image-slot
                id={`avatar-${c.id}`}
                shape="rect"
                fit="cover"
                placeholder=""
                class="dossier-avatar-slot">
              </image-slot>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="nm">{c.name}</div>
                <div className="tg">{c.tag} · {Math.round(st.fill)}%</div>
              </div>
            </div>
          );
        })}
      </div>

      <div className="dossier-detail scroll-pretty">
        <div className="hero" style={{ '--hue': active.portraitHue }}>
          <div className="avatar-lg">
            <image-slot
              id={`hero-${active.id}`}
              shape="rect"
              fit="cover"
              placeholder=""
              class="dossier-hero-slot">
            </image-slot>
            <div className="drop-hint drop-hint--hero">
              <div className="drop-hint__ring"></div>
              <div className="drop-hint__label">
                <span>DROP PORTRAIT</span>
                <strong>{active.name}</strong>
              </div>
            </div>
          </div>
          <div>
            <h2>{active.name}</h2>
            <div className="tg">{active.tag}</div>
            <p className="bio">{active.shortBio}</p>
            <div className="need-line need-line--big"><span>хочет:</span> {active.need}</div>
            <div className="dossier-stats">
              <Glass value={charProgress.fill} label="ЗАПОЛНЕННОСТЬ" size="sm" />
              <div className="endshift-stat" style={{ padding: 8 }}>
                <div className="lbl">Налито</div>
                <div className="val" style={{ fontSize: 20 }}>{charProgress.drinksServed || 0}</div>
              </div>
              <div className="endshift-stat" style={{ padding: 8 }}>
                <div className="lbl">Секретов</div>
                <div className="val" style={{ fontSize: 20 }}>{charProgress.secretsRevealed}/{active.secrets.length}</div>
              </div>
              <div className="endshift-stat" style={{ padding: 8 }}>
                <div className="lbl">Помощи</div>
                <div className="val" style={{ fontSize: 20 }}>{(charProgress.helpDone || []).length}/{active.helpActions.length}</div>
              </div>
            </div>
          </div>
        </div>

        <div className="dossier-section">
          <h3>Что он(а) пьёт</h3>
          <p style={{ margin: 0, color: 'var(--ink-dim)', lineHeight: 1.5 }}>{active.drinkPref}</p>
        </div>

        <div className="dossier-section">
          <h3>Биография · уровень доступа</h3>
          <div className="secret-list">
            {active.secrets.map((s, i) => (
              <div key={i} className={`secret ${i < charProgress.secretsRevealed ? 'revealed' : 'locked'}`}>
                {i < charProgress.secretsRevealed ? s : `Уровень ${i + 1}`}
              </div>
            ))}
          </div>
        </div>

        <div className="dossier-section">
          <h3>Возможности помочь</h3>
          <div className="secret-list">
            {active.helpActions.map(act => {
              const done = (charProgress.helpDone || []).includes(act.id);
              return (
                <div key={act.id} className={`secret ${done ? 'revealed' : 'locked'}`}>
                  <strong>{act.label}.</strong> {done ? act.done : act.tip}
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  );
}

// ── КНИГА РЕЦЕПТОВ ───────────────────────────────────────────────────────
function RecipesScreen({ data, unlocked }) {
  const { RECIPES, INGREDIENTS, GLASSWARE, METHODS } = data;
  return (
    <div className="recipes-screen scroll-pretty">
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 12, marginBottom: 14 }}>
        <h2 style={{ fontFamily: 'var(--font-display)', letterSpacing: '0.18em', margin: 0, fontSize: 24 }}>КНИГА БАРНЫХ РЕЦЕПТОВ</h2>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '0.2em', color: 'var(--ink-dim)', textTransform: 'uppercase' }}>{unlocked.length}/{RECIPES.length} ОТКРЫТО</span>
      </div>
      <div className="recipes-grid">
        {RECIPES.map(r => {
          const isOpen = r.unlocked || unlocked.includes(r.id);
          const glass = GLASSWARE.find(g => g.id === r.glass);
          const method = METHODS.find(m => m.id === r.method);
          return (
            <div key={r.id} className={`recipe-card ${isOpen ? '' : 'locked'}`}>
              {!isOpen && <div className="lock-badge">SECRET</div>}
              <h3>{isOpen ? r.name : '? ? ?'}</h3>
              <div className="meta">{isOpen ? `${glass?.name} · ${method?.name}` : '— · —'}</div>
              <div className="desc">{isOpen ? r.desc : 'Открывается, когда клиент сам попросит.'}</div>
              <div className="ingr">
                {r.ingredients.map(i => {
                  const ing = INGREDIENTS.find(x => x.id === i);
                  return <span key={i} className="tag">{isOpen ? ing?.name : '◼◼◼'}</span>;
                })}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ── «КТО Я» — фрагменты идентичности бармена ─────────────────────────────
function IdentityScreen({ fragments, unlockedIds, playerName, characters }) {
  const totalUnlocked = unlockedIds.length;
  const total = fragments.length;
  const revealed = totalUnlocked >= total;

  return (
    <div className="identity-screen scroll-pretty">
      <div className="identity-head">
        <div className="micro-label">SHIFT 047 · BARMAN PROFILE</div>
        <h1>КТО Я?</h1>
        <p className="identity-lead">
          Ты не помнишь, как сюда попал. Зеркало за стойкой не отражает прошлого.
          Но клиенты — каждый из своей дыры — роняют о тебе по одной фразе.
          Собери их.
        </p>
        <div className="identity-bar">
          <div className="identity-bar-fill" style={{ width: (totalUnlocked / total * 100) + '%' }}></div>
        </div>
        <div className="identity-bar-text">
          ВОССТАНОВЛЕНО · {totalUnlocked} / {total}
        </div>
      </div>

      <div className="fragments-list">
        {fragments.map((f, i) => {
          const unlocked = unlockedIds.includes(f.id);
          const character = characters.find(c => c.id === f.from);
          return (
            <div key={f.id} className={`fragment ${unlocked ? 'open' : 'locked'}`} style={{ '--hue': character?.portraitHue || 200 }}>
              <div className="fragment-num">0{i + 1}</div>
              <div className="fragment-body">
                <div className="fragment-source">
                  {unlocked ? <>СО СЛОВ {character?.name}</> : <>ЗАГЛУШЕНО · ИСТОЧНИК НЕИЗВЕСТЕН</>}
                </div>
                <div className="fragment-text">
                  {unlocked ? f.text : '◼◼◼ ◼◼◼ ◼◼ ◼◼◼◼◼ ◼◼◼ ◼◼◼◼ ◼◼ ◼◼◼ ◼◼◼◼◼.'}
                </div>
              </div>
            </div>
          );
        })}
      </div>

      {revealed && (
        <div className="identity-reveal">
          <div className="identity-reveal-lead">ТЫ ВСПОМНИЛ.</div>
          <div className="identity-reveal-name">{playerName || 'БАРМЕН'} — ЭТО МАСКА. ТВОЁ НАСТОЯЩЕЕ ИМЯ — КААН.</div>
          <p>
            Ты был барменом «Null//Pointer» до прошлой недели. Видел, как Венц подписал приказ. Тебя стёрли и
            вернули за ту же стойку — чтобы ты сам не догадался. Ты догадался.
          </p>
        </div>
      )}
    </div>
  );
}

// ── ВХОД / ЛОГИН ─────────────────────────────────────────────────────────
function LoginScreen({ onLogin, lastProfile, profiles }) {
  const [nick, setNick] = useState(lastProfile || '');
  const submit = () => {
    const v = nick.trim();
    if (!v) return;
    onLogin(v);
  };
  return (
    <div className="login-overlay">
      <div className="login-card">
        <div className="login-sub">UPLINK · NEON-Q · NULL//POINTER</div>
        <h1>НАЗОВИСЬ, БАРМЕН</h1>
        <p>
          Старый бармен исчез. Зеркало за стойкой не отражает прошлого. Назови себя — пусть хотя бы это
          у тебя будет.
        </p>
        <div className="login-input-row">
          <input
            type="text"
            value={nick}
            placeholder="никнейм"
            maxLength={24}
            onChange={e => setNick(e.target.value)}
            onKeyDown={e => { if (e.key === 'Enter') submit(); }}
            autoFocus
          />
          <button className="btn primary" onClick={submit} disabled={!nick.trim()}>ВОЙТИ ▸</button>
        </div>
        {profiles && profiles.length > 0 && (
          <div className="login-profiles">
            <div className="micro-label">ПРОФИЛИ В ПАМЯТИ</div>
            <div className="login-profiles-list">
              {profiles.map(p => (
                <button key={p} className="login-profile-chip" onClick={() => onLogin(p)}>{p}</button>
              ))}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

// ── КОНЕЦ СМЕНЫ ──────────────────────────────────────────────────────────
function EndShiftScreen({ shiftStats, onRestart, playerName }) {
  return (
    <div className="endshift">
      <div className="endshift-card">
        <div className="sub">СМЕНА ОКОНЧЕНА · {playerName?.toUpperCase()}</div>
        <h1>NULL//POINTER</h1>
        <p style={{ margin: 0, color: 'var(--ink-dim)', lineHeight: 1.6 }}>
          Неон гаснет. Дождь стихает. Кто-то ушёл, унеся с собой секрет. Кто-то остался — за стойкой ты теперь свой.
        </p>
        <div className="endshift-stats">
          <div className="endshift-stat"><div className="lbl">Чаевые</div><div className="val">¢ {shiftStats.tips}</div></div>
          <div className="endshift-stat"><div className="lbl">Помощей</div><div className="val">{shiftStats.helps}</div></div>
          <div className="endshift-stat"><div className="lbl">Фрагменты «Я»</div><div className="val">{shiftStats.fragments}/{shiftStats.totalFragments}</div></div>
        </div>
        <div className="endshift-list">
          {shiftStats.log.map((line, i) => (
            <div key={i} className="line">{line}</div>
          ))}
        </div>
        <div style={{ display: 'flex', gap: 10, marginTop: 8 }}>
          <button className="btn primary" onClick={onRestart}>НОВАЯ СМЕНА ▸</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  Glass, ClientCard, Portrait, ChatPanel, HelpPanel, CraftPanel,
  DossierScreen, RecipesScreen, IdentityScreen, LoginScreen, EndShiftScreen
});
