import { useEffect, useMemo, useState } from "react";
import { Copy, Download, Shield, Smartphone, Trash2 } from "lucide-react";
import QRCode from "qrcode";
import { toast } from "sonner";

import { trpc } from "@/lib/trpc";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Alert, AlertDescription } from "@/components/ui/alert";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { InputOTP, InputOTPGroup, InputOTPSlot } from "@/components/ui/input-otp";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";

type AccountSecurityPanelProps = {
  compact?: boolean;
};

export default function AccountSecurityPanel({ compact = false }: AccountSecurityPanelProps) {
  const utils = trpc.useUtils();
  const { data: securitySettings } = trpc.auth.getSecuritySettings.useQuery();
  const [authenticatorSetup, setAuthenticatorSetup] = useState<null | {
    manualEntryKey: string;
    otpauthUrl: string;
  }>(null);
  const [authenticatorCode, setAuthenticatorCode] = useState("");
  const [authenticatorQrCode, setAuthenticatorQrCode] = useState<string | null>(null);

  const setMfaMutation = trpc.auth.setMfaEnabled.useMutation({
    onSuccess: () => {
      utils.auth.getSecuritySettings.invalidate();
      toast.success("Réglage MFA mis à jour");
    },
    onError: (error) => toast.error(error.message || "Impossible de modifier le MFA"),
  });
  const startAuthenticatorMutation = trpc.auth.startAuthenticatorSetup.useMutation({
    onSuccess: (data) => {
      setAuthenticatorSetup(data);
      setAuthenticatorCode("");
    },
    onError: (error) => toast.error(error.message || "Impossible de démarrer Authenticator"),
  });
  const confirmAuthenticatorMutation = trpc.auth.confirmAuthenticatorSetup.useMutation({
    onSuccess: async () => {
      await utils.auth.getSecuritySettings.invalidate();
      setAuthenticatorSetup(null);
      setAuthenticatorCode("");
      toast.success("Authenticator activé");
    },
    onError: (error) => toast.error(error.message || "Code Authenticator invalide"),
  });
  const cancelAuthenticatorMutation = trpc.auth.cancelAuthenticatorSetup.useMutation({
    onSuccess: async () => {
      await utils.auth.getSecuritySettings.invalidate();
      setAuthenticatorSetup(null);
      setAuthenticatorCode("");
    },
  });
  const deleteAccountMutation = trpc.auth.deleteMyAccount.useMutation({
    onSuccess: async (data) => {
      await utils.auth.getSecuritySettings.invalidate();
      toast.success(
        `Demande enregistrée. Purge prévue le ${new Date(data.purgeScheduledAt).toLocaleDateString("fr-FR")}.`
      );
    },
    onError: (error) => toast.error(error.message || "Impossible de planifier la suppression du compte"),
  });
  const cancelDeletionMutation = trpc.auth.cancelAccountDeletion.useMutation({
    onSuccess: async () => {
      await utils.auth.getSecuritySettings.invalidate();
      toast.success("Suppression du compte annulée");
    },
    onError: (error) => toast.error(error.message || "Impossible d'annuler la suppression"),
  });

  const deletionPending = Boolean(securitySettings?.purgeScheduledAt);
  const canUseAuthenticator = securitySettings?.loginMethod === "local_jwt" && Boolean(securitySettings?.email);
  const emailMfaAllowed = securitySettings?.mfaPolicy?.emailFallbackAllowed !== false;
  const mfaModeLabel = useMemo(() => {
    if (securitySettings?.mfaMethod === "authenticator_app") return "Authenticator";
    if (securitySettings?.mfaEnabled) return "Code email";
    return "Inactif";
  }, [securitySettings]);

  useEffect(() => {
    let cancelled = false;

    async function buildQrCode() {
      if (!authenticatorSetup?.otpauthUrl) {
        setAuthenticatorQrCode(null);
        return;
      }

      try {
        const dataUrl = await QRCode.toDataURL(authenticatorSetup.otpauthUrl, {
          margin: 1,
          width: 192,
        });
        if (!cancelled) {
          setAuthenticatorQrCode(dataUrl);
        }
      } catch {
        if (!cancelled) {
          setAuthenticatorQrCode(null);
        }
      }
    }

    buildQrCode();

    return () => {
      cancelled = true;
    };
  }, [authenticatorSetup]);

  const handleExportData = async () => {
    const payload = await utils.auth.exportMyData.fetch();
    const blob = new Blob([JSON.stringify(payload, null, 2)], { type: "application/json" });
    const url = window.URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = url;
    link.download = `mes-donnees-portail-associations-${new Date().toISOString().slice(0, 10)}.json`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    window.URL.revokeObjectURL(url);
  };

  const copyValue = async (value: string, label: string) => {
    try {
      await navigator.clipboard.writeText(value);
      toast.success(`${label} copié`);
    } catch {
      toast.error(`Impossible de copier ${label.toLowerCase()}`);
    }
  };

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-2">
          <Shield className="h-5 w-5 text-primary" />
          Sécurité du compte
        </CardTitle>
        <CardDescription>
          {compact
            ? "MFA, export des données et état de suppression du compte."
            : "Pilote le MFA, l’export RGPD et la suppression différée à 30 jours."}
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-6">
        <div className={`grid gap-4 ${compact ? "md:grid-cols-2" : "md:grid-cols-3"}`}>
          <div className="rounded-lg border p-4">
            <p className="text-sm text-muted-foreground">Mode de connexion</p>
            <p className="mt-2 font-medium">
              {securitySettings?.loginMethod === "local_jwt"
                ? "Compte local"
                : securitySettings?.loginMethod?.includes("oauth")
                  ? "Compte social"
                  : securitySettings?.loginMethod || "Non déterminé"}
            </p>
          </div>
          <div className="rounded-lg border p-4">
            <p className="text-sm text-muted-foreground">MFA actif</p>
            <p className="mt-2 font-medium">{mfaModeLabel}</p>
            {securitySettings?.mfaRequiredByRole ? (
              <p className="mt-2 text-xs text-amber-700">Obligatoire pour ce rôle interne.</p>
            ) : null}
          </div>
          <div className="rounded-lg border p-4">
            <p className="text-sm text-muted-foreground">Verrouillage anti-bruteforce</p>
            <p className="mt-2 font-medium">
              {securitySettings
                ? `${securitySettings.lockoutPolicy.maxAttempts} tentatives puis ${securitySettings.lockoutPolicy.lockMinutes} min`
                : "Chargement..."}
            </p>
          </div>
        </div>

        {deletionPending ? (
          <Alert>
            <AlertDescription>
              Suppression demandée le{" "}
              {securitySettings?.deletionRequestedAt ? new Date(securitySettings.deletionRequestedAt).toLocaleDateString("fr-FR") : "-"}
              {" "}• purge prévue le{" "}
              {securitySettings?.purgeScheduledAt ? new Date(securitySettings.purgeScheduledAt).toLocaleDateString("fr-FR") : "-"}.
            </AlertDescription>
          </Alert>
        ) : null}

        <div className="grid gap-4 lg:grid-cols-2">
          <div className="rounded-lg border p-4 space-y-3">
            <div>
              <p className="font-medium">MFA par email</p>
              <p className="text-sm text-muted-foreground">
                Fonctionne immédiatement pour les comptes locaux avec une adresse email valide.
              </p>
            </div>
            {securitySettings?.mfaRequiredByRole ? (
              <Alert>
                <AlertDescription>
                  {emailMfaAllowed
                    ? "Disponible en solution de secours, mais l’application Authenticator est recommandée pour les comptes internes."
                    : "Cette méthode n'est plus autorisée comme mode normal pour ce rôle. L'application Authenticator est requise."}
                </AlertDescription>
              </Alert>
            ) : null}
            <div className="flex flex-wrap gap-2">
              <Button
                type="button"
                variant={securitySettings?.mfaMethod === "email_otp" || (securitySettings?.mfaEnabled && securitySettings?.mfaMethod !== "authenticator_app") ? "default" : "outline"}
                disabled={!securitySettings?.smtpReady || !canUseAuthenticator || setMfaMutation.isPending || !emailMfaAllowed}
                onClick={() => setMfaMutation.mutate({ enabled: true })}
              >
                Utiliser le code email
              </Button>
              {!securitySettings?.mfaRequiredByRole ? (
                <Button
                  type="button"
                  variant="outline"
                  disabled={setMfaMutation.isPending}
                  onClick={() => setMfaMutation.mutate({ enabled: false })}
                >
                  Désactiver
                </Button>
              ) : null}
            </div>
            {!securitySettings?.smtpReady ? (
              <p className="text-sm text-amber-700">Le SMTP doit être configuré pour utiliser le MFA email.</p>
            ) : null}
          </div>

          <div className="rounded-lg border p-4 space-y-3">
            <div className="flex items-start gap-3">
              <Smartphone className="mt-0.5 h-5 w-5 text-primary" />
              <div>
                <p className="font-medium">Appli Authenticator</p>
                <p className="text-sm text-muted-foreground">
                  Compatible Google Authenticator, Microsoft Authenticator et applications TOTP équivalentes.
                </p>
              </div>
            </div>
            {securitySettings?.mfaRequiredByRole ? (
              <Alert>
                <AlertDescription>
                  {securitySettings?.mfaPolicy?.enforcedMethod === "authenticator_app"
                    ? "Méthode exigée pour ce rôle : scannez le QR code puis validez le code à 6 chiffres pour aligner le compte."
                    : "Méthode cible pour les rôles internes : scannez le QR code puis validez le code à 6 chiffres pour activer la protection."}
                </AlertDescription>
              </Alert>
            ) : null}
            <div className="flex flex-wrap gap-2">
              <Button
                type="button"
                variant={securitySettings?.mfaMethod === "authenticator_app" ? "default" : "outline"}
                disabled={!canUseAuthenticator || startAuthenticatorMutation.isPending}
                onClick={() => startAuthenticatorMutation.mutate()}
              >
                Configurer Authenticator
              </Button>
              {securitySettings?.mfaMethod === "authenticator_app" ? (
                <Button
                  type="button"
                  variant="outline"
                  disabled={setMfaMutation.isPending}
                  onClick={() => setMfaMutation.mutate({ enabled: true })}
                >
                  Revenir au code email
                </Button>
              ) : null}
            </div>
            {authenticatorSetup ? (
              <div className="rounded-lg border bg-muted/30 p-4 space-y-4">
                <div className="grid gap-4 md:grid-cols-[192px_minmax(0,1fr)] md:items-start">
                  <div className="space-y-2">
                    <Label>QR code à scanner</Label>
                    <div className="flex h-48 w-48 items-center justify-center rounded-lg border bg-white">
                      {authenticatorQrCode ? (
                        <img
                          src={authenticatorQrCode}
                          alt="QR code Authenticator"
                          className="h-44 w-44"
                        />
                      ) : (
                        <p className="px-4 text-center text-xs text-muted-foreground">
                          QR code indisponible. Utilisez la clé manuelle.
                        </p>
                      )}
                    </div>
                  </div>

                  <div className="space-y-4 min-w-0">
                    <div className="space-y-2">
                      <Label>Clé manuelle</Label>
                      <div className="flex gap-2">
                        <Input value={authenticatorSetup.manualEntryKey} readOnly />
                        <Button
                          type="button"
                          variant="outline"
                          size="icon"
                          onClick={() => copyValue(authenticatorSetup.manualEntryKey, "Clé manuelle")}
                        >
                          <Copy className="h-4 w-4" />
                        </Button>
                      </div>
                    </div>
                    <div className="space-y-2">
                      <Label>Code de vérification</Label>
                      <InputOTP maxLength={6} value={authenticatorCode} onChange={setAuthenticatorCode}>
                        <InputOTPGroup>
                          <InputOTPSlot index={0} />
                          <InputOTPSlot index={1} />
                          <InputOTPSlot index={2} />
                          <InputOTPSlot index={3} />
                          <InputOTPSlot index={4} />
                          <InputOTPSlot index={5} />
                        </InputOTPGroup>
                      </InputOTP>
                      <p className="text-xs text-muted-foreground">
                        Scannez le QR code dans votre application, puis saisissez le code temporaire affiché.
                      </p>
                    </div>
                    <div className="space-y-2">
                      <Label>URL OTP avancée</Label>
                      <div className="flex gap-2">
                        <Input value={authenticatorSetup.otpauthUrl} readOnly />
                        <Button
                          type="button"
                          variant="outline"
                          size="icon"
                          onClick={() => copyValue(authenticatorSetup.otpauthUrl, "URL OTP")}
                        >
                          <Copy className="h-4 w-4" />
                        </Button>
                      </div>
                    </div>
                  </div>
                </div>
                <div className="flex flex-wrap gap-2">
                  <Button
                    type="button"
                    disabled={authenticatorCode.length !== 6 || confirmAuthenticatorMutation.isPending}
                    onClick={() => confirmAuthenticatorMutation.mutate({ code: authenticatorCode })}
                  >
                    Valider Authenticator
                  </Button>
                  <Button
                    type="button"
                    variant="outline"
                    onClick={() => cancelAuthenticatorMutation.mutate()}
                  >
                    Annuler
                  </Button>
                </div>
              </div>
            ) : null}
          </div>
        </div>

        <div className={`grid gap-4 ${compact ? "md:grid-cols-2" : "md:grid-cols-2"}`}>
          <div className="rounded-lg border p-4 space-y-3">
            <div>
              <p className="font-medium">Exporter mes données</p>
              <p className="text-sm text-muted-foreground">
                Télécharge un JSON contenant le compte, la fiche, les documents et les demandes.
              </p>
            </div>
            <Button type="button" variant="outline" onClick={handleExportData}>
              <Download className="mr-2 h-4 w-4" />
              Télécharger mes données
            </Button>
          </div>

          {securitySettings?.role === "user" ? (
            <div className="rounded-lg border border-red-200 bg-red-50/40 p-4 space-y-3">
              <div>
                <p className="font-medium text-red-700">Suppression du compte</p>
                <p className="text-sm text-muted-foreground">
                  Le compte est désactivé immédiatement, puis les données personnelles sont purgées au bout de 30 jours.
                </p>
              </div>
              <div className="flex flex-wrap gap-2">
                {!deletionPending ? (
                  <AlertDialog>
                    <AlertDialogTrigger asChild>
                      <Button type="button" variant="destructive">
                        <Trash2 className="mr-2 h-4 w-4" />
                        Demander la suppression
                      </Button>
                    </AlertDialogTrigger>
                    <AlertDialogContent>
                      <AlertDialogHeader>
                        <AlertDialogTitle>Planifier la suppression du compte ?</AlertDialogTitle>
                        <AlertDialogDescription>
                          Le compte sera désactivé maintenant. La purge définitive et l’anonymisation des données personnelles interviendront dans 30 jours.
                        </AlertDialogDescription>
                      </AlertDialogHeader>
                      <AlertDialogFooter>
                        <AlertDialogCancel>Annuler</AlertDialogCancel>
                        <AlertDialogAction onClick={() => deleteAccountMutation.mutate({ confirm: true })}>
                          Confirmer
                        </AlertDialogAction>
                      </AlertDialogFooter>
                    </AlertDialogContent>
                  </AlertDialog>
                ) : (
                  <Button type="button" variant="outline" onClick={() => cancelDeletionMutation.mutate()}>
                    Annuler la suppression planifiée
                  </Button>
                )}
              </div>
            </div>
          ) : null}
        </div>
      </CardContent>
    </Card>
  );
}
