// ============================================================
// LSMD — Admin (Rechte, Discord-Sync, Kanal-Konfiguration)
// ============================================================

function PermToggle({ on, onClick }) {
  return (
    <button type="button" onClick={onClick} className="grid place-items-center h-7 w-7 rounded-md transition-colors mx-auto"
      style={{ background: on ? 'var(--c-accent-soft)' : 'transparent', color: on ? 'var(--c-accent)' : 'var(--c-muted)' }}>
      <Icon name={on ? 'Check' : 'Minus'} size={16} strokeWidth={on ? 3 : 2} />
    </button>
  );
}

function DiscordChannelsPanel() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [msg, setMsg] = useState('');

  const load = async () => {
    setLoading(true);
    try {
      const d = await window.LSMD.loadDiscordAdmin();
      setData(d);
    } catch (e) {
      console.error(e);
      setMsg('Konfiguration konnte nicht geladen werden.');
    } finally {
      setLoading(false);
    }
  };

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

  const updateMod = (id, patch) => {
    setData(prev => ({
      ...prev,
      modules: prev.modules.map(m => (m.id === id ? { ...m, config: { ...m.config, ...patch } } : m)),
    }));
  };

  const save = async () => {
    setSaving(true);
    setMsg('');
    try {
      const payload = data.modules.map(m => ({
        id: m.id,
        enabled: m.config.enabled,
        channel_id: m.config.channel_id,
        post_time: m.config.post_time,
        notes: m.config.notes,
      }));
      const saved = await window.LSMD.saveDiscordModules(payload);
      setData(saved);
      setMsg('Discord-Kanäle gespeichert. Bot-Versand ist noch deaktiviert — nur Einstellungen.');
    } catch (e) {
      setMsg(e.message || 'Speichern fehlgeschlagen');
    } finally {
      setSaving(false);
    }
  };

  if (loading) return <div className="mt-6 text-muted text-sm">Discord-Konfiguration wird geladen …</div>;

  return (
    <div className="mt-6 flex flex-col gap-6">
      <Card className="p-5 border-accent/30 bg-[var(--c-accent-soft)]/30">
        <div className="flex items-start gap-3">
          <Icon name="Info" size={20} className="text-accent shrink-0 mt-0.5" />
          <div className="text-sm text-muted leading-relaxed">
            <strong className="text-ink">Kanäle für Website-Formulare:</strong> Bewerbungen und Beschwerden werden sofort in den eingetragenen Channel gepostet.
            Alle anderen Module sind vorbereitet (Versand folgt). Channel-ID: Rechtsklick auf Kanal → ID kopieren.
            Referenz: alte LSMD-Bot-Kanäle wie <span className="font-mono text-ink">tipp-des-tages</span>, <span className="font-mono text-ink">termine</span>, <span className="font-mono text-ink">meeting-abmeldung</span>, <span className="font-mono text-ink">urlaubsbeantragung</span>.
            Automatische Posts werden später aktiviert.
          </div>
        </div>
      </Card>

      <div className="flex flex-col gap-4">
        {data?.modules?.map(mod => (
          <Card key={mod.id} className="p-5">
            <div className="flex flex-wrap items-start justify-between gap-3">
              <div className="flex items-center gap-3 min-w-0">
                <div className="grid place-items-center h-10 w-10 rounded-md bg-discord/20 text-discord shrink-0">
                  <Icon name={mod.icon || 'Hash'} size={20} />
                </div>
                <div>
                  <h3 className="font-bold">{mod.label}</h3>
                  <p className="text-xs text-muted mt-0.5">Discord: #{mod.channelHint}</p>
                  <p className="text-sm text-muted mt-1 max-w-xl">{mod.description}</p>
                </div>
              </div>
              <label className="flex items-center gap-2 text-sm font-semibold shrink-0 cursor-pointer">
                <input
                  type="checkbox"
                  checked={!!mod.config.enabled}
                  onChange={e => updateMod(mod.id, { enabled: e.target.checked })}
                  className="rounded border-line"
                />
                Aktiv (später)
              </label>
            </div>
            <div className="mt-4 grid sm:grid-cols-2 lg:grid-cols-3 gap-3">
              <div>
                <label className="uplabel text-[10px]">Channel-ID</label>
                <input
                  value={mod.config.channel_id || ''}
                  onChange={e => updateMod(mod.id, { channel_id: e.target.value })}
                  placeholder="123456789012345678"
                  className="mt-1 w-full h-10 rounded-md border border-line bg-card px-3 text-sm font-mono outline-none focus:border-accent"
                />
              </div>
              {mod.fields?.includes('post_time') && (
                <div>
                  <label className="uplabel text-[10px]">Uhrzeit (Tipp)</label>
                  <input
                    value={mod.config.post_time || '20:00'}
                    onChange={e => updateMod(mod.id, { post_time: e.target.value })}
                    placeholder="20:00"
                    className="mt-1 w-full h-10 rounded-md border border-line bg-card px-3 text-sm outline-none focus:border-accent"
                  />
                </div>
              )}
              <div className={mod.fields?.includes('post_time') ? '' : 'sm:col-span-2'}>
                <label className="uplabel text-[10px]">Notizen</label>
                <input
                  value={mod.config.notes || ''}
                  onChange={e => updateMod(mod.id, { notes: e.target.value })}
                  placeholder="Optional: Embed-Text, Rolle pingen …"
                  className="mt-1 w-full h-10 rounded-md border border-line bg-card px-3 text-sm outline-none focus:border-accent"
                />
              </div>
            </div>
          </Card>
        ))}
      </div>

      <div className="flex flex-wrap items-center gap-3">
        <Btn icon="Save" onClick={save} disabled={saving}>{saving ? 'Speichert …' : 'Kanäle speichern'}</Btn>
        {msg && <span className={`text-sm ${msg.includes('fehl') ? 'text-signal' : 'text-success'}`}>{msg}</span>}
      </div>
    </div>
  );
}

