const { useState, useEffect } = React;

// ── API helper ────────────────────────────────────────
window.api = {
  async req(method, path, body) {
    const token = localStorage.getItem('token');
    const opts = {
      method,
      headers: {
        ...(token ? { Authorization: `Bearer ${token}` } : {}),
        ...(body ? { 'Content-Type': 'application/json' } : {})
      },
      ...(body ? { body: JSON.stringify(body) } : {})
    };
    const res = await fetch(path, opts);
    const data = await res.json();
    if (!res.ok) throw new Error(data.error || 'Request failed');
    return data;
  },
  get: (path) => window.api.req('GET', path),
  post: (path, body) => window.api.req('POST', path, body),
  put: (path, body) => window.api.req('PUT', path, body),
  del: (path) => window.api.req('DELETE', path)
};

// ── Marked setup ──────────────────────────────────────
marked.setOptions({ breaks: true, gfm: true });

// ── Settings page ─────────────────────────────────────
function SettingsPage({ config, user, onConfigSave, onNavigate }) {
  const [worldName, setWorldName] = useState(config.worldName || '');
  const [tagline, setTagline]     = useState(config.tagline || '');
  const [pinnedInput, setPinnedInput] = useState((config.pinnedPages || []).join(', '));
  const [saving, setSaving]       = useState(false);
  const [msg, setMsg]             = useState('');
  const [users, setUsers]         = useState([]);
  const [newUsername, setNewUsername] = useState('');
  const [newPassword, setNewPassword] = useState('');
  const [newRole, setNewRole]     = useState('viewer');
  const [userMsg, setUserMsg]     = useState('');

  useEffect(() => {
    window.api.get('/api/auth/users').then(setUsers).catch(() => {});
  }, []);

  async function saveConfig() {
    setSaving(true); setMsg('');
    try {
      const pinnedPages = pinnedInput.split(',').map(s => s.trim()).filter(Boolean);
      await onConfigSave({ worldName, tagline, pinnedPages });
      setMsg('Saved.');
    } catch (e) { setMsg('Error: ' + e.message); }
    setSaving(false);
  }

  async function addUser() {
    setUserMsg('');
    try {
      await window.api.post('/api/auth/users', { username: newUsername, password: newPassword, role: newRole });
      setNewUsername(''); setNewPassword('');
      const updated = await window.api.get('/api/auth/users');
      setUsers(updated);
      setUserMsg('User added.');
    } catch (e) { setUserMsg('Error: ' + e.message); }
  }

  async function removeUser(username) {
    if (!confirm(`Remove user "${username}"?`)) return;
    try {
      await window.api.del('/api/auth/users/' + username);
      setUsers(users.filter(u => u.username !== username));
    } catch (e) { alert(e.message); }
  }

  return (
    <div className="settings-wrap">
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 36 }}>
        <button className="btn btn-ghost btn-sm" onClick={() => onNavigate('#/')}>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><polyline points="15 18 9 12 15 6"/></svg>
          Back
        </button>
        <h1 style={{ fontSize: '1.4rem', fontWeight: 600 }}>Settings</h1>
      </div>

      <div className="settings-section">
        <div className="settings-section-title">World</div>
        <div className="settings-section-desc">Configure how your wiki appears to visitors.</div>
        <div className="form-field">
          <label className="form-label">World name</label>
          <input className="form-input" value={worldName} onChange={e => setWorldName(e.target.value)} placeholder="e.g. The Shattered Realm" />
        </div>
        <div className="form-field">
          <label className="form-label">Tagline</label>
          <input className="form-input" value={tagline} onChange={e => setTagline(e.target.value)} placeholder="A short description of your world" />
        </div>
        <div className="form-field">
          <label className="form-label">Pinned pages (slugs, comma-separated)</label>
          <input className="form-input" value={pinnedInput} onChange={e => setPinnedInput(e.target.value)} placeholder="locations/city, factions/order" style={{ fontFamily: 'var(--font-mono)', fontSize: '13.5px' }} />
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <button className="btn btn-primary btn-sm" onClick={saveConfig} disabled={saving}>{saving ? 'Saving…' : 'Save changes'}</button>
          {msg && <span style={{ fontSize: 13, color: msg.startsWith('Error') ? 'oklch(45% 0.18 25)' : 'var(--accent)' }}>{msg}</span>}
        </div>
      </div>

      <div className="settings-divider" />

      <div className="settings-section">
        <div className="settings-section-title">Users</div>
        <div className="settings-section-desc">Manage who can access the wiki. Admins can edit; viewers can only read.</div>
        <div style={{ marginBottom: 20 }}>
          {users.map(u => (
            <div key={u.username} className="user-row">
              <div className="user-row-name">{u.username}</div>
              <div className="user-row-role">{u.role}</div>
              {u.username !== user.username && (
                <button className="btn btn-danger btn-sm" onClick={() => removeUser(u.username)}>Remove</button>
              )}
            </div>
          ))}
        </div>
        <div style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--radius-lg)', padding: '18px 20px' }}>
          <div style={{ fontSize: '13px', fontWeight: 600, marginBottom: 14 }}>Add user</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr auto', gap: 10, alignItems: 'end' }}>
            <div className="form-field" style={{ marginBottom: 0 }}>
              <label className="form-label">Username</label>
              <input className="form-input" value={newUsername} onChange={e => setNewUsername(e.target.value)} />
            </div>
            <div className="form-field" style={{ marginBottom: 0 }}>
              <label className="form-label">Password</label>
              <input className="form-input" type="password" value={newPassword} onChange={e => setNewPassword(e.target.value)} />
            </div>
            <div className="form-field" style={{ marginBottom: 0 }}>
              <label className="form-label">Role</label>
              <select className="form-input" value={newRole} onChange={e => setNewRole(e.target.value)} style={{ height: 38 }}>
                <option value="viewer">Viewer</option>
                <option value="admin">Admin</option>
              </select>
            </div>
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginTop: 14 }}>
            <button className="btn btn-primary btn-sm" onClick={addUser} disabled={!newUsername || !newPassword}>Add user</button>
            {userMsg && <span style={{ fontSize: 13, color: userMsg.startsWith('Error') ? 'oklch(45% 0.18 25)' : 'var(--accent)' }}>{userMsg}</span>}
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Setup page (first run) ────────────────────────────
function SetupPage({ onDone }) {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [confirm, setConfirm]   = useState('');
  const [error, setError]       = useState('');
  const [loading, setLoading]   = useState(false);

  async function handleSubmit(e) {
    e.preventDefault();
    if (password !== confirm) { setError('Passwords do not match'); return; }
    if (password.length < 8) { setError('Password must be at least 8 characters'); return; }
    setError(''); setLoading(true);
    try {
      const data = await window.api.post('/api/auth/setup', { username, password });
      localStorage.setItem('token', data.token);
      onDone(data);
    } catch (e) { setError(e.message); }
    setLoading(false);
  }

  return (
    <div className="setup-wrap">
      <div className="setup-card">
        <div className="setup-logo">
          <div className="setup-logo-mark">W</div>
          <span style={{ fontSize: '1.1rem', fontWeight: 600 }}>Wiki Setup</span>
        </div>
        <h1 className="setup-title">Create your admin account</h1>
        <p className="setup-desc">This is a one-time setup. You'll use these credentials to sign in and manage the wiki.</p>
        <form onSubmit={handleSubmit}>
          <div className="form-field">
            <label className="form-label">Username</label>
            <input className="form-input" value={username} onChange={e => setUsername(e.target.value)} required autoFocus />
          </div>
          <div className="form-field">
            <label className="form-label">Password</label>
            <input className="form-input" type="password" value={password} onChange={e => setPassword(e.target.value)} required />
          </div>
          <div className="form-field">
            <label className="form-label">Confirm password</label>
            <input className="form-input" type="password" value={confirm} onChange={e => setConfirm(e.target.value)} required />
            {error && <div className="form-error">{error}</div>}
          </div>
          <button type="submit" className="btn btn-primary" style={{ width: '100%', height: 40, marginTop: 8 }} disabled={loading}>
            {loading ? 'Creating…' : 'Create account & continue'}
          </button>
        </form>
      </div>
    </div>
  );
}

