/* ============================================================
   admin-content.jsx — Тексты бота + Команды бота
   content API: GET {items[]} (key,value,imageUrl,group) • PUT {key,value,imageUrl}
   bot-commands API: GET {items[]} • POST/PUT camelCase • apply = POST {action:'apply'}
   ============================================================ */

const { useState, useEffect } = React;

function AdminContent() {
  const { API_BASE } = useAuth();
  const toast = useToast();
  const [tab, setTab] = useState('texts');

  const tabs = [
    { id: 'texts', label: '✏️ Тексты' },
    { id: 'commands', label: '⌨️ Команды' },
  ];

  return (
    <div>
      <div className="page-head">
        <div className="page-head-text">
          <h1 className="page-title h-display">✏️ Тексты / Команды</h1>
        </div>
      </div>
      <Tabs items={tabs} active={tab} onChange={setTab} />
      {tab === 'texts'    && <AdminTexts API_BASE={API_BASE} toast={toast} />}
      {tab === 'commands' && <AdminCommands API_BASE={API_BASE} toast={toast} />}
    </div>
  );
}

/* ─── Texts ─── */
function AdminTexts({ API_BASE, toast }) {
  const [items, setItems] = useState([]);
  const [edited, setEdited] = useState({});      // key → новое значение
  const [imgEdits, setImgEdits] = useState({});  // key → новый imageUrl
  const [imgOpen, setImgOpen] = useState({});    // key → bool (показать загрузку)
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(null);
  const [groupFilter, setGroupFilter] = useState('all');
  const [search, setSearch] = useState('');

  async function load() {
    setLoading(true);
    try {
      const r = await fetch(`${API_BASE}/api/tg/admin/content`, { credentials: 'include' });
      if (r.ok) { const data = await r.json(); setItems(data.items || []); }
    } catch {}
    finally { setLoading(false); }
  }

  useEffect(() => { load(); }, []);

  function curVal(item) { return edited[item.key] !== undefined ? edited[item.key] : (item.value || ''); }
  function curImg(item) { return imgEdits[item.key] !== undefined ? imgEdits[item.key] : (item.imageUrl || ''); }
  function isDirty(item) {
    return (edited[item.key] !== undefined && edited[item.key] !== item.value)
        || (imgEdits[item.key] !== undefined && imgEdits[item.key] !== (item.imageUrl || ''));
  }

  async function save(item) {
    setSaving(item.key);
    try {
      const r = await fetch(`${API_BASE}/api/tg/admin/content`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ key: item.key, value: curVal(item), imageUrl: curImg(item) || null }),
        credentials: 'include',
      });
      if (r.ok) {
        toast(`Сохранено: ${item.key}`, 'ok');
        setEdited(e => { const n = {...e}; delete n[item.key]; return n; });
        setImgEdits(e => { const n = {...e}; delete n[item.key]; return n; });
        load();
      } else {
        const d = await r.json();
        toast(d.error || 'Ошибка', 'warn');
      }
    } catch { toast('Ошибка', 'warn'); }
    finally { setSaving(null); }
  }

  const groups = [...new Set(items.map(i => i.group || 'other'))];
  const filtered = items.filter(i => {
    const grpOk = groupFilter === 'all' || (i.group || 'other') === groupFilter;
    const srchOk = !search || i.key.includes(search) || (i.value || '').includes(search);
    return grpOk && srchOk;
  });

  if (loading) return <div style={{ textAlign: 'center', padding: 40 }}><Spinner /></div>;

  return (
    <div>
      <div style={{ display: 'flex', gap: 10, marginBottom: 16 }}>
        <input
          className="field-input"
          placeholder="Поиск по ключу / тексту"
          value={search}
          onChange={e => setSearch(e.target.value)}
          style={{ flex: 1 }}
        />
      </div>

      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 16 }}>
        <button className={`seg-btn${groupFilter === 'all' ? ' on' : ''}`} onClick={() => setGroupFilter('all')}>Все</button>
        {groups.map(g => (
          <button key={g} className={`seg-btn${groupFilter === g ? ' on' : ''}`} onClick={() => setGroupFilter(g)}>{g}</button>
        ))}
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {filtered.map(item => {
          const hasImg = curImg(item);
          const showImg = imgOpen[item.key] || hasImg;
          return (
            <div key={item.key} className="glass" style={{ padding: '14px 16px' }}>
              <div style={{ fontWeight: 600, fontSize: 13, marginBottom: 8, color: '#c4b5fd' }}>{item.key}</div>
              <textarea
                className="prompt-area"
                rows={Math.min(6, curVal(item).split('\n').length + 1)}
                value={curVal(item)}
                onChange={e => setEdited(ed => ({ ...ed, [item.key]: e.target.value }))}
                style={{ fontSize: 13 }}
              />

              {showImg ? (
                <div style={{ marginTop: 10 }}>
                  <AdminImageUpload API_BASE={API_BASE} value={curImg(item)} onChange={v => setImgEdits(ed => ({ ...ed, [item.key]: v }))} toast={toast} />
                </div>
              ) : (
                <button className="btn btn-ghost btn-sm" style={{ marginTop: 8 }} onClick={() => setImgOpen(o => ({ ...o, [item.key]: true }))}>🖼 Добавить картинку</button>
              )}

              {isDirty(item) && (
                <button
                  className="btn btn-accent btn-sm"
                  style={{ marginTop: 8, marginLeft: 8 }}
                  onClick={() => save(item)}
                  disabled={saving === item.key}
                >
                  {saving === item.key ? <Spinner sm /> : '✓ Сохранить'}
                </button>
              )}
            </div>
          );
        })}
        {filtered.length === 0 && <EmptyState icon="🔍" title="Ничего не найдено" />}
      </div>
    </div>
  );
}

