// @ts-ignore - Inertia types are available at runtime
import { GoogleIcon } from '@/components/icons/google-icon';
import { Head, Link, useForm, usePage } from '@inertiajs/react';
import { LoaderCircle } from 'lucide-react';
import { FormEventHandler, memo, useCallback, useEffect, useMemo, useRef } from 'react';
import { Toaster } from 'sonner';

import AppLogoIcon from '@/components/layout/app-logo-icon';
import InputError from '@/components/shared/input-error';
import TextLink from '@/components/shared/text-link';
import { Button } from '@/components/ui/button';
import { Field, FieldDescription, FieldGroup, FieldLabel, FieldSeparator } from '@/components/ui/field-1';
import { Input } from '@/components/ui/input';
import { ProtojahBg, ProtojahFormBg } from '@/components/ui/protojah-bg';
import { getFontClass } from '@/lib/fonts';

// CSRF token is handled automatically in app.tsx

// Memoized background component to prevent re-renders
const BackgroundComponent = memo(function BackgroundComponent({ loginBackgroundUrl }: { loginBackgroundUrl: string | null }) {
    const isVideo = loginBackgroundUrl?.toLowerCase().endsWith('.mp4');

    return (
        <div className="relative hidden h-full lg:block">
            {loginBackgroundUrl ? (
                isVideo ? (
                    <video autoPlay loop muted playsInline className="absolute inset-0 h-full w-full object-cover">
                        <source src={loginBackgroundUrl} type="video/mp4" />
                    </video>
                ) : (
                    <img
                        src={loginBackgroundUrl}
                        alt=""
                        className="absolute inset-0 h-full w-full object-cover"
                        loading="lazy"
                        decoding="async"
                        fetchPriority="low"
                    />
                )
            ) : (
                <ProtojahBg />
            )}
        </div>
    );
});

type RegisterForm = {
    name: string;
    truename: string;
    email: string;
    password: string;
    password_confirmation: string;
    pin: string;
    'cf-turnstile-response': string;
};

interface Props {
    pinFieldEnabled: boolean;
    googleLoginEnabled: boolean;
}

