'use client';

import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import Link from 'next/link';
import { CATEGORIES, categoryLabel, localePath, type Locale } from '@ai-radar/shared';
import type { Dictionary } from '@/lib/dictionary';
import {
  me,
  logout,
  deleteAccount as deleteAccountRequest,
  getPreferences,
  savePreferences,
  getChannels,
  getSessions,
  revokeOtherSessions,
  getLinkedLogins,
  type PublicAccount,
  type Preferences,
} from '@/lib/auth-client';

/**
 * Account settings.
 *
 * The filters here are the reason accounts exist, so they come first and
 * everything else is below them. Saving pushes to every linked channel
 * server-side — the reader is told that, because otherwise setting a
 * filter here and still getting unfiltered Telegram alerts would look
 * broken.
 */
export function AccountPanel({ locale, dict }: { locale: Locale; dict: Dictionary }) {
  const t = dict.auth;
  const router = useRouter();

  const [account, setAccount] = useState<PublicAccount | null>(null);
  const [prefs, setPrefs] = useState<Preferences | null>(null);
  const [channels, setChannels] = useState<Awaited<ReturnType<typeof getChannels>> | null>(null);
  const [sessions, setSessions] = useState<Awaited<ReturnType<typeof getSessions>>['sessions']>([]);
  const [linked, setLinked] = useState<Array<{ provider: string; email: string | null }>>([]);
  const [loading, setLoading] = useState(true);
  const [savedAt, setSavedAt] = useState(0);
  const [deleting, setDeleting] = useState(false);
  const [deleteError, setDeleteError] = useState<string | null>(null);

  useEffect(() => {
    (async () => {
      const who = await me().catch(() => ({ account: null }));
      setAccount(who.account);

      if (!who.account) {
        setLoading(false);
        return;
      }

      // Everything at once: four small reads, and staggering them would
      // make the page assemble itself visibly.
      const [p, c, s, l] = await Promise.all([
        getPreferences().catch(() => null),
        getChannels().catch(() => null),
        getSessions().catch(() => ({ sessions: [] })),
        getLinkedLogins().catch(() => ({ linked: [] })),
      ]);

      if (p) setPrefs(p.preferences);
      if (c) setChannels(c);
      setSessions(s.sessions);
      setLinked(l.linked);
      setLoading(false);
    })();
  }, []);

  async function toggleFilter(kind: 'categories', value: string) {
    if (!prefs) return;

    const current = prefs[kind];
    const next = current.includes(value)
      ? current.filter((v) => v !== value)
      : [...current, value];

    // Optimistic: the reader sees the chip change immediately, and the
    // server is the authority on what comes back.
    setPrefs({ ...prefs, [kind]: next });

    const result = await savePreferences({ [kind]: next }).catch(() => null);
    if (result) {
      setPrefs(result.preferences);
      setSavedAt(Date.now());
    }
  }

  async function signOut() {
    await logout().catch(() => {});
    router.push(localePath('/', locale));
    router.refresh();
  }

  async function deleteAccount() {
    if (!window.confirm(t.deleteAccountConfirm)) return;

    setDeleting(true);
    setDeleteError(null);
    const result = await deleteAccountRequest().catch(() => ({ ok: false }));

    if (!result.ok) {
      setDeleting(false);
      setDeleteError(t.deleteAccountFailed);
      return;
    }

    router.push(localePath('/', locale));
    router.refresh();
  }

  if (loading) return <p className="t-body-sm">…</p>;

  if (!account) {
    return (
      <div className="auth-card">
        <p className="auth-blurb">{t.signInRequired}</p>
        <Link className="auth-submit" href={localePath('/signin', locale)}>
          {t.signIn}
        </Link>
      </div>
    );
  }

  return (
    <div className="account">
      <header className="account-head">
        <div>
          <h1 className="t-h1">{t.account}</h1>
          <p className="t-meta account-email">{account.email}</p>
        </div>
        <button type="button" className="account-signout" onClick={() => void signOut()}>
          {t.signOut}
        </button>
      </header>

      {/* Filters first: this is what an account is for. */}
      <section className="account-block">
        <h2 className="account-h2">{t.yourAlerts}</h2>
        <p className="account-help">{t.yourAlertsHelp}</p>

        <p className="account-label">{t.filterTopics}</p>
        <div className="account-chips">
          {CATEGORIES.map((category) => {
            const on = prefs?.categories.includes(category) ?? false;
            return (
              <button
                key={category}
                type="button"
                className={`account-chip ${on ? 'on' : ''}`}
                aria-pressed={on}
                onClick={() => void toggleFilter('categories', category)}
              >
                {categoryLabel(category, locale)}
              </button>
            );
          })}
        </div>

        <p className="account-note">
          {prefs && prefs.categories.length === 0
            ? t.everything
            : `${prefs?.categories.length ?? 0} / ${CATEGORIES.length}`}
          {savedAt > 0 && <span className="account-saved"> · {t.saved}</span>}
        </p>
      </section>

      {channels && (
        <section className="account-block">
          <h2 className="account-h2">{t.channels}</h2>
          <p className="account-help">{t.channelsHelp}</p>

          <ul className="account-list">
            {channels.telegram.map((c) => (
              <li key={`tg-${c.id}`}>
                Telegram{c.username ? ` · @${c.username}` : ''} · {c.status}
              </li>
            ))}
            {channels.email.map((c) => (
              <li key={`em-${c.id}`}>
                {c.address} · {c.status}
              </li>
            ))}
            {channels.devices.map((c) => (
              <li key={`dv-${c.id}`}>
                {c.platform} · {c.status}
              </li>
            ))}
            {channels.telegram.length === 0 &&
              channels.email.length === 0 &&
              channels.devices.length === 0 && <li>—</li>}
          </ul>
        </section>
      )}

      {linked.length > 0 && (
        <section className="account-block">
          <h2 className="account-h2">{t.linkedLogins}</h2>
          <ul className="account-list">
            {linked.map((l) => (
              <li key={l.provider}>
                {l.provider}
                {l.email ? ` · ${l.email}` : ''}
              </li>
            ))}
          </ul>
        </section>
      )}

      <section className="account-block">
        <h2 className="account-h2">{t.activeSessions}</h2>
        <ul className="account-list">
          {sessions.map((s) => (
            <li key={s.id}>
              {s.client}
              {s.current ? ` · ${t.thisDevice}` : ''}
              {s.userAgent ? ` · ${s.userAgent.slice(0, 40)}` : ''}
            </li>
          ))}
        </ul>

        {sessions.length > 1 && (
          <button
            type="button"
            className="account-secondary"
            onClick={() => {
              void revokeOtherSessions().then(() =>
                getSessions()
                  .then((r) => setSessions(r.sessions))
                  .catch(() => {}),
              );
            }}
          >
            {t.signOutOthers}
          </button>
        )}
      </section>

      <section className="account-block">
        <h2 className="account-h2">{t.deleteAccount}</h2>
        <p className="account-help">{t.deleteAccountHelp}</p>
        {deleteError && <p className="account-help account-delete-error">{deleteError}</p>}
        <button
          type="button"
          className="account-danger"
          disabled={deleting}
          onClick={() => void deleteAccount()}
        >
          {deleting ? '…' : t.deleteAccount}
        </button>
      </section>
    </div>
  );
}