/* ─── Commands ─── */
function AdminCommands({ API_BASE, toast }) {
  const [commands, setCommands] = useState([]);
  const [loading, setLoading] = useState(true);
  const [form, setForm] = useState(null);
  const [saving, setSaving] = useState(false);
  const [applying, setApplying] = useState(false);

  async function load() {
    setLoading(true);
    try {
      const r = await fetch(`${API_BASE}/api/tg/admin/bot-commands`, { credentials: 'include' });
      if (r.ok) { const data = await r.json(); setCommands(data.items || []); }
    } catch {}
    finally { setLoading(false); }
  }

  useEffect(() => { load(); }, []);

  async function saveCmd() {
    setSaving(true);
    try {
      const isNew = form.id === undefined;
      const payload = {
        ...(form.id && { id: form.id }),
        command: form.command,
        description: form.description,
        isActive: form.isActive ?? true,
        sortOrder: Number(form.sortOrder) || 0,
      };
      const r = await fetch(`${API_BASE}/api/tg/admin/bot-commands`, {
        method: isNew ? 'POST' : 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
        credentials: 'include',
      });
      if (r.ok) { toast('Сохранено', 'ok'); setForm(null); load(); }
      else { const d = await r.json(); toast(d.error || 'Ошибка', 'warn'); }
    } catch { toast('Ошибка', 'warn'); }
    finally { setSaving(false); }
  }

  async function deleteCmd(id) {
    if (!confirm('Удалить команду?')) return;
    try {
      const r = await fetch(`${API_BASE}/api/tg/admin/bot-commands?id=${id}`, {
        method: 'DELETE', credentials: 'include',
      });
      if (r.ok) { toast('Удалено', 'ok'); load(); }
    } catch {}
  }

  async function applyCommands() {
    setApplying(true);
    try {
      const r = await fetch(`${API_BASE}/api/tg/admin/bot-commands`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ action: 'apply' }),
        credentials: 'include',
      });
      if (r.ok) toast('Команды применены в Telegram', 'ok');
      else toast('Ошибка применения', 'warn');
    } catch {}
    finally { setApplying(false); }
  }

  if (loading) return <div style={{ textAlign: 'center', padding: 40 }}><Spinner /></div>;

  if (form) return (
    <div style={{ maxWidth: 460 }}>
      <div className="page-head">
        <button className="btn btn-ghost back-btn" onClick={() => setForm(null)}>← Назад</button>
      </div>
      <div className="glass" style={{ padding: 24 }}>
        <div className="block-title" style={{ marginBottom: 18 }}>{form.id ? 'Редактировать' : 'Новая команда'}</div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <div className="field">
            <label className="field-label">Команда (без /)</label>
            <input className="field-input" value={form.command || ''} onChange={e => setForm(f => ({...f, command: e.target.value}))} />
          </div>
          <div className="field">
            <label className="field-label">Описание</label>
            <input className="field-input" value={form.description || ''} onChange={e => setForm(f => ({...f, description: e.target.value}))} />
          </div>
          <div className="field">
            <label className="field-label">Порядок (sortOrder)</label>
            <input className="field-input" type="number" value={form.sortOrder || 0} onChange={e => setForm(f => ({...f, sortOrder: Number(e.target.value)}))} />
          </div>
          <Toggle label="Активна" value={form.isActive ?? true} onChange={v => setForm(f => ({...f, isActive: v}))} />
          <div style={{ display: 'flex', gap: 10 }}>
            <button className="btn btn-accent" onClick={saveCmd} disabled={saving || !form.command || !form.description}>{saving ? <Spinner sm /> : 'Сохранить'}</button>
            <button className="btn btn-ghost" onClick={() => setForm(null)}>Отмена</button>
          </div>
        </div>
      </div>
    </div>
  );

  return (
    <div>
      <div style={{ display: 'flex', gap: 10, marginBottom: 20 }}>
        <button className="btn btn-accent btn-sm" onClick={() => setForm({ command: '', description: '', isActive: true, sortOrder: 0 })}>+ Добавить</button>
        <button className="btn btn-ghost btn-sm" onClick={applyCommands} disabled={applying}>
          {applying ? <Spinner sm /> : '📲 Применить в Telegram'}
        </button>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {commands.map(cmd => (
          <div key={cmd.id} className="glass" style={{ padding: '14px 18px', display: 'flex', alignItems: 'center', gap: 14 }}>
            <div style={{ flex: 1 }}>
              <div style={{ fontWeight: 700 }}>/{cmd.command}</div>
              <div className="muted" style={{ fontSize: 13 }}>{cmd.description}</div>
            </div>
            <span className={`pill${cmd.isActive ? ' pill-free' : ''}`} style={{ background: cmd.isActive ? undefined : 'rgba(255,255,255,.06)', color: cmd.isActive ? undefined : 'var(--text-dim)' }}>
              {cmd.isActive ? 'Активна' : 'Откл.'}
            </span>
            <button className="btn btn-ghost btn-sm" onClick={() => setForm(cmd)}>✏️</button>
            <button className="btn btn-sm" style={{ color: '#fca5a5' }} onClick={() => deleteCmd(cmd.id)}>🗑</button>
          </div>
        ))}
        {commands.length === 0 && <EmptyState icon="⌨️" title="Нет команд" />}
      </div>
    </div>
  );
}
