import { useEffect } from "react";
import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
import { useForm } from "@tanstack/react-form";
import { useMutation } from "@tanstack/react-query";
import { toast } from "sonner";
import { ArrowRight } from "lucide-react";
import { z } from "zod";

import { loginSchema, type AuthSession, type LoginInput } from "@rubis/shared";

import { api, ApiError } from "@/lib/api";
import { authStore } from "@/lib/auth";
import { Button } from "@/components/ui/Button";
import { Input } from "@/components/ui/Input";
import { Field } from "@/components/ui/Field";
import { Eyebrow } from "@/components/ui/Eyebrow";
import { Brand } from "@/components/brand/Brand";
import { Gem } from "@/components/brand/Gem";
import { SsoButton, AuthDivider } from "@/components/auth/SsoButton";

const ssoErrorEnum = z
  .enum(["denied", "state_mismatch", "error", "no_email"])
  .optional();

const searchSchema = z.object({
  redirect: z.string().optional(),
  google: ssoErrorEnum,
  microsoft: ssoErrorEnum,
});

const SSO_ERROR_MESSAGES: Record<string, Record<string, string>> = {
  google: {
    denied: "Connexion Google annulée.",
    state_mismatch: "Session expirée, réessayez la connexion Google.",
    error: "Connexion Google impossible. Réessayez dans un instant.",
    no_email: "Votre compte Google n'a pas d'email associé.",
  },
  microsoft: {
    denied: "Connexion Microsoft annulée.",
    state_mismatch: "Session expirée, réessayez la connexion Microsoft.",
    error: "Connexion Microsoft impossible. Réessayez dans un instant.",
    no_email: "Votre compte Microsoft n'a pas d'email associé.",
  },
};

export const Route = createFileRoute("/login")({
  validateSearch: searchSchema,
  component: LoginPage,
});

