"use client";

import { useEffect, useState } from "react";
import { TextField, useToast } from "@nexarch/shl";
import {
  ApiError,
  Me,
  beginTotpSetup,
  changePassword,
  confirmTotpSetup,
  fetchMe,
  fetchTotpStatus,
} from "../../lib/api";

export default function ProfilePage() {
  const { push } = useToast();
  const [me, setMe] = useState<Me | null>(null);
  const [totpEnabled, setTotpEnabled] = useState<boolean | null>(null);
  const [loadError, setLoadError] = useState<string | null>(null);

  useEffect(() => {
    Promise.all([fetchMe(), fetchTotpStatus()])
      .then(([meResult, statusResult]) => {
        setMe(meResult);
        setTotpEnabled(statusResult.enabled);
      })
      .catch(() => setLoadError("Bitte melden Sie sich an, um Ihr Profil zu sehen."));
  }, []);

  if (loadError) {
    return (
      <main style={{ maxWidth: 480, margin: "80px auto", padding: "0 16px" }}>
        <p role="alert">{loadError}</p>
        <a href="/login">Zur Anmeldung</a>
      </main>
    );
  }

  return (
    <main style={{ maxWidth: 480, margin: "40px auto", padding: "0 16px" }}>
      <h1>Mein Profil</h1>
      {me && (
        <section aria-labelledby="stammdaten-heading">
          <h2 id="stammdaten-heading">Stammdaten</h2>
          <p>
            {me.name} — {me.email}
          </p>
        </section>
      )}

      <ChangePasswordSection onSuccess={() => push("Passwort geändert.", "success")} />

      <TotpSection
        enabled={totpEnabled}
        onEnabled={() => setTotpEnabled(true)}
        onNotice={(text) => push(text, "info")}
      />
    </main>
  );
}

function ChangePasswordSection({ onSuccess }: { onSuccess: () => void }) {
  const [currentPassword, setCurrentPassword] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState(false);

  async function onSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setError(null);
    setSubmitting(true);
    try {
      await changePassword(currentPassword, newPassword);
      setCurrentPassword("");
      setNewPassword("");
      onSuccess();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "Passwort konnte nicht geändert werden.");
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <section aria-labelledby="passwort-heading">
      <h2 id="passwort-heading">Passwort ändern</h2>
      <form onSubmit={onSubmit} noValidate>
        <TextField
          label="Aktuelles Passwort"
          type="password"
          autoComplete="current-password"
          required
          value={currentPassword}
          onChange={(e) => setCurrentPassword(e.target.value)}
        />
        <TextField
          label="Neues Passwort"
          type="password"
          autoComplete="new-password"
          required
          minLength={8}
          value={newPassword}
          onChange={(e) => setNewPassword(e.target.value)}
        />
        {error && (
          <p role="alert" style={{ color: "var(--shl-color-danger)" }}>
            {error}
          </p>
        )}
        <button type="submit" disabled={submitting}>
          {submitting ? "Wird gespeichert…" : "Passwort ändern"}
        </button>
      </form>
    </section>
  );
}

function TotpSection({
  enabled,
  onEnabled,
  onNotice,
}: {
  enabled: boolean | null;
  onEnabled: () => void;
  onNotice: (text: string) => void;
}) {
  const [setupData, setSetupData] = useState<{ secret: string; provisioningUri: string } | null>(null);
  const [confirmCode, setConfirmCode] = useState("");
  const [recoveryCodes, setRecoveryCodes] = useState<string[] | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  async function onBeginSetup() {
    setError(null);
    setBusy(true);
    try {
      const result = await beginTotpSetup();
      setSetupData({ secret: result.secret, provisioningUri: result.provisioning_uri });
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "Einrichtung konnte nicht gestartet werden.");
    } finally {
      setBusy(false);
    }
  }

  async function onConfirm(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setError(null);
    setBusy(true);
    try {
      const result = await confirmTotpSetup(confirmCode);
      // Akzeptanzkriterium 2: Wiederherstellungscodes werden HIER, EINMALIG
      // im Klartext angezeigt — die Backend-API liefert sie an keiner
      // anderen Stelle je wieder aus (siehe internal/totp/store.go).
      setRecoveryCodes(result.recovery_codes);
      setSetupData(null);
      onEnabled();
      onNotice("Zwei-Faktor-Authentifizierung aktiviert. Bewahren Sie die Wiederherstellungscodes sicher auf.");
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "Code ungültig.");
    } finally {
      setBusy(false);
    }
  }

  return (
    <section aria-labelledby="zwei-faktor-heading">
      <h2 id="zwei-faktor-heading">Zwei-Faktor-Authentifizierung</h2>

      {recoveryCodes ? (
        <div role="alert">
          <p>
            <strong>Wiederherstellungscodes — jetzt notieren, sie werden nicht erneut angezeigt:</strong>
          </p>
          <ul>
            {recoveryCodes.map((code) => (
              <li key={code}>
                <code>{code}</code>
              </li>
            ))}
          </ul>
        </div>
      ) : enabled ? (
        <p>Zwei-Faktor-Authentifizierung ist aktiv.</p>
      ) : setupData ? (
        <form onSubmit={onConfirm} noValidate>
          <p>
            Scannen Sie den folgenden Schlüssel mit Ihrer Authenticator-App oder geben Sie ihn manuell ein:
          </p>
          <p>
            <code>{setupData.secret}</code>
          </p>
          <p style={{ wordBreak: "break-all" }}>
            <a href={setupData.provisioningUri}>{setupData.provisioningUri}</a>
          </p>
          <TextField
            label="Bestätigungscode aus der App"
            type="text"
            inputMode="numeric"
            required
            value={confirmCode}
            onChange={(e) => setConfirmCode(e.target.value)}
          />
          {error && (
            <p role="alert" style={{ color: "var(--shl-color-danger)" }}>
              {error}
            </p>
          )}
          <button type="submit" disabled={busy}>
            {busy ? "Wird bestätigt…" : "Einrichtung bestätigen"}
          </button>
        </form>
      ) : (
        <>
          <p>Zwei-Faktor-Authentifizierung ist derzeit nicht aktiv.</p>
          {error && (
            <p role="alert" style={{ color: "var(--shl-color-danger)" }}>
              {error}
            </p>
          )}
          <button type="button" onClick={onBeginSetup} disabled={busy}>
            {busy ? "Wird gestartet…" : "Einrichten"}
          </button>
        </>
      )}
    </section>
  );
}