function DiscordSyncPanel() {
  const [status, setStatus] = useState(null);
  const [syncing, setSyncing] = useState(false);
  const [msg, setMsg] = useState('');

  useEffect(() => {
    window.LSMD.loadDiscordAdmin().then(setStatus).catch(console.error);
  }, []);

  const sync = async () => {
    setSyncing(true);
    setMsg('');
    try {
      const r = await window.LSMD.syncMembers();
      setMsg(`Sync OK — ${r.synced ?? 0} Mitglieder`);
      const d = await window.LSMD.loadDiscordAdmin();
      setStatus(d);
    } catch (e) {
      setMsg(e.message || 'Sync fehlgeschlagen');
    } finally {
      setSyncing(false);
    }
  };

  const lastSync = status?.lastSyncAt
    ? new Date(status.lastSyncAt).toLocaleString('de-DE')
    : 'Noch nie';

  return (
    <div className="mt-6 grid lg:grid-cols-2 gap-6">
      <Card className="p-6">
        <div className="flex items-center gap-3 mb-4">
          <div className="grid place-items-center h-11 w-11 rounded-md bg-discord text-white"><Icon name="MessageCircle" size={22} /></div>
          <div>
            <h2 className="text-lg font-bold">Discord-Server</h2>
            <p className="text-sm text-muted">LSMD · San Andreas</p>
          </div>
        </div>
        <div className={`flex items-center gap-2 rounded-md border p-3 text-sm ${status?.botOnline ? 'border-success/40 bg-success/10' : 'border-line'}`}>
          <Icon name={status?.botOnline ? 'CircleCheck' : 'CircleAlert'} size={16} className={status?.botOnline ? 'text-success' : 'text-muted'} />
          {status?.botOnline ? 'Bot verbunden' : 'Bot nicht konfiguriert (.env)'}
        </div>
        <div className="mt-4 flex flex-col gap-2">
          {[['Server-ID', status?.guildId || '—'], ['Mitarbeiter im Portal', String(status?.memberCount ?? '—')], ['Letzter Sync', lastSync], ['Auto-Posts', 'Deaktiviert (Konfiguration only)']].map(([l, v]) => (
            <div key={l} className="flex items-center justify-between rounded-md border border-line p-3">
              <span className="text-sm text-muted">{l}</span>
              <span className="font-mono text-sm font-semibold text-right max-w-[60%] truncate">{v}</span>
            </div>
          ))}
        </div>
        <Btn variant="outline" icon="RefreshCw" className="mt-4 w-full" onClick={sync} disabled={syncing}>
          {syncing ? 'Synchronisiere …' : 'Jetzt synchronisieren'}
        </Btn>
        {msg && <p className="mt-2 text-sm text-muted">{msg}</p>}
      </Card>
      <Card className="p-6">
        <h2 className="text-lg font-bold mb-2">Hinweis</h2>
        <p className="text-sm text-muted leading-relaxed">
          Rollen-Zuordnung erfolgt über Discord-Rollen beim Login und Mitglieder-Sync.
          Kanäle für Tipp des Tages, Termine, Urlaub usw. legst du unter dem Tab <strong className="text-ink">Discord-Kanäle</strong> fest.
        </p>
      </Card>
    </div>
  );
}