// ── Main App ──────────────────────────────────────────
function App() {
  const [ready, setReady]       = useState(false);
  const [isSetup, setIsSetup]   = useState(true);
  const [user, setUser]         = useState(null);
  const [config, setConfig]     = useState({ worldName: '', tagline: '', pinnedPages: [] });
  const [pages, setPages]       = useState([]);
  const [route, setRoute]       = useState(window.location.hash || '#/');
  const [loginOpen, setLoginOpen] = useState(false);
  const [searchOpen, setSearchOpen] = useState(false);

  async function loadPages() {
    try { setPages(await window.api.get('/api/pages')); } catch {}
  }

  useEffect(() => {
    async function init() {
      try {
        const status = await window.api.get('/api/status');
        if (!status.setup) { setIsSetup(false); setReady(true); return; }
        setIsSetup(true);
        const cfg = await window.api.get('/api/config');
        setConfig(cfg);
        const token = localStorage.getItem('token');
        if (token) {
          try { setUser(await window.api.get('/api/auth/me')); } catch { localStorage.removeItem('token'); }
        }
        await loadPages();
      } catch {}
      setReady(true);
    }
    init();

    const onHash = () => setRoute(window.location.hash || '#/');
    window.addEventListener('hashchange', onHash);

    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); setSearchOpen(true); }
    };
    window.addEventListener('keydown', onKey);

    return () => {
      window.removeEventListener('hashchange', onHash);
      window.removeEventListener('keydown', onKey);
    };
  }, []);

  function navigate(hash) {
    window.location.hash = hash.startsWith('#') ? hash : '#' + hash;
  }

  function handleLogin(data) {
    setUser(data);
    setLoginOpen(false);
    loadPages();
  }

  function handleLogout() {
    localStorage.removeItem('token');
    setUser(null);
    navigate('#/');
  }

  async function handleConfigSave(updates) {
    const updated = await window.api.put('/api/config', updates);
    setConfig(updated);
  }

  async function handleDelete(slug, title) {
    if (!confirm(`Delete "${title}"? This cannot be undone.`)) return;
    await window.api.del('/api/pages/' + slug);
    await loadPages();
    navigate('#/');
  }

  function handleEditorSave(savedSlug) {
    loadPages();
    navigate('#/wiki/' + savedSlug);
  }

  if (!ready) return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100vh', color: 'var(--text-muted)', fontSize: 14 }}>
      Loading…
    </div>
  );

  if (!isSetup) {
    return <SetupPage onDone={data => { setUser(data); setIsSetup(true); loadPages(); }} />;
  }

  // Parse route
  const hash = route.replace(/^#/, '') || '/';
  let view = 'home', viewSlug = '';
  if (hash.startsWith('/wiki/'))       { view = 'article'; viewSlug = hash.replace('/wiki/', ''); }
  else if (hash.startsWith('/edit/'))  { view = 'edit';    viewSlug = hash.replace('/edit/', ''); }
  else if (hash === '/edit')           { view = 'edit';    viewSlug = ''; }
  else if (hash.startsWith('/section/')) { view = 'section'; viewSlug = hash.replace('/section/', ''); }
  else if (hash === '/settings')       { view = 'settings'; }

  const worldInitial = (config.worldName || 'W')[0].toUpperCase();

  return (
    <div className="app">
      <Sidebar
        pages={pages}
        currentSlug={viewSlug}
        user={user}
        config={config}
        onNavigate={navigate}
        onSearch={() => setSearchOpen(true)}
        onNewPage={() => navigate('#/edit')}
        onSettings={() => navigate('#/settings')}
        onLogin={() => setLoginOpen(true)}
        onLogout={handleLogout}
      />

      <div className="main">
        {/* Top bar */}
        <div className="topbar">
          <button className="topbar-search-btn" onClick={() => setSearchOpen(true)}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
            Search…
            <span style={{ marginLeft: 'auto', fontSize: 11, opacity: 0.6 }}>⌘K</span>
          </button>
          <div className="topbar-actions">
            {view === 'article' && viewSlug && user?.role === 'admin' && (
              <button className="btn btn-ghost btn-sm" onClick={() => navigate('#/edit/' + viewSlug)}>
                <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
                Edit
              </button>
            )}
            {!user && (
              <button className="btn btn-ghost btn-sm" onClick={() => setLoginOpen(true)}>Sign in</button>
            )}
            {user && (
              <div className="user-chip">
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
                <span>{user.username}</span>
                <span style={{ color: 'var(--text-muted)' }}>·</span>
                <span style={{ color: 'var(--text-muted)' }}>{user.role}</span>
              </div>
            )}
          </div>
        </div>

        {/* Page area */}
        <div className="page-area">
          {view === 'home' && (
            <HomePage config={config} pages={pages} user={user} onNavigate={navigate} onEdit={slug => navigate('#/edit/' + slug)} />
          )}
          {view === 'article' && (
            <ArticlePage
              key={viewSlug}
              slug={viewSlug}
              user={user}
              onEdit={slug => navigate('#/edit/' + slug)}
              onDelete={handleDelete}
              onNavigate={navigate}
              history={[]}
              onRestore={() => {}}
            />
          )}
          {view === 'edit' && user?.role === 'admin' && (
            <Editor
              key={viewSlug || '__new'}
              slug={viewSlug || null}
              user={user}
              pages={pages}
              onSave={handleEditorSave}
              onCancel={() => viewSlug ? navigate('#/wiki/' + viewSlug) : navigate('#/')}
            />
          )}
          {view === 'edit' && !user && (
            <div className="empty-state">
              <div className="empty-state-title">Sign in required</div>
              <div className="empty-state-desc">You need to be signed in as an admin to edit pages.</div>
              <button className="btn btn-primary" style={{ marginTop: 8 }} onClick={() => setLoginOpen(true)}>Sign in</button>
            </div>
          )}
          {view === 'settings' && user?.role === 'admin' && (
            <SettingsPage config={config} user={user} onConfigSave={handleConfigSave} onNavigate={navigate} />
          )}
          {view === 'section' && (
            <div className="article-wrap" style={{ display: 'block', paddingTop: 48 }}>
              <h1 style={{ fontSize: '1.8rem', fontWeight: 600, marginBottom: 24, textTransform: 'capitalize' }}>
                {viewSlug.replace(/-/g, ' ')}
              </h1>
              <div className="page-cards">
                {pages.filter(p => p.slug.startsWith(viewSlug + '/')).map(p => (
                  <a key={p.slug} className="page-card" href={'#/wiki/' + p.slug}
                    onClick={e => { e.preventDefault(); navigate('#/wiki/' + p.slug); }}>
                    <div className="page-card-title">{p.title}</div>
                    {p.tags?.length > 0 && <div className="page-card-tags">{p.tags.map(t => <span key={t} className="tag">{t}</span>)}</div>}
                  </a>
                ))}
              </div>
            </div>
          )}
        </div>
      </div>

      {loginOpen && <LoginModal onLogin={handleLogin} onClose={() => setLoginOpen(false)} />}
      {searchOpen && <SearchOverlay onClose={() => setSearchOpen(false)} onNavigate={navigate} />}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