function LoginPage() {
  const navigate = useNavigate();
  const search = Route.useSearch();

  // Toast d'erreur si on revient d'un échec SSO (?google=denied, ?microsoft=…).
  useEffect(() => {
    for (const provider of ["google", "microsoft"] as const) {
      const code = search[provider];
      if (code && SSO_ERROR_MESSAGES[provider]?.[code]) {
        toast.error(SSO_ERROR_MESSAGES[provider]![code]!);
      }
    }
  }, [search.google, search.microsoft]);

  const loginMutation = useMutation({
    mutationFn: async (input: LoginInput) =>
      api.post<AuthSession>("/api/v1/auth/login", input, { anonymous: true }),
    onSuccess: (session) => {
      authStore.setSession(session.accessToken, session.user);
      toast.success(`Bonjour ${session.user.fullName.split(" ")[0]}.`);
      // Si on a une URL de redirection (depuis le guard d'auth), on la suit ;
      // sinon /  qui décide quoi faire selon l'état d'onboarding.
      void navigate({ to: search.redirect ?? "/" });
    },
    onError: (error: unknown) => {
      if (error instanceof ApiError && error.status === 401) {
        toast.error("Email ou mot de passe incorrect.");
        return;
      }
      toast.error("Connexion impossible. Réessayez dans un instant.");
    },
  });

  const form = useForm({
    defaultValues: { email: "", password: "" } satisfies LoginInput,
    validators: {
      onChange: loginSchema,
    },
    onSubmit: async ({ value }) => {
      await loginMutation.mutateAsync(value);
    },
  });

  return (
    <main className="min-h-screen bg-cream relative overflow-hidden">
      {/* Glow rubis discret en haut-droite — signature visuelle (cohérent landing). */}
      <div
        aria-hidden="true"
        className="pointer-events-none absolute top-[-180px] right-[-220px] size-[680px] rounded-full"
        style={{
          background:
            "radial-gradient(circle, rgba(251,228,234,0.55), transparent 60%)",
        }}
      />

      <div className="relative z-10 mx-auto grid min-h-screen w-full max-w-[1180px] grid-cols-1 gap-16 px-6 py-12 lg:grid-cols-[1.1fr_1fr] lg:items-center lg:px-8">
        {/* Colonne gauche — message marketing.
            Décalée, dense, du caractère. Pas une carte centrée et fade. */}
        <section className="order-2 lg:order-1 max-w-[520px]">
          <div className="flex flex-col gap-4">
            <Link to="/login" className="inline-block">
              <Brand withSuffix />
            </Link>
            <Eyebrow>Bon retour</Eyebrow>
          </div>
          <h1 className="mt-4 font-display text-[44px] font-bold leading-[1.05] tracking-tight text-ink lg:text-[52px]">
            Vos factures vous <em>attendent</em>.
            <br className="hidden sm:block" />
            On reprend où vous en étiez.
          </h1>
          <p className="mt-5 max-w-md text-[16px] leading-[1.6] text-ink-2">
            Connectez-vous pour voir où en sont vos relances, qui a payé,
            et combien de temps Rubis vous a fait gagner cette semaine.
          </p>

          <ul className="mt-10 flex flex-wrap gap-x-6 gap-y-3 text-[12.5px] text-ink-3">
            <li className="inline-flex items-center gap-2">
              <Gem size={10} /> Hébergement souverain
            </li>
            <li className="inline-flex items-center gap-2">
              <span className="size-1 rounded-full bg-ink-3" aria-hidden="true" />
              Made in France
            </li>
            <li className="inline-flex items-center gap-2">
              <span className="size-1 rounded-full bg-ink-3" aria-hidden="true" />
              RGPD-friendly
            </li>
          </ul>
        </section>

        {/* Colonne droite — formulaire de connexion */}
        <section className="order-1 lg:order-2">
          <div className="mx-auto w-full max-w-[420px] rounded-card border border-line bg-white p-8 shadow-card">
            <h2 className="font-display text-2xl font-semibold tracking-[-0.018em] text-ink">
              Se connecter
            </h2>
            <p className="mt-1.5 text-[14px] text-ink-3">
              Pas encore de compte ?{" "}
              <Link
                to="/signup"
                className="font-medium text-rubis underline-offset-4 hover:underline"
              >
                Créer un compte
              </Link>
            </p>

            <div className="mt-7 flex flex-col gap-2">
              <SsoButton provider="google" />
              <SsoButton provider="microsoft" />
              <AuthDivider />
            </div>

            <form
              noValidate
              onSubmit={(e) => {
                e.preventDefault();
                void form.handleSubmit();
              }}
              className="flex flex-col gap-5"
            >
              <form.Field name="email">
                {(field) => (
                  <Field
                    label="Email"
                    htmlFor={field.name}
                    error={field.state.meta.errors[0]?.message}
                  >
                    <Input
                      id={field.name}
                      name={field.name}
                      type="email"
                      autoComplete="email"
                      autoFocus
                      placeholder="vous@entreprise.fr"
                      value={field.state.value}
                      onBlur={field.handleBlur}
                      onChange={(e) => field.handleChange(e.target.value)}
                      aria-invalid={field.state.meta.errors.length > 0}
                    />
                  </Field>
                )}
              </form.Field>

              <form.Field name="password">
                {(field) => (
                  <Field
                    label="Mot de passe"
                    htmlFor={field.name}
                    error={field.state.meta.errors[0]?.message}
                  >
                    <Input
                      id={field.name}
                      name={field.name}
                      type="password"
                      autoComplete="current-password"
                      placeholder="••••••••"
                      value={field.state.value}
                      onBlur={field.handleBlur}
                      onChange={(e) => field.handleChange(e.target.value)}
                      aria-invalid={field.state.meta.errors.length > 0}
                    />
                  </Field>
                )}
              </form.Field>

              <Button
                type="submit"
                size="md"
                loading={loginMutation.isPending}
                className="mt-1 w-full"
              >
                Continuer <ArrowRight size={16} aria-hidden="true" />
              </Button>

              <p className="text-center text-[12.5px] text-ink-3">
                <Link to="/login" className="hover:text-rubis hover:underline">
                  Mot de passe oublié ?
                </Link>
              </p>
            </form>
          </div>
        </section>
      </div>
    </main>
  );
}
