import { FormEvent, useEffect, useMemo, useState } from "react";
import { Link, useLocation } from "wouter";
import { AlertCircle, ArrowLeft, LogIn, UserPlus } from "lucide-react";

import { useAuth } from "@/_core/hooks/useAuth";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import DataPrivacyValidationDialog from "@/components/DataPrivacyValidationDialog";
import { Input } from "@/components/ui/input";
import { InputOTP, InputOTPGroup, InputOTPSlot } from "@/components/ui/input-otp";
import { Label } from "@/components/ui/label";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { trpc } from "@/lib/trpc";
import { buildDataPrivacyConsent } from "@shared/privacyCompliance";

type AuthMode = "login" | "register";

export default function Login() {
  const [, setLocation] = useLocation();
  const { login, register, loading, error, providers, providersLoading } = useAuth();
  const [mode, setMode] = useState<AuthMode>("login");
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [mfaCode, setMfaCode] = useState("");
  const [mfaChallenge, setMfaChallenge] = useState<null | {
    challengeType: "email" | "totp";
    challengeToken: string;
    expiresAt: string | Date;
    maskedEmail?: string;
  }>(null);
  const [privacyDialogOpen, setPrivacyDialogOpen] = useState(false);
  const verifyMfaMutation = trpc.auth.verifyLoginMfa.useMutation();
  const resendMfaMutation = trpc.auth.resendLoginMfa.useMutation();
  const authError = typeof window !== "undefined"
    ? new URLSearchParams(window.location.search).get("authError")
    : null;
  const registerName = typeof window !== "undefined"
    ? new URLSearchParams(window.location.search).get("name")
    : null;
  const registerEmail = typeof window !== "undefined"
    ? new URLSearchParams(window.location.search).get("email")
    : null;
  const requestedMode = typeof window !== "undefined"
    ? new URLSearchParams(window.location.search).get("mode")
    : null;

  useEffect(() => {
    if (requestedMode === "register") {
      setMode("register");
    }
    if (registerName) {
      setName(registerName);
    }
    if (registerEmail) {
      setEmail(registerEmail);
    }
  }, [requestedMode, registerName, registerEmail]);

  const title = useMemo(
    () => mode === "login" ? "Connexion" : "Creation de compte",
    [mode]
  );

  const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();

    if (mode === "login") {
      const authenticated = await login({ email, password });
      if (authenticated.mfaRequired) {
        setMfaChallenge(authenticated);
        return;
      }
      setLocation(authenticated.user?.role === "service_terrain" ? "/terrain" : "/dashboard");
      return;
    }

    setPrivacyDialogOpen(true);
  };

  const handleRegisterWithPrivacyConsent = async () => {
    const authenticatedUser = await register({
      name,
      email,
      password,
      privacyConsent: buildDataPrivacyConsent("register_account"),
    });
    setLocation(authenticatedUser?.role === "service_terrain" ? "/terrain" : "/dashboard");
  };

  const handleVerifyMfa = async () => {
    if (!mfaChallenge) return;
    const authenticatedUser = await verifyMfaMutation.mutateAsync({
      challengeToken: mfaChallenge.challengeToken,
      code: mfaCode,
    });
    setLocation(authenticatedUser?.role === "service_terrain" ? "/terrain" : "/dashboard");
  };

  const handleResendMfa = async () => {
    if (!mfaChallenge) return;
    const nextChallenge = await resendMfaMutation.mutateAsync({
      challengeToken: mfaChallenge.challengeToken,
    });
    setMfaChallenge(nextChallenge);
  };

  return (
    <div className="min-h-screen bg-muted/30">
      <header className="border-b border-border bg-white">
        <div className="container py-4">
          <div className="flex items-center justify-between">
            <Link href="/" className="flex flex-col">
              <span className="text-xs text-muted-foreground uppercase tracking-wider">Republique Francaise</span>
              <span className="text-lg font-bold text-primary">Portail Associations</span>
            </Link>
            <Link href="/" className="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-primary">
              <ArrowLeft className="h-4 w-4" />
              Accueil
            </Link>
          </div>
        </div>
      </header>

      <main className="container flex min-h-[calc(100vh-73px)] items-center justify-center py-10">
        <Card className="w-full max-w-md shadow-sm">
          <CardHeader>
            <CardTitle>{title}</CardTitle>
            <CardDescription>
              Accedez a votre espace association avec votre email et votre mot de passe.
            </CardDescription>
          </CardHeader>
          <CardContent>
            <Tabs value={mode} onValueChange={value => setMode(value as AuthMode)}>
              <TabsList className="grid w-full grid-cols-2">
                <TabsTrigger value="login" className="gap-2">
                  <LogIn className="h-4 w-4" />
                  Connexion
                </TabsTrigger>
                <TabsTrigger value="register" className="gap-2">
                  <UserPlus className="h-4 w-4" />
                  Inscription
                </TabsTrigger>
              </TabsList>

              {error ? (
                <Alert variant="destructive" className="mt-4">
                  <AlertCircle className="h-4 w-4" />
                  <AlertDescription>{error.message}</AlertDescription>
                </Alert>
              ) : null}

              {!error && authError ? (
                <Alert variant="destructive" className="mt-4">
                  <AlertCircle className="h-4 w-4" />
                  <AlertDescription>{authError}</AlertDescription>
                </Alert>
              ) : null}

              <div className="mt-6 space-y-3">
                <Button
                  type="button"
                  variant="outline"
                  className="w-full"
                  disabled={providersLoading || !providers.google}
                  onClick={() => {
                    window.location.href = "/auth/google/start";
                  }}
                >
                  Continuer avec Google
                </Button>
                <Button
                  type="button"
                  variant="outline"
                  className="w-full"
                  disabled={providersLoading || !providers.facebook}
                  onClick={() => {
                    window.location.href = "/auth/facebook/start";
                  }}
                >
                  Continuer avec Facebook
                </Button>
              </div>

              <div className="my-6 flex items-center gap-3 text-xs uppercase tracking-wide text-muted-foreground">
                <div className="h-px flex-1 bg-border" />
                <span>ou</span>
                <div className="h-px flex-1 bg-border" />
              </div>

              <form onSubmit={handleSubmit} className="space-y-4">
                <TabsContent value="register" className="m-0">
                  <div className="space-y-2">
                    <Label htmlFor="name">Nom complet</Label>
                    <Input
                      id="name"
                      value={name}
                      onChange={event => setName(event.target.value)}
                      autoComplete="name"
                      minLength={2}
                      required={mode === "register"}
                    />
                  </div>
                </TabsContent>

                <TabsContent value="login" className="m-0" />

                <div className="space-y-2">
                  <Label htmlFor="email">Email</Label>
                  <Input
                    id="email"
                    type="email"
                    value={email}
                    onChange={event => setEmail(event.target.value)}
                    autoComplete="email"
                    required
                  />
                </div>

                <div className="space-y-2">
                  <Label htmlFor="password">Mot de passe</Label>
                  <Input
                    id="password"
                    type="password"
                    value={password}
                    onChange={event => setPassword(event.target.value)}
                    autoComplete={mode === "login" ? "current-password" : "new-password"}
                    minLength={mode === "register" ? 8 : 1}
                    required
                  />
                </div>

                <Button type="submit" className="w-full gap-2" disabled={loading}>
                  {mode === "login" ? <LogIn className="h-4 w-4" /> : <UserPlus className="h-4 w-4" />}
                  {mode === "login" ? "Se connecter" : "Creer mon compte"}
                </Button>

                <p className="text-xs leading-5 text-muted-foreground">
                  En créant un compte, vous serez invité à confirmer l’information relative au traitement des données personnelles.
                  <Link href="/confidentialite" className="ml-1 font-medium text-primary underline underline-offset-4">
                    Consulter la politique de confidentialité
                  </Link>
                </p>
              </form>
            </Tabs>
          </CardContent>
        </Card>
      </main>

      {mfaChallenge ? (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4">
              <Card className="w-full max-w-md shadow-lg">
            <CardHeader>
              <CardTitle>Verification en 2 etapes</CardTitle>
              <CardDescription>
                {mfaChallenge.challengeType === "email"
                  ? `Un code a 6 chiffres a ete envoye sur ${mfaChallenge.maskedEmail}.`
                  : "Saisissez le code genere par votre application Authenticator."}
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-4">
              {(verifyMfaMutation.error || resendMfaMutation.error) ? (
                <Alert variant="destructive">
                  <AlertCircle className="h-4 w-4" />
                  <AlertDescription>
                    {verifyMfaMutation.error?.message || resendMfaMutation.error?.message}
                  </AlertDescription>
                </Alert>
              ) : null}

              <div className="space-y-2">
                  <Label>{mfaChallenge.challengeType === "email" ? "Code reçu par email" : "Code Authenticator"}</Label>
                  <InputOTP maxLength={6} value={mfaCode} onChange={setMfaCode}>
                  <InputOTPGroup>
                    <InputOTPSlot index={0} />
                    <InputOTPSlot index={1} />
                    <InputOTPSlot index={2} />
                    <InputOTPSlot index={3} />
                    <InputOTPSlot index={4} />
                    <InputOTPSlot index={5} />
                  </InputOTPGroup>
                </InputOTP>
              </div>

              <div className="flex flex-col gap-3">
                <Button
                  onClick={handleVerifyMfa}
                  disabled={mfaCode.length !== 6 || verifyMfaMutation.isPending}
                >
                  Verifier le code
                </Button>
                {mfaChallenge.challengeType === "email" ? (
                  <Button
                    variant="outline"
                    onClick={handleResendMfa}
                    disabled={resendMfaMutation.isPending}
                  >
                    Renvoyer le code
                  </Button>
                ) : null}
                <Button
                  variant="ghost"
                  onClick={() => {
                    setMfaChallenge(null);
                    setMfaCode("");
                  }}
                >
                  Annuler
                </Button>
              </div>
            </CardContent>
          </Card>
        </div>
      ) : null}

      <DataPrivacyValidationDialog
        open={privacyDialogOpen}
        onOpenChange={setPrivacyDialogOpen}
        context="register_account"
        confirmLabel="Valider et créer le compte"
        onConfirm={handleRegisterWithPrivacyConsent}
      />
    </div>
  );
}