function Admin() {
  const [tab, setTab] = useState('kanaele');
  const [perms, setPerms] = useState(() => JSON.parse(JSON.stringify(DEFAULT_PERMISSIONS)));
  const [roles] = useState(DISCORD_ROLES);
  const [dirty, setDirty] = useState(false);

  const toggle = (roleId, permId) => {
    setPerms(p => ({ ...p, [roleId]: { ...p[roleId], [permId]: p[roleId][permId] ? 0 : 1 } }));
    setDirty(true);
  };
  const reset = () => { setPerms(JSON.parse(JSON.stringify(DEFAULT_PERMISSIONS))); setDirty(false); };

  const tabs = [
    { id: 'uebersicht', label: 'Übersicht' },
    { id: 'nutzer', label: 'Nutzer & Rechte' },
    { id: 'kanaele', label: 'Discord-Kanäle' },
    { id: 'discord', label: 'Discord-Sync' },
    { id: 'rechte', label: 'Rollen-Matrix' },
    { id: 'einstellungen', label: 'Einstellungen' },
  ];

  return (
    <div>
      <PageHead title="Admin" sub="Discord-Bot, Kanäle & Systemeinstellungen">
        {tab === 'rechte' && dirty && (
          <div className="flex gap-2">
            <Btn variant="ghost" onClick={reset}>Verwerfen</Btn>
            <Btn icon="Save" onClick={() => setDirty(false)}>Speichern</Btn>
          </div>
        )}
      </PageHead>
      <Tabs tabs={tabs} active={tab} onChange={setTab} />

      {tab === 'uebersicht' && <AdminOverviewPanel />}
      {tab === 'nutzer' && <AdminNutzerPanel />}
      {tab === 'kanaele' && <DiscordChannelsPanel />}
      {tab === 'discord' && <DiscordSyncPanel />}

      {tab === 'rechte' && (
        <div className="mt-6 flex flex-col gap-6">
          <div className="grid grid-cols-2 md:grid-cols-5 gap-3">
            {roles.map(r => (
              <Card key={r.id} className="p-4">
                <div className="flex items-center gap-2">
                  <span className="h-3 w-3 rounded-full" style={{ background: r.color }} />
                  <span className="font-bold text-sm truncate">{r.name}</span>
                </div>
                <div className="mt-2 text-2xl font-extrabold">{r.members}</div>
                <div className="text-[11px] text-muted">Mitglieder (Demo)</div>
              </Card>
            ))}
          </div>
          <Card className="p-0 overflow-hidden">
            <div className="p-5 border-b border-line">
              <h2 className="text-lg font-bold">Rechte-Matrix</h2>
              <p className="text-sm text-muted mt-0.5">Live-Rechte kommen aus der Datenbank (Discord-Rollen-Sync). Matrix-Vorschau.</p>
            </div>
            <div className="overflow-x-auto">
              <table className="w-full border-collapse min-w-[640px]">
                <thead>
                  <tr className="border-b border-line">
                    <th className="text-left p-4 text-[11px] uplabel font-semibold sticky left-0 bg-card">Recht</th>
                    {roles.map(r => (
                      <th key={r.id} className="p-3 text-center">
                        <div className="flex flex-col items-center gap-1">
                          <span className="h-2.5 w-2.5 rounded-full" style={{ background: r.color }} />
                          <span className="text-[11px] font-bold whitespace-nowrap">{r.name}</span>
                        </div>
                      </th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {PERMISSION_GROUPS.map(g => (
                    <React.Fragment key={g.group}>
                      <tr className="bg-bg/40">
                        <td colSpan={roles.length + 1} className="px-4 py-2 text-[11px] uplabel font-bold text-accent sticky left-0">{g.group}</td>
                      </tr>
                      {g.perms.map(perm => (
                        <tr key={perm.id} className="border-b border-line/50 hover:bg-white/[.02]">
                          <td className="p-4 text-sm font-medium sticky left-0 bg-card">{perm.label}</td>
                          {roles.map(r => (
                            <td key={r.id} className="p-2"><PermToggle on={perms[r.id][perm.id]} onClick={() => toggle(r.id, perm.id)} /></td>
                          ))}
                        </tr>
                      ))}
                    </React.Fragment>
                  ))}
                </tbody>
              </table>
            </div>
          </Card>
        </div>
      )}

      {tab === 'einstellungen' && (
        <div className="mt-6 grid lg:grid-cols-2 gap-6">
          <BrandingUpload />
          <Card className="p-6">
            <h2 className="text-lg font-bold mb-4">System</h2>
            <p className="text-sm text-muted">Website-Logbuch protokolliert Logins, Bewerbungen, Admin-Änderungen und Syncs unter <strong className="text-ink">Logbuch</strong>.</p>
            <p className="text-sm text-muted mt-3">Bewerbungs-Kanal: Admin → Discord-Kanäle → Bewerbungen.</p>
          </Card>
        </div>
      )}
    </div>
  );
}

function AdminOverviewPanel() {
  const [data, setData] = useState(null);
  useEffect(() => {
    window.LSMD.loadAdminOverview().then(setData).catch(console.error);
  }, []);
  if (!data) return <p className="mt-6 text-muted text-sm">Lädt …</p>;
  return (
    <div className="mt-6 flex flex-col gap-6">
      <div className="grid grid-cols-3 gap-3">
        {[['Nutzer', data.stats.users], ['Patientenakten', data.stats.akten], ['Akteneinträge', data.stats.eintraege]].map(([l, v]) => (
          <Card key={l} className="p-4"><div className="uplabel text-[10px]">{l}</div><div className="text-2xl font-black mt-1">{v}</div></Card>
        ))}
      </div>
      <Card className="p-5">
        <h2 className="font-bold mb-3">Letzte Aktivitäten (Logbuch)</h2>
        <div className="flex flex-col gap-2 max-h-64 overflow-y-auto">
          {data.recentAudit.map((r, i) => (
            <div key={i} className="text-sm border-b border-line/50 pb-2">
              <span className="font-semibold">{r.user}</span> — {r.action}
              <div className="text-[10px] text-muted font-mono">{r.ts} · {r.type}</div>
            </div>
          ))}
        </div>
      </Card>
    </div>
  );
}

function AdminNutzerPanel() {
  const [staff, setStaff] = useState([]);
  const [sel, setSel] = useState(null);
  useEffect(() => {
    window.LSMD.loadAdminOverview().then(d => setStaff(d.staff || []));
  }, []);
  return (
    <div className="mt-6 grid lg:grid-cols-[280px_1fr] gap-5">
      <Card className="p-3 max-h-[70vh] overflow-y-auto">
        <p className="text-xs text-muted mb-2 px-2">Nutzer wählen — Rechte unter Personal → Verwaltung pro Person</p>
        {staff.map(u => (
          <button key={u.id} type="button" onClick={() => setSel(u)}
            className={`w-full text-left rounded-md p-2 mb-1 text-sm ${sel?.id === u.id ? 'bg-[var(--c-accent-soft)]' : 'hover:bg-white/5'}`}>
            <div className="font-semibold">{u.name}</div>
            <div className="text-xs text-muted">{u.dn} · {u.rank}</div>
          </button>
        ))}
      </Card>
      <Card className="p-6">
        {!sel && <p className="text-muted text-sm">Mitarbeiter links auswählen. Detaillierte Rechte & Abteilungen: <strong>Personal → Verwaltung</strong>.</p>}
        {sel && (
          <>
            <h2 className="text-xl font-bold">{sel.name}</h2>
            <p className="text-sm text-muted mt-1">{sel.dn} · {sel.rank} · Rolle: {sel.role}</p>
            <Btn className="mt-4" variant="outline" onClick={() => window.LSMD_NAV?.('verwaltung')}>In Personalverwaltung öffnen</Btn>
          </>
        )}
      </Card>
    </div>
  );
}

function BrandingUpload() {
  const [logo, setLogo] = useState(window.LSMD?.logoUrl?.() || '/img/lsmd-logo.png');
  const [msg, setMsg] = useState('');
  const upload = async (type, file) => {
    if (!file) return;
    const fd = new FormData();
    fd.append('type', type);
    fd.append('file', file);
    const r = await fetch('/api/admin/branding', { method: 'POST', body: fd, credentials: 'same-origin' });
    const data = await r.json();
    if (!r.ok) throw new Error(data.error || 'Upload fehlgeschlagen');
    if (type === 'logo') {
      setLogo(data.url);
      window.__LSMD_SITE__ = { ...window.__LSMD_SITE__, logoUrl: data.url };
    }
    setMsg(`${type} aktualisiert`);
  };
  return (
    <Card className="p-6 lg:col-span-2">
      <h2 className="text-lg font-bold mb-1">Branding & Uploads</h2>
      <p className="text-sm text-muted mb-4">LSMD-Logo und Hero-Bild für die öffentliche Seite.</p>
      <div className="flex flex-wrap items-center gap-6">
        <img src={logo} alt="LSMD Logo" className="h-24 w-24 object-contain rounded-md border border-line bg-bg/40 p-2" />
        <div className="flex flex-col gap-2">
          <label className="text-sm font-semibold">Logo hochladen (PNG/JPG)</label>
          <input type="file" accept="image/*" onChange={e => upload('logo', e.target.files[0])} className="text-sm" />
          <label className="text-sm font-semibold mt-2">Hero-Hintergrund</label>
          <input type="file" accept="image/*" onChange={e => upload('hero', e.target.files[0])} className="text-sm" />
        </div>
      </div>
      {msg && <p className="mt-3 text-sm text-success">{msg}</p>}
    </Card>
  );
}

Object.assign(window, { Admin, BrandingUpload, DiscordChannelsPanel, DiscordSyncPanel });
