// ── AdminPage.jsx ──────────────────────────────────────────────
// Admin dashboard: login, submission list, settings

function getFirebaseAdminAuth() {
  return window.CIQ_FIREBASE_AUTH || null;
}

function AdminLogin({ onLogin, initialError }) {
  const [loading, setLoading] = React.useState(false);
  const [status, setStatus] = React.useState('Firebase Auth 프로젝트 auth-f7b2b를 사용합니다.');
  const [err, setErr] = React.useState(initialError || '');

  React.useEffect(() => {
    setErr(initialError || '');
  }, [initialError]);

  async function handleLogin() {
    const firebaseAuth = getFirebaseAdminAuth();
    if (!firebaseAuth) {
      setErr('Firebase 로그인 설정을 찾을 수 없습니다.');
      return;
    }

    setLoading(true);
    setErr('');
    setStatus('Google 로그인 창을 여는 중입니다.');
    try {
      const user = await firebaseAuth.signInWithGoogle();
      setStatus('로그인이 완료되었습니다.');
      onLogin(user);
    } catch (error) {
      setErr(firebaseAuth.loginMessage(error));
      setStatus('허용된 Google 계정으로 다시 시도해 주세요.');
    } finally {
      setLoading(false);
    }
  }

  return (
    <div className="animate-fade-in" style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--bg-color)', padding: '1.5rem' }}>
      <div className="card" style={{ width: '100%', maxWidth: '420px', padding: '3rem 2rem' }}>
        <div style={{ textAlign: 'center', marginBottom: '2rem' }}>
          <div style={{ fontSize: '2.5rem', marginBottom: '0.75rem', background: 'linear-gradient(135deg, var(--primary), #3b82f6)', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent' }}>⚓</div>
          <h1 style={{ fontSize: '1.5rem', fontWeight: '800', color: 'var(--text-primary)' }}>관리자 로그인</h1>
          <p style={{ fontSize: '0.875rem', color: 'var(--text-muted)', marginTop: '0.25rem' }}>Yacht CIQ 서류 지원 시스템</p>
        </div>
        <div style={{ background: '#f8fafc', borderRadius: 'var(--radius-md)', padding: '1rem', fontSize: '0.8125rem', color: 'var(--text-secondary)', lineHeight: '1.6', border: '1px solid var(--border)', marginBottom: '1rem' }}>
          허용된 Google 관리자 계정으로만 접속할 수 있습니다.
        </div>
        {err && <p style={{ color: '#ef4444', fontSize: '0.8125rem', marginBottom: '1rem', textAlign: 'center' }}>{err}</p>}
        <button onClick={handleLogin} disabled={loading} className="btn btn-primary" style={{ width: '100%', padding: '0.875rem', opacity: loading ? 0.7 : 1 }}>
          {loading ? 'Google 로그인 확인 중...' : 'Google로 로그인'}
        </button>
        <p role="status" aria-live="polite" style={{ textAlign: 'center', marginTop: '1.5rem', fontSize: '0.75rem', color: 'var(--text-muted)' }}>
          {status}
        </p>
      </div>
    </div>
  );
}

const STATUS_LABELS = {
  received: '접수됨',
  reviewing: '검토 중',
  missing_info: '보완 요청',
  validated: '자동화 가능',
  generated: '서류 생성',
  packaged: '패키지 완료',
  submitted: '제출 완료',
  archived: '보관',
};
const STATUS_COLORS = {
  received: 'badge-yellow',
  reviewing: 'badge-blue',
  missing_info: 'badge-red',
  validated: 'badge-green',
  generated: 'badge-blue',
  packaged: 'badge-green',
  submitted: 'badge-green',
  archived: 'badge-gray',
};

function adminNowIso() {
  return new Date().toISOString();
}

function adminEmptyDraftData() {
  return {
    applicant: {},
    voyage: {},
    vessel: {},
    captain: { crew: [] },
    crew: { crew: [{}] },
    consent: {},
  };
}

function adminNormalizeDraftRecord(id, raw = {}) {
  const data = raw.data || adminEmptyDraftData();
  return {
    id,
    docName: raw.docName || '',
    pin: String(raw.pin || ''),
    data,
    files: raw.files || {},
    revisions: Array.isArray(raw.revisions) ? raw.revisions : [],
    createdAt: raw.createdAt || raw.updatedAt || adminNowIso(),
    updatedAt: raw.updatedAt || raw.createdAt || adminNowIso(),
  };
}

function adminGetDraftRecords() {
  const records = [];
  for (let i = 0; i < localStorage.length; i++) {
    const key = localStorage.key(i);
    if (!key || !key.startsWith('ciq_draft_')) continue;
    try {
      const id = key.replace('ciq_draft_', '');
      records.push(adminNormalizeDraftRecord(id, JSON.parse(localStorage.getItem(key))));
    } catch {}
  }
  return records.sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt));
}

