// 금칙어 관리 — 닉네임·리뷰에서 막을 단어 (/admin/banword). 등록 + 삭제(🔴 하드).
//
// 🔴 삭제는 되돌릴 수 없습니다(하드 DELETE). 삭제만 변경이력에 남고, 등록은 안 남습니다(backend 확인).
// 🔴 서버에 중복 검사가 없어 같은 단어가 둘 등록될 수 있습니다 — 화면이 이미 있는 단어를 경고합니다(막진 않음).

const BANWORD_SCOPES = [
  { value: 'ALL', label: '전체 (닉네임·리뷰)' },
  { value: 'NICKNAME', label: '닉네임만' },
];
const banwordScopeLabel = (s) => (BANWORD_SCOPES.find((x) => x.value === s) || {}).label || s || '전체 (닉네임·리뷰)';
const BANWORD_MAX = 50;   // ban_word.word VARCHAR(50). STRICT 라 넘으면 500.

const BanWords = () => {
  const [scopeFilter, setScopeFilter] = React.useState('');   // '' = 전체
  const [creating, setCreating] = React.useState(false);
  const [deletingId, setDeletingId] = React.useState(null);
  const [flash, setFlash] = React.useState(null);
  const list = useLive(() => api.live.banwords.list(), []);
  const rows = listRows(list.data);
  const filtered = scopeFilter ? rows.filter((r) => (r.scope || 'ALL') === scopeFilter) : rows;

  const remove = async (r) => {
    if (deletingId != null) return;
    if (!window.confirm(`금칙어 "${r.word}"를 삭제할까요?\n\n🔴 되돌릴 수 없습니다(완전 삭제). 다시 막으려면 새로 등록해야 합니다.`)) return;
    setDeletingId(r.id); setFlash(null);
    try {
      await api.live.banwords.remove(r.id);
      setFlash({ tone: 'info', text: `"${r.word}"를 삭제했습니다.` });
      list.reload();
    } catch (e) {
      setFlash({ tone: 'danger', text: `"${r.word}"를 삭제하지 못했습니다: ${errorText(e)}` });
    } finally {
      setDeletingId(null);
    }
  };

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1>금칙어 관리</h1>
          <div className="sub">닉네임·리뷰에서 막을 단어입니다</div>
        </div>
        <div className="actions">
          <button className="btn btn-ghost btn-sm" onClick={list.reload} disabled={list.loading}>
            <Icon name="refresh" size={14}/>새로고침
          </button>
          <button className="btn btn-primary btn-sm" onClick={() => setCreating(true)}>
            <Icon name="plus" size={14}/>금칙어 등록
          </button>
        </div>
      </div>

      {flash && <div style={{ marginBottom: 12 }}><Notice tone={flash.tone}>{flash.text}</Notice></div>}

      <div className="table-wrap" data-loading={list.loading ? 'true' : 'false'}>
        <div className="table-toolbar" style={{ flexWrap: 'wrap' }}>
          <select className="select" aria-label="적용 범위" value={scopeFilter} onChange={(e) => setScopeFilter(e.target.value)}>
            <option value="">전체 범위</option>
            {BANWORD_SCOPES.map((s) => <option key={s.value} value={s.value}>{s.label}</option>)}
          </select>
        </div>
        <LiveBlock state={list} empty={filtered.length === 0} emptyTitle={scopeFilter ? '이 범위의 금칙어가 없습니다' : '등록된 금칙어가 없습니다'}>
          <table className="table">
            <thead><tr>
              <th>단어</th>
              <th>적용 범위</th>
              <th>등록일</th>
              <th style={{ width: 80 }}></th>
            </tr></thead>
            <tbody>
              {filtered.map((r) => (
                <tr key={r.id}>
                  <td style={{ fontWeight: 600 }}>{r.word}</td>
                  <td>{banwordScopeLabel(r.scope)}</td>
                  <td style={{ whiteSpace: 'nowrap', color: 'var(--text-3)' }}>{fmtDT(r.regDate)}</td>
                  <td>
                    <button className="btn btn-danger-ghost btn-sm" disabled={deletingId != null}
                      onClick={() => remove(r)}>{deletingId === r.id ? '삭제 중…' : '삭제'}</button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </LiveBlock>
        {!list.error && (
          <div className="table-foot">
            <span style={{ fontSize: 13, color: 'var(--text-3)' }}>
              {list.data ? `${fmtNum(filtered.length)}개${scopeFilter ? ` (전체 ${fmtNum(rows.length)}개 중)` : ''}` : ''}
            </span>
          </div>
        )}
      </div>

      {creating && (
        <BanWordCreateDrawer existing={rows} onClose={() => setCreating(false)}
          onCreated={(word) => { setCreating(false); setFlash({ tone: 'info', text: `"${word}"를 등록했습니다.` }); list.reload(); }}/>
      )}
    </div>
  );
};

const BanWordCreateDrawer = ({ existing, onClose, onCreated }) => {
  const [word, setWord] = React.useState('');
  const [scope, setScope] = React.useState('ALL');
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState('');
  const w = word.trim();
  const tooLong = w.length > BANWORD_MAX;
  // 서버 중복검사가 없어 화면이 경고(막진 않음). 같은 범위에 이미 있으면 알립니다.
  const dup = w && existing.some((r) => r.word === w && (r.scope || 'ALL') === scope);
  const problem = !w ? '단어를 입력하세요.' : tooLong ? `단어는 ${BANWORD_MAX}자까지입니다. (현재 ${w.length}자)` : null;

  const submit = async () => {
    if (problem) { setError(problem); return; }
    const scopeLabel = banwordScopeLabel(scope);
    if (!window.confirm(`금칙어를 등록할까요?\n\n단어: ${w}\n범위: ${scopeLabel}${dup ? '\n\n⚠ 같은 범위에 이미 등록된 단어입니다. 그래도 등록하면 중복으로 쌓입니다.' : ''}`)) return;
    setBusy(true); setError('');
    try {
      await api.live.banwords.create({ word: w, scope });
      onCreated(w);
    } catch (e) { setError(errorText(e)); }
    finally { setBusy(false); }
  };

  return (
    <Drawer open onClose={onClose} title="금칙어 등록"
      footer={<>
        <button className="btn btn-primary" disabled={busy || !!problem} onClick={submit}>{busy ? '등록 중…' : '등록'}</button>
        <button className="btn btn-ghost" onClick={onClose}>닫기</button>
      </>}>
      {error && <div style={{ marginBottom: 12 }}><Notice tone="danger">등록하지 못했습니다: {error}</Notice></div>}
      <div style={{ display: 'grid', gap: 14 }}>
        <div>
          <label style={{ fontSize: 13, fontWeight: 600 }}>단어</label>
          <input className="input" style={{ width: '100%', marginTop: 4 }} maxLength={BANWORD_MAX}
            value={word} onChange={(e) => setWord(e.target.value)} disabled={busy} placeholder="막을 단어"/>
          <div style={{ textAlign: 'right', fontSize: 11.5, color: tooLong ? 'var(--danger)' : 'var(--text-3)' }}>{w.length}/{BANWORD_MAX}</div>
        </div>
        <div>
          <label style={{ fontSize: 13, fontWeight: 600 }}>적용 범위</label>
          <select className="select" style={{ width: '100%', marginTop: 4 }} value={scope} onChange={(e) => setScope(e.target.value)} disabled={busy}>
            {BANWORD_SCOPES.map((s) => <option key={s.value} value={s.value}>{s.label}</option>)}
          </select>
          <div style={{ fontSize: 12, color: 'var(--text-3)', marginTop: 4 }}>
            전체는 닉네임과 리뷰 모두에서, 닉네임만은 닉네임에서만 막습니다.
          </div>
        </div>
        {dup && <Notice tone="warn">같은 범위에 "{w}"가 이미 등록돼 있습니다. 등록하면 중복으로 쌓입니다(서버가 막지 않습니다).</Notice>}
      </div>
    </Drawer>
  );
};

Object.assign(window, { BanWords, BanWordCreateDrawer, banwordScopeLabel, BANWORD_SCOPES, BANWORD_MAX });
