import type { FormComponentRef } from '@inertiajs/core';
import { Form, Head, usePage } from '@inertiajs/react';
import { Eye, EyeOff, Loader2, Lock, Mail } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import { toast, Toaster } from 'sonner';
import { Button } from '@/components/ui/button';
import {
    Field,
    FieldError,
    FieldGroup,
    FieldLabel,
} from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import { Separator } from '@/components/ui/separator';
import { EMAIL_MAX, EMAIL_REGEX, PASSWORD_MAX } from '@/lib/constants';
import { route } from '@/lib/route';
import { cn } from '@/lib/utils';

function loginClientErrors(data: Record<string, unknown>): Record<string, string> {
    const errors: Record<string, string> = {};
    const email = String(data.email ?? '').trim();
    const password = String(data.password ?? '');

    if (!email) {
        errors.email = 'The email field is required.';
    } else if (email.length > EMAIL_MAX) {
        errors.email = `The email field must not be greater than ${EMAIL_MAX} characters.`;
    } else if (!EMAIL_REGEX.test(email)) {
        errors.email = 'The email field must be a valid email address.';
    }

    if (!password) {
        errors.password = 'The password field is required.';
    } else if (password.length > PASSWORD_MAX) {
        errors.password = `The password field must not be greater than ${PASSWORD_MAX} characters.`;
    }

    return errors;
}