function adminSaveDraftRecord(record) {
  localStorage.setItem(`ciq_draft_${record.id}`, JSON.stringify(record));
}

function adminDraftKey(id) {
  return `ciq_draft_${id}`;
}

function adminFormatDate(value) {
  if (!value) return '미기록';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return date.toLocaleString('ko-KR', { dateStyle: 'short', timeStyle: 'short' });
}

function AdminDashboard({ adminUser, onLogout }) {
  const [tab, setTab] = React.useState('submissions'); // 'submissions' | 'documents' | 'settings'
  const [selected, setSelected] = React.useState(null);
  const [search, setSearch] = React.useState('');
  const [gaId, setGaId] = React.useState('G-XXXXXXXXXX');
  const [clarityId, setClarityId] = React.useState('');
  const [adminNotifyEmail, setAdminNotifyEmail] = React.useState(adminUser.email);
  const [saved, setSaved] = React.useState(false);
  const [draftVersion, setDraftVersion] = React.useState(0);
  const [docForm, setDocForm] = React.useState({ originalId: '', id: '', docName: '', pin: '' });
  const [docMessage, setDocMessage] = React.useState('');
  const [submissions, setSubmissions] = React.useState([]);
  const [submissionLoading, setSubmissionLoading] = React.useState(false);
  const [submissionError, setSubmissionError] = React.useState('');
  const [statusDraft, setStatusDraft] = React.useState('');

  const localDrafts = React.useMemo(() => adminGetDraftRecords(), [draftVersion]);

  React.useEffect(() => {
    loadSubmissions();
  }, [adminUser.idToken]);

  const filtered = submissions.filter(s =>
    !search || String(s.name || '').includes(search) || String(s.vessel || '').includes(search) || String(s.id || '').includes(search.toUpperCase())
  );

  async function adminFetch(url, options = {}) {
    const headers = { ...(options.headers || {}), Authorization: `Bearer ${adminUser.idToken}` };
    const response = await fetch(url, { ...options, headers });
    if (!response.ok) {
      let message = '관리자 요청에 실패했습니다.';
      try {
        const body = await response.json();
        message = body.error || message;
      } catch {}
      throw new Error(message);
    }
    return response;
  }

  async function loadSubmissions() {
    setSubmissionLoading(true);
    setSubmissionError('');
    try {
      const response = await adminFetch('submit.php?action=list');
      const data = await response.json();
      setSubmissions(data.items || []);
    } catch (error) {
      setSubmissionError(error.message || '접수 목록을 불러오지 못했습니다.');
    } finally {
      setSubmissionLoading(false);
    }
  }

  async function downloadSubmission(id) {
    try {
      const response = await adminFetch(`submit.php?action=download&id=${encodeURIComponent(id)}`);
      const blob = await response.blob();
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = `${id}.zip`;
      document.body.appendChild(link);
      link.click();
      link.remove();
      URL.revokeObjectURL(url);
    } catch (error) {
      setSubmissionError(error.message || '자동화 ZIP을 내려받지 못했습니다.');
    }
  }

  async function updateSubmissionStatus(id, status) {
    try {
      const response = await adminFetch('submit.php?action=status', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ id, status }),
      });
      const data = await response.json();
      setSubmissions(items => items.map(item => item.id === id ? data.item : item));
      setSelected(data.item);
      setStatusDraft(status);
    } catch (error) {
      setSubmissionError(error.message || '상태를 변경하지 못했습니다.');
    }
  }

  function saveSettings() {
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  }

  function resetDocForm() {
    setDocForm({ originalId: '', id: '', docName: '', pin: '' });
    setDocMessage('');
  }

  function editDocument(record) {
    setDocForm({ originalId: record.id, id: record.id, docName: record.docName || '', pin: record.pin || '' });
    setDocMessage('');
    setTab('documents');
  }

  function saveDocument(e) {
    e.preventDefault();
    const id = docForm.id.trim();
    const docName = docForm.docName.trim();
    const pin = docForm.pin.trim();
    const originalId = docForm.originalId;
    if (!id || !docName || !pin) {
      setDocMessage('저장 ID, 서류 이름, 비밀번호/PIN을 모두 입력해 주세요.');
      return;
    }
    if (id.includes('/') || id.includes('\\')) {
      setDocMessage('저장 ID에는 / 또는 \\ 문자를 사용할 수 없습니다.');
      return;
    }
    const duplicate = localStorage.getItem(adminDraftKey(id));
    if (duplicate && id !== originalId) {
      setDocMessage('이미 사용 중인 저장 ID입니다. 다른 ID를 입력해 주세요.');
      return;
    }

    let existing = null;
    try {
      const raw = originalId ? localStorage.getItem(adminDraftKey(originalId)) : localStorage.getItem(adminDraftKey(id));
      existing = raw ? adminNormalizeDraftRecord(originalId || id, JSON.parse(raw)) : null;
    } catch {}

    const record = {
      id,
      docName,
      pin,
      data: existing?.data || adminEmptyDraftData(),
      files: existing?.files || {},
      revisions: existing?.revisions || [],
      createdAt: existing?.createdAt || adminNowIso(),
      updatedAt: adminNowIso(),
    };
    adminSaveDraftRecord(record);
    if (originalId && originalId !== id) {
      localStorage.removeItem(adminDraftKey(originalId));
    }
    setDocForm({ originalId: id, id, docName, pin });
    setDraftVersion(v => v + 1);
    setDocMessage(originalId ? '저장 ID, 서류 이름, 비밀번호/PIN을 수정했습니다.' : '새 서류를 생성했습니다.');
  }

  return (
    <div className="animate-fade-in" style={{ minHeight: '100vh', background: 'var(--bg-color)', fontFamily: 'inherit' }}>
      {/* Top bar */}
      <div style={{ background: '#0f172a', padding: '0 1.5rem', display: 'flex', alignItems: 'center', justifyContent: 'space-between', height: '64px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem' }}>
          <span style={{ fontSize: '1.5rem' }}>⚓</span>
          <span style={{ color: 'white', fontWeight: '700', fontSize: '1rem', letterSpacing: '-0.5px' }}>Yacht CIQ Admin</span>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
          <span style={{ color: '#94a3b8', fontSize: '0.875rem' }}>{adminUser.email}</span>
          <button onClick={onLogout} style={{ background: 'rgba(255,255,255,0.1)', border: 'none', color: '#e2e8f0', borderRadius: 'var(--radius-md)', padding: '0.5rem 1rem', cursor: 'pointer', fontFamily: 'inherit', fontSize: '0.8125rem', fontWeight: '500', transition: 'background 0.2s' }}
            onMouseEnter={e => e.target.style.background = 'rgba(255,255,255,0.2)'}
            onMouseLeave={e => e.target.style.background = 'rgba(255,255,255,0.1)'}>
            로그아웃
          </button>
        </div>
      </div>

      {/* Tab nav */}
      <div style={{ background: 'white', borderBottom: '1px solid var(--border)', padding: '0 1.5rem', display: 'flex' }}>
        {[
          { key: 'submissions', label: '📋 접수 목록' },
          { key: 'documents', label: '🗂️ 서류 관리' },
          { key: 'settings', label: '⚙️ 설정' },
        ].map(t => (
          <button key={t.key} onClick={() => setTab(t.key)} style={{
            padding: '1rem 1.5rem', background: 'none', border: 'none', fontFamily: 'inherit',
            fontWeight: tab === t.key ? '600' : '500', fontSize: '0.9375rem', cursor: 'pointer',
            color: tab === t.key ? 'var(--primary)' : 'var(--text-secondary)',
            borderBottom: tab === t.key ? '2px solid var(--primary)' : '2px solid transparent',
            transition: 'all 0.2s', marginBottom: '-1px'
          }}>{t.label}</button>
        ))}
      </div>

      <div style={{ padding: '2rem 1.5rem', maxWidth: '1100px', margin: '0 auto' }}>
        {tab === 'submissions' && (
          <div className="animate-fade-in">
            {/* Stats */}
            <div className="grid grid-cols-4 mb-8">
              {[
                { label: '전체 접수', value: submissions.length, color: '#0f172a' },
                { label: '검토 대기', value: submissions.filter(s=>s.status==='received').length, color: '#b91c1c' },
                { label: '검토 중', value: submissions.filter(s=>s.status==='reviewing').length, color: '#0284c7' },
                { label: '자동화 가능', value: submissions.filter(s=>s.status==='validated').length, color: '#15803d' },
              ].map(s => (
                <div key={s.label} className="card" style={{ padding: '1.5rem' }}>
                  <div style={{ fontSize: '2rem', fontWeight: '800', color: s.color, lineHeight: '1' }}>{s.value}</div>
                  <div style={{ fontSize: '0.875rem', color: 'var(--text-secondary)', marginTop: '0.5rem', fontWeight: '500' }}>{s.label}</div>
                </div>
              ))}
            </div>

            {/* Search */}
            <div className="mb-4">
              <input value={search} onChange={e => setSearch(e.target.value)} placeholder="이름, 선박명, 접수번호 검색..."
                className="form-control" style={{ width: '300px' }} />
            </div>
            {submissionError && (
              <div className="card mb-4" style={{ background: '#fef2f2', border: '1px solid #fecaca', color: '#b91c1c', fontSize: '0.875rem' }}>
                {submissionError}
              </div>
            )}
            {submissionLoading && (
              <div className="card mb-4" style={{ color: 'var(--text-secondary)', fontSize: '0.875rem' }}>
                접수 목록을 불러오는 중입니다.
              </div>
            )}

            {/* Table */}
            <div className="card" style={{ padding: '0', overflow: 'hidden' }}>
              <table style={{ width: '100%', borderCollapse: 'collapse', textAlign: 'left' }}>
                <thead>
                  <tr style={{ background: '#f8fafc', borderBottom: '1px solid var(--border)' }}>
                    {['접수번호','접수일','신청자','선박명','항로','파일','상태',''].map(h => (
                      <th key={h} style={{ padding: '1rem', fontWeight: '600', color: 'var(--text-muted)', fontSize: '0.8125rem' }}>{h}</th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {filtered.map((s, i) => (
                    <tr key={s.id} style={{ borderBottom: i < filtered.length-1 ? '1px solid #f1f5f9' : 'none', transition: 'background 0.2s' }} onMouseEnter={e=>e.currentTarget.style.background='#f8fafc'} onMouseLeave={e=>e.currentTarget.style.background='transparent'}>
                      <td style={{ padding: '1rem', fontFamily: 'monospace', fontWeight: '700', color: 'var(--primary)', fontSize: '0.875rem' }}>{s.id}</td>
                      <td style={{ padding: '1rem', color: 'var(--text-secondary)', fontSize: '0.875rem' }}>{s.date}</td>
                      <td style={{ padding: '1rem', fontWeight: '600', color: 'var(--text-primary)', fontSize: '0.875rem' }}>{s.name}</td>
                      <td style={{ padding: '1rem', color: 'var(--text-secondary)', fontSize: '0.875rem' }}>{s.vessel}</td>
                      <td style={{ padding: '1rem', color: 'var(--text-secondary)', fontSize: '0.875rem' }}>{s.route}</td>
                      <td style={{ padding: '1rem', color: 'var(--text-secondary)', fontSize: '0.875rem' }}>{s.files}건</td>
                      <td style={{ padding: '1rem' }}>
                        <span className={`badge ${STATUS_COLORS[s.status] || 'badge-blue'}`}>
                          {STATUS_LABELS[s.status] || s.status}
                        </span>
                      </td>
                      <td style={{ padding: '1rem' }}>
                        <button onClick={() => { setSelected(s); setStatusDraft(s.status || 'received'); }} className="btn btn-outline" style={{ padding: '0.375rem 0.75rem', fontSize: '0.75rem' }}>상세</button>
                      </td>
                    </tr>
                  ))}
                  {filtered.length === 0 && !submissionLoading && (
                    <tr>
                      <td colSpan="8" style={{ padding: '2rem', color: 'var(--text-secondary)', textAlign: 'center', fontSize: '0.9375rem' }}>
                        저장된 접수가 없습니다.
                      </td>
                    </tr>
                  )}
                </tbody>
              </table>
            </div>

            {localDrafts.length > 0 && (
              <div className="card mt-8" style={{ background: '#fffbeb', border: '1px solid #fcd34d' }}>
                <h3 style={{ fontSize: '1rem', fontWeight: '700', color: '#92400e', marginBottom: '1rem' }}>임시저장 중인 신청서 ({localDrafts.length}건)</h3>
                <div style={{ display: 'grid', gap: '0.5rem' }}>
                  {localDrafts.map(d => (
                    <div key={d.id} style={{ fontSize: '0.875rem', color: '#92400e', background: 'white', padding: '0.75rem 1rem', borderRadius: 'var(--radius-md)', border: '1px solid #fde68a' }}>
                      <strong style={{ fontFamily: 'monospace', letterSpacing: '1px' }}>{d.id}</strong> <span style={{ opacity: 0.5, margin: '0 0.5rem' }}>|</span> {d.docName || '서류 이름 미설정'} <span style={{ opacity: 0.5, margin: '0 0.5rem' }}>|</span> {d.data?.applicant?.name || '이름 미입력'}
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        )}

        {tab === 'documents' && (
          <div className="animate-fade-in">
            <div className="card mb-8">
              <div style={{ display: 'flex', justifyContent: 'space-between', gap: '1rem', alignItems: 'flex-start', marginBottom: '1.5rem', flexWrap: 'wrap' }}>
                <div>
                  <h3 style={{ fontSize: '1.125rem', fontWeight: '700', color: 'var(--text-primary)', marginBottom: '0.375rem' }}>서류 관리</h3>
                  <p style={{ fontSize: '0.875rem', color: 'var(--text-secondary)', lineHeight: '1.6' }}>
                    고객에게 안내할 서류 이름과 불러오기 비밀번호/PIN을 생성하거나 수정합니다.
                  </p>
                </div>
                {docForm.originalId && (
                  <button type="button" onClick={resetDocForm} className="btn btn-outline" style={{ padding: '0.625rem 1rem' }}>
                    신규 생성으로 전환
                  </button>
                )}
              </div>

              <form onSubmit={saveDocument}>
                <div className="grid grid-cols-2">
                  <div>
                    <label className="form-label" htmlFor="admin-doc-id">저장 ID</label>
                    <input id="admin-doc-id" value={docForm.id} onChange={e => setDocForm(p => ({ ...p, id: e.target.value }))}
                      placeholder="예: TSUSHIMA-2026-01" className="form-control" style={{ fontFamily: 'monospace' }} />
                  </div>
                  <div>
                    <label className="form-label" htmlFor="admin-doc-name">서류 이름</label>
                    <input id="admin-doc-name" value={docForm.docName} onChange={e => setDocForm(p => ({ ...p, docName: e.target.value }))}
                      placeholder="예: 홍길동 2026 쓰시마 출항" className="form-control" />
                  </div>
                </div>
                <div className="grid grid-cols-2" style={{ marginTop: '1rem' }}>
                  <div>
                    <label className="form-label" htmlFor="admin-doc-pin">비밀번호/PIN</label>
                    <input id="admin-doc-pin" value={docForm.pin} onChange={e => setDocForm(p => ({ ...p, pin: e.target.value }))}
                      placeholder="고객에게 안내할 PIN" className="form-control" />
                  </div>
                </div>
                {docMessage && (
                  <p style={{ color: docMessage.includes('입력') ? '#b91c1c' : '#15803d', fontSize: '0.875rem', marginTop: '1rem', fontWeight: '600' }}>
                    {docMessage}
                  </p>
                )}
                <button type="submit" className="btn btn-primary" style={{ marginTop: '1.25rem', background: '#0f172a' }}>
                  {docForm.originalId ? '수정 저장' : '신규 서류 생성'}
                </button>
              </form>
            </div>

            <div className="card" style={{ padding: '0', overflow: 'hidden' }}>
              <div style={{ padding: '1rem 1.25rem', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '1rem', flexWrap: 'wrap' }}>
                <h3 style={{ fontSize: '1rem', fontWeight: '700', color: 'var(--text-primary)' }}>저장된 서류 목록</h3>
                <span style={{ fontSize: '0.8125rem', color: 'var(--text-muted)' }}>{localDrafts.length}건</span>
              </div>
              {localDrafts.length === 0 ? (
                <div style={{ padding: '2rem', color: 'var(--text-secondary)', textAlign: 'center', fontSize: '0.9375rem' }}>
                  아직 생성된 서류가 없습니다.
                </div>
              ) : (
                <div style={{ overflowX: 'auto' }}>
                  <table style={{ width: '100%', minWidth: '820px', borderCollapse: 'collapse', textAlign: 'left' }}>
                    <thead>
                      <tr style={{ background: '#f8fafc', borderBottom: '1px solid var(--border)' }}>
                        {['저장 ID','서류 이름','신청자','선박명','수정일','비밀번호',''].map(h => (
                          <th key={h} style={{ padding: '1rem', fontWeight: '600', color: 'var(--text-muted)', fontSize: '0.8125rem' }}>{h}</th>
                        ))}
                      </tr>
                    </thead>
                    <tbody>
                      {localDrafts.map((record, i) => {
                        const vessel = [record.data?.vessel?.vesselNameKo, record.data?.vessel?.vesselNameEn].filter(Boolean).join(' / ');
                        return (
                          <tr key={record.id} style={{ borderBottom: i < localDrafts.length-1 ? '1px solid #f1f5f9' : 'none' }}>
                            <td style={{ padding: '1rem', fontFamily: 'monospace', fontWeight: '700', color: 'var(--primary)', fontSize: '0.875rem' }}>{record.id}</td>
                            <td style={{ padding: '1rem', fontWeight: '600', color: 'var(--text-primary)', fontSize: '0.875rem' }}>{record.docName || '서류 이름 미설정'}</td>
                            <td style={{ padding: '1rem', color: 'var(--text-secondary)', fontSize: '0.875rem' }}>{record.data?.applicant?.name || '미입력'}</td>
                            <td style={{ padding: '1rem', color: 'var(--text-secondary)', fontSize: '0.875rem' }}>{vessel || '미입력'}</td>
                            <td style={{ padding: '1rem', color: 'var(--text-secondary)', fontSize: '0.875rem', whiteSpace: 'nowrap' }}>{adminFormatDate(record.updatedAt)}</td>
                            <td style={{ padding: '1rem' }}>
                              <span className={`badge ${record.pin ? 'badge-green' : 'badge-red'}`}>
                                {record.pin ? '설정됨' : '미설정'}
                              </span>
                            </td>
                            <td style={{ padding: '1rem' }}>
                              <button onClick={() => editDocument(record)} className="btn btn-outline" style={{ padding: '0.375rem 0.75rem', fontSize: '0.75rem' }}>수정</button>
                            </td>
                          </tr>
                        );
                      })}
                    </tbody>
                  </table>
                </div>
              )}
            </div>
          </div>
        )}

        {tab === 'settings' && (
          <div className="animate-fade-in" style={{ maxWidth: '600px' }}>
            <div className="card mb-6">
              <h3 style={{ fontSize: '1.125rem', fontWeight: '700', color: 'var(--text-primary)', marginBottom: '1.5rem' }}>📊 분석 도구 설정</h3>
              <div className="mb-4">
                <label className="form-label">Google Analytics 4 측정 ID</label>
                <input value={gaId} onChange={e => setGaId(e.target.value)} placeholder="G-XXXXXXXXXX"
                  className="form-control" style={{ fontFamily: 'monospace' }} />
              </div>
              <div className="mb-0">
                <label className="form-label">Microsoft Clarity 프로젝트 ID</label>
                <input value={clarityId} onChange={e => setClarityId(e.target.value)} placeholder="xxxxxxxxxx"
                  className="form-control" style={{ fontFamily: 'monospace' }} />
              </div>
            </div>

            <div className="card mb-6">
              <h3 style={{ fontSize: '1.125rem', fontWeight: '700', color: 'var(--text-primary)', marginBottom: '1.5rem' }}>📧 이메일 알림 설정</h3>
              <div className="mb-4">
                <label className="form-label">관리자 알림 수신 이메일</label>
                <input value={adminNotifyEmail} onChange={e => setAdminNotifyEmail(e.target.value)} type="email"
                  className="form-control" />
              </div>
              <div style={{ background: '#f8fafc', borderRadius: 'var(--radius-md)', padding: '1rem', fontSize: '0.8125rem', color: 'var(--text-secondary)', lineHeight: '1.6', border: '1px solid var(--border)' }}>
                ℹ️ 고객 확인 메일에는 접수번호와 안내 사항만 포함됩니다.<br/>
                여권번호 등 민감 정보는 메일에 포함되지 않습니다.
              </div>
            </div>

            <div className="card mb-6">
              <h3 style={{ fontSize: '1.125rem', fontWeight: '700', color: 'var(--text-primary)', marginBottom: '1.25rem' }}>🔒 보안 설정</h3>
              {[
                { label: 'HTTPS 강제 리디렉션', on: true },
                { label: '업로드 파일 직접 URL 접근 차단', on: true },
                { label: '허용 확장자 제한 (JPG·PNG·PDF)', on: true },
                { label: '접수 JSON 외부 노출 차단', on: true },
              ].map((item, idx, arr) => (
                <div key={item.label} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '1rem 0', borderBottom: idx === arr.length - 1 ? 'none' : '1px solid var(--border)' }}>
                  <span style={{ fontSize: '0.875rem', color: 'var(--text-primary)', fontWeight: '500' }}>{item.label}</span>
                  <span className={`badge ${item.on ? 'badge-green' : 'badge-red'}`}>
                    {item.on ? '✓ 적용됨' : '⚠ 미적용'}
                  </span>
                </div>
              ))}
            </div>

            <button onClick={saveSettings} className={`btn ${saved ? 'btn-outline' : 'btn-primary'}`} style={{
              width: '100%', background: saved ? '#15803d' : '', borderColor: saved ? '#15803d' : '', color: saved ? 'white' : ''
            }}>
              {saved ? '✓ 설정이 저장되었습니다' : '설정 저장하기'}
            </button>
          </div>
        )}
      </div>

      {/* Detail modal */}
      {selected && (
        <div style={{ position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.6)', backdropFilter: 'blur(4px)', zIndex: 200, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '1.5rem' }} onClick={() => setSelected(null)}>
          <div className="card animate-fade-in" style={{ width: '100%', maxWidth: '500px', padding: '2rem' }} onClick={e => e.stopPropagation()}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '1.5rem' }}>
              <div>
                <h2 style={{ fontSize: '1.25rem', fontWeight: '800', color: 'var(--text-primary)', marginBottom: '0.25rem' }}>{selected.name} — {selected.vessel}</h2>
                <span style={{ fontFamily: 'monospace', fontSize: '0.875rem', color: 'var(--primary)', fontWeight: '600' }}>{selected.id}</span>
              </div>
              <button onClick={() => setSelected(null)} style={{ background: 'none', border: 'none', color: 'var(--text-muted)', fontSize: '1.5rem', cursor: 'pointer', lineHeight: '1' }}>✕</button>
            </div>

            <div style={{ background: '#f8fafc', borderRadius: 'var(--radius-md)', padding: '1rem', marginBottom: '1.5rem', border: '1px solid var(--border)' }}>
              {[
                { label: '접수일', value: selected.date },
                { label: '항로', value: selected.route },
                { label: '첨부파일', value: `${selected.files}건` },
                { label: '상태', value: <span className={`badge ${STATUS_COLORS[selected.status] || 'badge-blue'}`}>{STATUS_LABELS[selected.status] || selected.status}</span> },
                { label: '자동화 폴더', value: selected.project_path || '미기록' },
              ].map((row, idx, arr) => (
                <div key={row.label} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '0.75rem 0', borderBottom: idx === arr.length - 1 ? 'none' : '1px solid var(--border)', fontSize: '0.875rem' }}>
                  <span style={{ color: 'var(--text-secondary)', fontWeight: '500' }}>{row.label}</span>
                  <span style={{ fontWeight: '600', color: 'var(--text-primary)' }}>{row.value}</span>
                </div>
              ))}
            </div>

            <div style={{ display: 'flex', gap: '0.75rem' }}>
              <select value={statusDraft || selected.status || 'received'} onChange={e => setStatusDraft(e.target.value)} className="form-control" style={{ flex: 1 }}>
                <option value="received">접수됨</option>
                <option value="reviewing">검토 중</option>
                <option value="missing_info">보완 요청</option>
                <option value="validated">자동화 가능</option>
                <option value="generated">서류 생성</option>
                <option value="packaged">패키지 완료</option>
                <option value="submitted">제출 완료</option>
                <option value="archived">보관</option>
              </select>
              <button onClick={() => updateSubmissionStatus(selected.id, statusDraft || selected.status || 'received')} className="btn btn-primary" style={{ whiteSpace: 'nowrap', background: '#0f172a' }}>상태 변경</button>
              <button onClick={() => downloadSubmission(selected.id)} className="btn btn-outline" style={{ whiteSpace: 'nowrap' }}>자동화 ZIP</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function AdminLoading() {
  return (
    <div className="animate-fade-in" style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--bg-color)', padding: '1.5rem' }}>
      <div className="card" style={{ width: '100%', maxWidth: '420px', padding: '2rem', textAlign: 'center' }}>
        <div style={{ fontSize: '2rem', marginBottom: '1rem' }}>⚓</div>
        <h1 style={{ fontSize: '1.25rem', fontWeight: '800', color: 'var(--text-primary)', marginBottom: '0.5rem' }}>관리자 로그인 확인 중</h1>
        <p style={{ fontSize: '0.875rem', color: 'var(--text-secondary)' }}>Firebase Auth 세션을 확인하고 있습니다.</p>
      </div>
    </div>
  );
}

function AdminPage() {
  const [checkingAuth, setCheckingAuth] = React.useState(true);
  const [adminUser, setAdminUser] = React.useState(null);
  const [authError, setAuthError] = React.useState('');

  React.useEffect(() => {
    const firebaseAuth = getFirebaseAdminAuth();
    if (!firebaseAuth) {
      setAuthError('Firebase 로그인 설정을 찾을 수 없습니다.');
      setCheckingAuth(false);
      return;
    }

    let active = true;
    let unsubscribe = null;
    firebaseAuth.listen(user => {
      if (!active) return;
      setAdminUser(user);
      setCheckingAuth(false);
    }).then(stop => {
      unsubscribe = stop;
    }).catch(error => {
      if (!active) return;
      setAuthError(firebaseAuth.loginMessage(error));
      setCheckingAuth(false);
    });

    return () => {
      active = false;
      if (unsubscribe) unsubscribe();
    };
  }, []);

  async function handleLogout() {
    const firebaseAuth = getFirebaseAdminAuth();
    if (firebaseAuth) await firebaseAuth.signOutAdmin();
    setAdminUser(null);
  }

  if (checkingAuth) return <AdminLoading />;
  return adminUser
    ? <AdminDashboard adminUser={adminUser} onLogout={handleLogout} />
    : <AdminLogin initialError={authError} onLogin={setAdminUser} />;
}

Object.assign(window, { AdminPage });