export default function Register({ pinFieldEnabled, googleLoginEnabled }: Props) {
    const { appName, appLogoUrl, loginBackgroundUrl, loginBackgroundPosition, turnstile, appFont, appNameColor, heroUseLogo } = usePage()
        .props as any;
    const { data, setData, post, processing, errors, reset } = useForm<Required<RegisterForm>>({
        name: '',
        truename: '',
        email: '',
        password: '',
        password_confirmation: '',
        pin: '',
        'cf-turnstile-response': '',
    });

    const observerRef = useRef<MutationObserver | null>(null);
    const turnstileScriptLoadedRef = useRef(false);

    // Memoize gradient colors to prevent recalculation
    const gradientColors = useMemo(() => ['#bcecf6', '#00aaff', '#ffd447'], []);

    // Memoize background settings
    const backgroundSettings = useMemo(
        () => ({
            onLeft: loginBackgroundPosition === 'left',
            isFullWidth: loginBackgroundPosition === 'full',
            isVideo: loginBackgroundUrl?.toLowerCase().endsWith('.mp4'),
        }),
        [loginBackgroundPosition, loginBackgroundUrl],
    );

    // Memoized turnstile callback to prevent recreation
    const handleTurnstileCallback = useCallback(
        (token: string) => {
            setData('cf-turnstile-response', token);
        },
        [setData],
    );

    // Set turnstile callback once on mount
    useEffect(() => {
        (window as any).onTurnstileCallback = handleTurnstileCallback;
        return () => {
            delete (window as any).onTurnstileCallback;
        };
    }, [handleTurnstileCallback]);

    // Optimized Turnstile script loading - load only once
    useEffect(() => {
        if (turnstile?.enabled && turnstile?.siteKey && !turnstileScriptLoadedRef.current) {
            const script = document.createElement('script');
            script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
            script.async = true;
            script.defer = true;
            document.body.appendChild(script);
            turnstileScriptLoadedRef.current = true;

            return () => {
                if (document.body.contains(script)) {
                    document.body.removeChild(script);
                    turnstileScriptLoadedRef.current = false;
                }
            };
        }
    }, [turnstile?.enabled, turnstile?.siteKey]);

    // Optimized dark theme effect
    useEffect(() => {
        const html = document.documentElement;

        // Add dark theme only if not already present
        if (!html.classList.contains('dark')) {
            html.classList.add('dark');
        }
        html.setAttribute('data-force-dark', 'true');

        // Create observer
        if (!observerRef.current) {
            observerRef.current = new MutationObserver((mutations) => {
                for (const mutation of mutations) {
                    if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
                        if (!html.classList.contains('dark')) {
                            html.classList.add('dark');
                        }
                        break; // Early exit once dark class is ensured
                    }
                }
            });

            observerRef.current.observe(html, { attributes: true, attributeFilter: ['class'] });
        }

        return () => {
            if (observerRef.current) {
                observerRef.current.disconnect();
                observerRef.current = null;
            }
            html.classList.remove('dark');
            html.removeAttribute('data-force-dark');
        };
    }, []);

    // Memoized submit handler
    const submit = useCallback<FormEventHandler>(
        (e) => {
            e.preventDefault();
            setData('name', data.name.toLowerCase());
            post(route('register'), {
                onFinish: () => reset('password', 'password_confirmation'),
            });
        },
        [post, reset, data.name],
    );

    const handleNameChange = useCallback(
        (e: React.ChangeEvent<HTMLInputElement>) => {
            setData('name', e.target.value.toLowerCase());
        },
        [setData],
    );

    // Full width layout
    if (backgroundSettings.isFullWidth) {
        return (
            <>
                <Head title={`Register - ${appName}`} />
                <Toaster position="top-right" richColors closeButton duration={4000} />

                <div className="relative flex h-svh items-center justify-center py-8">
                    {/* Full width background */}
                    <div className="absolute inset-0 z-0">
                        {loginBackgroundUrl ? (
                            backgroundSettings.isVideo ? (
                                <video autoPlay loop muted playsInline className="h-full w-full object-cover">
                                    <source src={loginBackgroundUrl} type="video/mp4" />
                                </video>
                            ) : (
                                <img
                                    src={loginBackgroundUrl}
                                    alt=""
                                    className="h-full w-full object-cover"
                                    loading="lazy"
                                    decoding="async"
                                    fetchPriority="low"
                                />
                            )
                        ) : (
                            <ProtojahBg />
                        )}
                        {/* Overlay for readability */}
                        <div className="absolute inset-0 bg-black/40" />
                    </div>

                    {/* Centered form card */}
                    <div className="relative z-10 mx-4 w-full max-w-md">
                        <div className="bg-background/25 scrollbar-hide max-h-[85svh] overflow-y-auto rounded-xl p-8 shadow-2xl backdrop-blur-sm">
                            <form className="flex flex-col gap-6" onSubmit={submit}>
                                <FieldGroup>
                                    {/* Logo */}
                                    <div className="flex justify-center">
                                        <Link href={route('home')} className="flex items-center gap-2">
                                            {appLogoUrl ? (
                                                <img
                                                    src={appLogoUrl}
                                                    alt={appName || 'Logo'}
                                                    className="h-32 w-32 object-contain"
                                                    width="128"
                                                    height="128"
                                                    loading="lazy"
                                                    decoding="async"
                                                />
                                            ) : (
                                                <AppLogoIcon className="h-32 w-32 fill-current text-[var(--foreground)] dark:text-white" />
                                            )}
                                        </Link>
                                    </div>

                                    {/* Header */}
                                    <div className="flex flex-col items-center gap-1 text-center">
                                        {!heroUseLogo && (
                                            <h1
                                                className={`bg-clip-text pb-1 text-center text-3xl leading-normal font-bold text-transparent drop-shadow-lg ${getFontClass(appFont)}`}
                                                style={{
                                                    backgroundImage: appNameColor
                                                        ? `linear-gradient(to bottom, white, ${appNameColor}, ${appNameColor}dd)`
                                                        : 'linear-gradient(to bottom, white, #fcd34d, #d97706)',
                                                }}
                                            >
                                                {appName}
                                            </h1>
                                        )}
                                        <p className="text-muted-foreground text-sm text-balance">Register Account</p>
                                    </div>

                                    {/* Username and Full Name */}
                                    <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
                                        <Field>
                                            <FieldLabel htmlFor="name">Username</FieldLabel>
                                            <Input
                                                id="name"
                                                type="text"
                                                required
                                                autoFocus
                                                tabIndex={1}
                                                autoComplete="username"
                                                value={data.name}
                                                onChange={handleNameChange}
                                                disabled={processing}
                                                placeholder="Username"
                                            />
                                            <InputError message={errors.name} />
                                        </Field>

                                        <Field>
                                            <FieldLabel htmlFor="truename">Full Name</FieldLabel>
                                            <Input
                                                id="truename"
                                                type="text"
                                                required
                                                tabIndex={2}
                                                autoComplete="name"
                                                value={data.truename}
                                                onChange={(e) => setData('truename', e.target.value)}
                                                disabled={processing}
                                                placeholder="Your full name"
                                            />
                                            <InputError message={errors.truename} />
                                        </Field>
                                    </div>

                                    {/* Email Field */}
                                    <Field>
                                        <FieldLabel htmlFor="email">Email address</FieldLabel>
                                        <Input
                                            id="email"
                                            type="email"
                                            required
                                            tabIndex={3}
                                            autoComplete="email"
                                            value={data.email}
                                            onChange={(e) => setData('email', e.target.value)}
                                            disabled={processing}
                                            placeholder="example@gmail.com"
                                        />
                                        <InputError message={errors.email} />
                                    </Field>

                                    {/* Security PIN (conditional) */}
                                    {pinFieldEnabled === true && (
                                        <Field>
                                            <FieldLabel htmlFor="pin">Security PIN</FieldLabel>
                                            <Input
                                                id="pin"
                                                type="text"
                                                inputMode="numeric"
                                                pattern="[0-9]{6}"
                                                maxLength={6}
                                                required
                                                tabIndex={4}
                                                value={data.pin}
                                                onChange={(e) => {
                                                    const value = e.target.value.replace(/\D/g, '').slice(0, 6);
                                                    setData('pin', value);
                                                }}
                                                disabled={processing}
                                                placeholder="6-digit PIN"
                                            />
                                            <p className="text-muted-foreground text-xs">This PIN is required to change your password</p>
                                            <InputError message={errors.pin} />
                                        </Field>
                                    )}

                                    {/* Password Field */}
                                    <Field>
                                        <FieldLabel htmlFor="password">Password</FieldLabel>
                                        <Input
                                            id="password"
                                            type="password"
                                            required
                                            tabIndex={pinFieldEnabled ? 5 : 4}
                                            autoComplete="new-password"
                                            value={data.password}
                                            onChange={(e) => setData('password', e.target.value)}
                                            disabled={processing}
                                            placeholder="Create a strong password"
                                        />
                                        <InputError message={errors.password} />
                                    </Field>

                                    {/* Confirm Password Field */}
                                    <Field>
                                        <FieldLabel htmlFor="password_confirmation">Confirm Password</FieldLabel>
                                        <Input
                                            id="password_confirmation"
                                            type="password"
                                            required
                                            tabIndex={pinFieldEnabled ? 6 : 5}
                                            autoComplete="new-password"
                                            value={data.password_confirmation}
                                            onChange={(e) => setData('password_confirmation', e.target.value)}
                                            disabled={processing}
                                            placeholder="Confirm your password"
                                        />
                                        <InputError message={errors.password_confirmation} />
                                    </Field>

                                    {/* Turnstile widget - conditional */}
                                    {turnstile?.enabled && turnstile?.siteKey && (
                                        <div className="flex flex-col items-center gap-2">
                                            <div className="cf-turnstile" data-sitekey={turnstile.siteKey} data-callback="onTurnstileCallback" />
                                            <InputError message={errors['cf-turnstile-response']} />
                                        </div>
                                    )}

                                    {/* Submit Button */}
                                    <Field>
                                        <Button type="submit" className="w-full" tabIndex={pinFieldEnabled ? 7 : 6} disabled={processing}>
                                            {processing && <LoaderCircle className="h-4 w-4 animate-spin" />}
                                            Create account
                                        </Button>
                                    </Field>

                                    {/* Google Auth Button */}
                                    {googleLoginEnabled && (
                                        <>
                                            <FieldSeparator>Or continue with</FieldSeparator>
                                            <Field>
                                                <Button
                                                    type="button"
                                                    variant="outline"
                                                    className="w-full"
                                                    tabIndex={pinFieldEnabled ? 8 : 7}
                                                    onClick={() => (window.location.href = route('auth.google'))}
                                                >
                                                    <GoogleIcon className="mr-2 h-4 w-4" />
                                                    Sign up with Google
                                                </Button>
                                            </Field>
                                        </>
                                    )}

                                    {/* Login Link */}
                                    <FieldDescription className="text-center">
                                        Already have an account?{' '}
                                        <TextLink href={route('login')} tabIndex={pinFieldEnabled ? 9 : 8}>
                                            Log in
                                        </TextLink>
                                    </FieldDescription>
                                </FieldGroup>
                            </form>
                        </div>
                    </div>
                </div>
            </>
        );
    }

    return (
        <>
            <Head title={`Register - ${appName}`} />
            <Toaster position="top-right" richColors closeButton duration={4000} />

            <div className={`grid h-svh ${backgroundSettings.onLeft ? 'lg:grid-cols-[75%_25%]' : 'lg:grid-cols-[25%_75%]'} overflow-hidden`}>
                {/* Background - conditionally first */}
                {backgroundSettings.onLeft && <BackgroundComponent loginBackgroundUrl={loginBackgroundUrl} />}

                {/* Register Form */}
                <div className="relative flex flex-col gap-4 p-6 md:p-10">
                    <ProtojahFormBg className="absolute inset-0" />
                    {/* Form Container */}
                    <div className="scrollbar-hide flex w-full flex-1 items-center justify-center overflow-y-auto">
                        <div className="w-full max-w-sm">
                            <form className="flex flex-col gap-6" onSubmit={submit}>
                                <FieldGroup>
                                    {/* Logo */}
                                    <div className="flex justify-center">
                                        <Link href={route('home')} className="flex items-center gap-2">
                                            {appLogoUrl ? (
                                                <img
                                                    src={appLogoUrl}
                                                    alt={appName || 'Logo'}
                                                    className="h-32 w-32 object-contain"
                                                    width="128"
                                                    height="128"
                                                    loading="lazy"
                                                    decoding="async"
                                                />
                                            ) : (
                                                <AppLogoIcon className="h-32 w-32 fill-current text-[var(--foreground)] dark:text-white" />
                                            )}
                                        </Link>
                                    </div>

                                    {/* Header */}
                                    <div className="flex flex-col items-center gap-1 text-center">
                                        {!heroUseLogo && (
                                            <h1
                                                className={`bg-clip-text pb-1 text-center text-3xl leading-normal font-bold text-transparent drop-shadow-lg ${getFontClass(appFont)}`}
                                                style={{
                                                    backgroundImage: appNameColor
                                                        ? `linear-gradient(to bottom, white, ${appNameColor}, ${appNameColor}dd)`
                                                        : 'linear-gradient(to bottom, white, #fcd34d, #d97706)',
                                                }}
                                            >
                                                {appName}
                                            </h1>
                                        )}
                                        <p className="text-muted-foreground text-sm text-balance">Register Account</p>
                                    </div>

                                    {/* Username and Full Name */}
                                    <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
                                        <Field>
                                            <FieldLabel htmlFor="name">Username</FieldLabel>
                                            <Input
                                                id="name"
                                                type="text"
                                                required
                                                autoFocus
                                                tabIndex={1}
                                                autoComplete="username"
                                                value={data.name}
                                                onChange={handleNameChange}
                                                disabled={processing}
                                                placeholder="Username"
                                            />
                                            <InputError message={errors.name} />
                                        </Field>

                                        <Field>
                                            <FieldLabel htmlFor="truename">Full Name</FieldLabel>
                                            <Input
                                                id="truename"
                                                type="text"
                                                required
                                                tabIndex={2}
                                                autoComplete="name"
                                                value={data.truename}
                                                onChange={(e) => setData('truename', e.target.value)}
                                                disabled={processing}
                                                placeholder="Your full name"
                                            />
                                            <InputError message={errors.truename} />
                                        </Field>
                                    </div>

                                    {/* Email Field */}
                                    <Field>
                                        <FieldLabel htmlFor="email">Email address</FieldLabel>
                                        <Input
                                            id="email"
                                            type="email"
                                            required
                                            tabIndex={3}
                                            autoComplete="email"
                                            value={data.email}
                                            onChange={(e) => setData('email', e.target.value)}
                                            disabled={processing}
                                            placeholder="example@gmail.com"
                                        />
                                        <InputError message={errors.email} />
                                    </Field>

                                    {/* Security PIN (conditional) */}
                                    {pinFieldEnabled === true && (
                                        <Field>
                                            <FieldLabel htmlFor="pin">Security PIN</FieldLabel>
                                            <Input
                                                id="pin"
                                                type="text"
                                                inputMode="numeric"
                                                pattern="[0-9]{6}"
                                                maxLength={6}
                                                required
                                                tabIndex={4}
                                                value={data.pin}
                                                onChange={(e) => {
                                                    const value = e.target.value.replace(/\D/g, '').slice(0, 6);
                                                    setData('pin', value);
                                                }}
                                                disabled={processing}
                                                placeholder="6-digit PIN"
                                            />
                                            <p className="text-muted-foreground text-xs">This PIN is required to change your password</p>
                                            <InputError message={errors.pin} />
                                        </Field>
                                    )}

                                    {/* Password Field */}
                                    <Field>
                                        <FieldLabel htmlFor="password">Password</FieldLabel>
                                        <Input
                                            id="password"
                                            type="password"
                                            required
                                            tabIndex={pinFieldEnabled ? 5 : 4}
                                            autoComplete="new-password"
                                            value={data.password}
                                            onChange={(e) => setData('password', e.target.value)}
                                            disabled={processing}
                                            placeholder="Create a strong password"
                                        />
                                        <InputError message={errors.password} />
                                    </Field>

                                    {/* Confirm Password Field */}
                                    <Field>
                                        <FieldLabel htmlFor="password_confirmation">Confirm Password</FieldLabel>
                                        <Input
                                            id="password_confirmation"
                                            type="password"
                                            required
                                            tabIndex={pinFieldEnabled ? 6 : 5}
                                            autoComplete="new-password"
                                            value={data.password_confirmation}
                                            onChange={(e) => setData('password_confirmation', e.target.value)}
                                            disabled={processing}
                                            placeholder="Confirm your password"
                                        />
                                        <InputError message={errors.password_confirmation} />
                                    </Field>

                                    {/* Turnstile widget - conditional */}
                                    {turnstile?.enabled && turnstile?.siteKey && (
                                        <div className="flex flex-col items-center gap-2">
                                            <div className="cf-turnstile" data-sitekey={turnstile.siteKey} data-callback="onTurnstileCallback" />
                                            <InputError message={errors['cf-turnstile-response']} />
                                        </div>
                                    )}

                                    {/* Submit Button */}
                                    <Field>
                                        <Button type="submit" className="w-full" tabIndex={pinFieldEnabled ? 7 : 6} disabled={processing}>
                                            {processing && <LoaderCircle className="h-4 w-4 animate-spin" />}
                                            Create account
                                        </Button>
                                    </Field>

                                    {/* Google Auth Button */}
                                    {googleLoginEnabled && (
                                        <>
                                            <FieldSeparator>Or continue with</FieldSeparator>
                                            <Field>
                                                <Button
                                                    type="button"
                                                    variant="outline"
                                                    className="w-full"
                                                    tabIndex={pinFieldEnabled ? 8 : 7}
                                                    onClick={() => (window.location.href = route('auth.google'))}
                                                >
                                                    <GoogleIcon className="mr-2 h-4 w-4" />
                                                    Sign up with Google
                                                </Button>
                                            </Field>
                                        </>
                                    )}

                                    {/* Login Link */}
                                    <FieldDescription className="text-center">
                                        Already have an account?{' '}
                                        <TextLink href={route('login')} tabIndex={pinFieldEnabled ? 9 : 8}>
                                            Log in
                                        </TextLink>
                                    </FieldDescription>
                                </FieldGroup>
                            </form>
                        </div>
                    </div>
                </div>

                {/* Background - conditionally last */}
                {!backgroundSettings.onLeft && <BackgroundComponent loginBackgroundUrl={loginBackgroundUrl} />}
            </div>
        </>
    );
}