export default function Login() {
    const formRef = useRef<FormComponentRef | null>(null);
    const [passwordVisible, setPasswordVisible] = useState(false);
    const { flash } = usePage().props as {
        flash?: { success?: string | null; error?: string | null };
    };

    useEffect(() => {
        if (flash?.error) {
            toast.error(flash.error);
        }
    }, [flash?.error]);

    return (
        <>
            <Head title="Sign in" />
            <Toaster
                position="bottom-right"
                toastOptions={{
                    classNames: {
                        error: '!bg-red-600 !text-white !border-red-700 [&_[data-icon]]:!text-white',
                    },
                }}
            />

            <div className="grid min-h-svh lg:grid-cols-2">
                <aside
                    className={cn(
                        'login-brand relative hidden overflow-hidden lg:flex lg:flex-col lg:justify-between',
                        'px-12 py-12 xl:px-16',
                    )}
                >
                    <div aria-hidden className="login-brand-grid absolute inset-0" />
                    <div
                        aria-hidden
                        className="login-brand-orb absolute -right-24 top-1/4 size-[28rem] rounded-full blur-3xl"
                    />
                    <div
                        aria-hidden
                        className="login-brand-orb-soft absolute -bottom-20 -left-16 size-[22rem] rounded-full blur-3xl"
                    />

                    <p
                        className={cn(
                            'relative font-heading text-5xl font-semibold tracking-tight text-primary-foreground xl:text-6xl',
                            'motion-safe:animate-in motion-safe:fade-in motion-safe:slide-in-from-left-4 motion-safe:duration-700',
                        )}
                    >
                        SuperGame
                    </p>

                    <div
                        className={cn(
                            'relative max-w-md space-y-4',
                            'motion-safe:animate-in motion-safe:fade-in motion-safe:slide-in-from-bottom-3 motion-safe:duration-700 motion-safe:delay-150',
                        )}
                    >
                        <span
                            aria-hidden
                            className="block h-1 w-14 bg-primary-foreground/80"
                        />
                        <p className="font-heading text-2xl font-medium leading-snug text-primary-foreground xl:text-3xl">
                            Leagues, fixtures, and match day — one place.
                        </p>
                        <p className="text-sm leading-relaxed text-primary-foreground/70">
                            Sign in to keep your competitions running.
                        </p>
                    </div>
                </aside>

                <main className="login-form-shell relative flex flex-col justify-center px-6 py-12 sm:px-10 lg:px-16">
                    <div
                        className={cn(
                            'mx-auto w-full max-w-[520px]',
                            'motion-safe:animate-in motion-safe:fade-in motion-safe:slide-in-from-bottom-2 motion-safe:duration-500',
                        )}
                    >
                        <p className="mb-8 font-heading text-3xl font-semibold tracking-tight text-foreground lg:hidden">
                            SuperGame
                        </p>

                        <div className="rounded-2xl border border-border/70 bg-card shadow-[0_1px_2px_oklch(0_0_0/4%),0_12px_40px_-12px_oklch(0_0_0/12%)]">
                            <div className="space-y-10 p-10 sm:p-12">
                                <header className="space-y-2">
                                    <h1 className="font-heading text-3xl font-semibold tracking-tight text-foreground">
                                        Sign in
                                    </h1>
                                    <p className="text-base leading-relaxed text-muted-foreground">
                                        Enter your credentials to continue.
                                    </p>
                                </header>

                                <Form
                                    ref={formRef}
                                    action={route('login.store')}
                                    method="post"
                                    resetOnSuccess={['password']}
                                    noValidate
                                    onBefore={() => {
                                        const errors = loginClientErrors(
                                            formRef.current?.getData() ?? {},
                                        );

                                        if (Object.keys(errors).length > 0) {
                                            formRef.current?.setError(errors);

                                            return false;
                                        }

                                        formRef.current?.clearErrors();
                                    }}
                                    onError={(errors) => {
                                        if (errors.account) {
                                            toast.error(errors.account);
                                        }
                                    }}
                                >
                                    {({ errors, processing, clearErrors }) => (
                                        <FieldGroup className="gap-6">
                                            <Field data-invalid={!!errors.email || undefined}>
                                                <FieldLabel
                                                    htmlFor="email"
                                                    className="text-xs font-medium uppercase tracking-wider text-muted-foreground"
                                                >
                                                    Email{' '}
                                                    <span className="text-destructive" aria-hidden>
                                                        *
                                                    </span>
                                                </FieldLabel>
                                                <div className="relative">
                                                    <Mail
                                                        aria-hidden
                                                        className="pointer-events-none absolute top-1/2 left-3.5 size-4 -translate-y-1/2 text-muted-foreground/70"
                                                    />
                                                    <Input
                                                        id="email"
                                                        name="email"
                                                        type="email"
                                                        inputMode="email"
                                                        autoComplete="username"
                                                        autoFocus
                                                        maxLength={EMAIL_MAX}
                                                        placeholder="you@club.com"
                                                        aria-invalid={!!errors.email || undefined}
                                                        onInput={() => clearErrors('email')}
                                                        className="h-12 border-border/80 bg-muted/40 pl-10 text-base shadow-none transition-colors focus-visible:bg-background"
                                                    />
                                                </div>
                                                <FieldError>{errors.email}</FieldError>
                                            </Field>

                                            <Field data-invalid={!!errors.password || undefined}>
                                                <FieldLabel
                                                    htmlFor="password"
                                                    className="text-xs font-medium uppercase tracking-wider text-muted-foreground"
                                                >
                                                    Password{' '}
                                                    <span className="text-destructive" aria-hidden>
                                                        *
                                                    </span>
                                                </FieldLabel>
                                                <div className="relative">
                                                    <Lock
                                                        aria-hidden
                                                        className="pointer-events-none absolute top-1/2 left-3.5 size-4 -translate-y-1/2 text-muted-foreground/70"
                                                    />
                                                    <Input
                                                        id="password"
                                                        name="password"
                                                        type={passwordVisible ? 'text' : 'password'}
                                                        autoComplete="current-password"
                                                        maxLength={PASSWORD_MAX}
                                                        placeholder="••••••••"
                                                        aria-invalid={!!errors.password || undefined}
                                                        onInput={() => clearErrors('password')}
                                                        className="h-12 border-border/80 bg-muted/40 pl-10 pr-11 text-base shadow-none transition-colors focus-visible:bg-background"
                                                    />
                                                    <button
                                                        type="button"
                                                        aria-label={
                                                            passwordVisible
                                                                ? 'Hide password'
                                                                : 'Show password'
                                                        }
                                                        aria-pressed={passwordVisible}
                                                        onClick={() =>
                                                            setPasswordVisible(
                                                                (v) => !v,
                                                            )
                                                        }
                                                        className="absolute top-1/2 right-3.5 -translate-y-1/2 cursor-pointer text-muted-foreground/70 transition-colors hover:text-foreground"
                                                    >
                                                        {passwordVisible ? (
                                                            <EyeOff
                                                                aria-hidden
                                                                className="size-4"
                                                            />
                                                        ) : (
                                                            <Eye
                                                                aria-hidden
                                                                className="size-4"
                                                            />
                                                        )}
                                                    </button>
                                                </div>
                                                <FieldError>{errors.password}</FieldError>
                                            </Field>

                                            <div className="flex items-center justify-between pt-1">
                                                <label
                                                    htmlFor="remember"
                                                    className="flex cursor-pointer items-center gap-2.5 text-sm text-muted-foreground"
                                                >
                                                    <input
                                                        id="remember"
                                                        name="remember"
                                                        type="checkbox"
                                                        value="1"
                                                        className="size-4 cursor-pointer rounded-[4px] border border-input accent-primary"
                                                    />
                                                    Remember me
                                                </label>
                                            </div>

                                            <Separator className="bg-border/60" />

                                            <Button
                                                type="submit"
                                                size="lg"
                                                disabled={processing}
                                                className="h-12 w-full cursor-pointer gap-2 text-base font-semibold shadow-[0_1px_2px_oklch(0_0_0/8%)] transition-all duration-200 hover:brightness-110 active:translate-y-px disabled:opacity-70"
                                            >
                                                {processing && (
                                                    <Loader2
                                                        aria-hidden
                                                        className="size-4 animate-spin"
                                                    />
                                                )}
                                                {processing ? 'Signing in…' : 'Sign in'}
                                            </Button>
                                        </FieldGroup>
                                    )}
                                </Form>
                            </div>
                        </div>
                    </div>
                </main>
            </div>
        </>
    );
}
