'use client';

import React, {ChangeEvent, SubmitEvent, useState} from 'react';
import Link from 'next/link';
import {useRouter} from 'next/navigation';
import {
    Box,
    Button,
    InputAdornment,
    Paper,
    Stack,
    TextField,
    Typography,
    Alert,
} from '@mui/material';
import {authClient} from '@/lib/api/auth';
import {ApiError, ApiValidationErrors} from '@/lib/api/client';
import {GuestGuard} from "@/src/auth/GuestGuard";

type FormValues = {
    username: string;
    firstName: string;
    lastName: string;
    email: string;
    phone: string;
    password: string;
    confirmPassword: string;
};

type FormErrors = Partial<Record<keyof FormValues, string>>;

const initialValues: FormValues = {
    username: '',
    firstName: '',
    lastName: '',
    email: '',
    phone: '',
    password: '',
    confirmPassword: '',
};

const validationFieldMap: Partial<Record<string, keyof FormValues>> = {
    username: 'username',
    first_name: 'firstName',
    last_name: 'lastName',
    email: 'email',
    phone: 'phone',
    password: 'password',
    password_confirmation: 'confirmPassword',
};

const mapValidationErrors = (errors?: ApiValidationErrors): FormErrors => {
    if (!errors) {
        return {};
    }

    return Object.entries(errors).reduce<FormErrors>((accumulator, [key, messages]) => {
        const field = validationFieldMap[key];

        if (field && messages.length > 0) {
            accumulator[field] = messages[0];
        }

        return accumulator;
    }, {});
};

const Page: React.FC = () => {
    const router = useRouter();
    const [values, setValues] = useState<FormValues>(initialValues);
    const [errors, setErrors] = useState<FormErrors>({});
    const [isSubmitting, setIsSubmitting] = useState(false);
    const [serverError, setServerError] = useState('');

    const handleChange =
        (field: keyof FormValues) => (event: ChangeEvent<HTMLInputElement>) => {
            const nextValue =
                field === 'phone'
                    ? event.target.value.replace(/\D/g, '').slice(0, 10)
                    : event.target.value;

            setValues((current) => ({
                ...current,
                [field]: nextValue,
            }));

            setErrors((current) => {
                if (!current[field]) {
                    return current;
                }

                const nextErrors = {...current};
                delete nextErrors[field];
                return nextErrors;
            });
        };

    const validateForm = () => {
        const nextErrors: FormErrors = {};

        if (!values.username.trim()) {
            nextErrors.username = 'El nombre de usuario es obligatorio.';
        }

        if (!values.firstName.trim()) {
            nextErrors.firstName = 'El nombre es obligatorio.';
        }

        if (!values.lastName.trim()) {
            nextErrors.lastName = 'El apellido es obligatorio.';
        }

        if (!values.email.trim()) {
            nextErrors.email = 'El correo electrónico es obligatorio.';
        } else if (!/\S+@\S+\.\S+/.test(values.email)) {
            nextErrors.email = 'Ingresa un correo electrónico válido.';
        }

        if (!values.phone.trim()) {
            nextErrors.phone = 'El número celular es obligatorio.';
        } else if (!/^\d{10}$/.test(values.phone)) {
            nextErrors.phone = 'Ingresa 10 dígitos numéricos.';
        }

        if (!values.password) {
            nextErrors.password = 'La contraseña es obligatoria.';
        } else if (values.password.length < 8) {
            nextErrors.password = 'La contraseña debe tener al menos 8 caracteres.';
        }

        if (!values.confirmPassword) {
            nextErrors.confirmPassword = 'Confirma tu contraseña.';
        } else if (values.password !== values.confirmPassword) {
            nextErrors.confirmPassword = 'Las contraseñas no coinciden.';
        }

        setErrors(nextErrors);
        return Object.keys(nextErrors).length === 0;
    };

    const handleSubmit = (event: SubmitEvent<HTMLFormElement>) => {
        event.preventDefault();
        setServerError('');

        if (!validateForm()) {
            return;
        }

        setIsSubmitting(true);

        authClient
            .register({
                username: values.username.trim(),
                first_name: values.firstName.trim(),
                last_name: values.lastName.trim(),
                email: values.email.trim(),
                phone: values.phone.trim(),
                password: values.password,
                password_confirmation: values.confirmPassword,
            })
            .then(() => router.push('/'))
            .catch((error: unknown) => {
                if (error instanceof ApiError) {
                    setErrors((current) => ({
                        ...current,
                        ...mapValidationErrors(error.errors),
                    }));
                    setServerError(error.message);
                    return;
                }

                setServerError('No fue posible crear la cuenta.');
            })
            .finally(() => {
                setIsSubmitting(false);
            });
    };

    return (
        <GuestGuard>
            <Box
                sx={{
                    minHeight: '100vh',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    bgcolor: 'grey.100',
                    p: 3,
                }}
            >
                <Paper
                    elevation={4}
                    sx={{
                        width: '100%',
                        maxWidth: 520,
                        borderRadius: 4,
                        px: {xs: 3, sm: 4},
                        py: 4,
                    }}
                >
                    <Typography variant="h4" fontWeight={700} gutterBottom>
                        Crea tu cuenta
                    </Typography>

                    <Typography variant="body1" color="text.secondary" sx={{mb: 3}}>
                        Llena todos los campos para crear tu cuenta
                    </Typography>

                    <Box component="form" noValidate onSubmit={handleSubmit}>
                        <Stack spacing={2}>
                            {serverError ? <Alert severity="error">{serverError}</Alert> : null}

                            <TextField
                                label="Apodo"
                                name="username"
                                value={values.username}
                                onChange={handleChange('username')}
                                error={Boolean(errors.username)}
                                helperText={errors.username}
                                required
                                fullWidth
                            />

                            <Stack direction={{xs: 'column', sm: 'row'}} spacing={2}>
                                <TextField
                                    label="Nombre(s)"
                                    name="firstName"
                                    value={values.firstName}
                                    onChange={handleChange('firstName')}
                                    error={Boolean(errors.firstName)}
                                    helperText={errors.firstName}
                                    required
                                    fullWidth
                                />

                                <TextField
                                    label="Apellido(s)"
                                    name="lastName"
                                    value={values.lastName}
                                    onChange={handleChange('lastName')}
                                    error={Boolean(errors.lastName)}
                                    helperText={errors.lastName}
                                    required
                                    fullWidth
                                />
                            </Stack>

                            <TextField
                                label="Correo electrónico"
                                name="email"
                                type="email"
                                autoComplete="email"
                                value={values.email}
                                onChange={handleChange('email')}
                                error={Boolean(errors.email)}
                                helperText={errors.email}
                                required
                                fullWidth
                            />

                            <TextField
                                label="Número celular"
                                name="phone"
                                type="tel"
                                autoComplete="tel-national"
                                value={values.phone}
                                onChange={handleChange('phone')}
                                error={Boolean(errors.phone)}
                                helperText={errors.phone ?? 'Captura 10 dígitos.'}
                                required
                                fullWidth
                                slotProps={{
                                    htmlInput: {
                                        inputMode: 'numeric',
                                        pattern: '[0-9]*',
                                        maxLength: 10,
                                    },
                                    input: {
                                        startAdornment: (
                                            <InputAdornment position="start">+52</InputAdornment>
                                        ),
                                    },
                                }}
                            />

                            <TextField
                                label="Contraseña"
                                name="password"
                                type="password"
                                autoComplete="new-password"
                                value={values.password}
                                onChange={handleChange('password')}
                                error={Boolean(errors.password)}
                                helperText={errors.password}
                                required
                                fullWidth
                            />

                            <TextField
                                label="Confirmar contraseña"
                                name="confirmPassword"
                                type="password"
                                autoComplete="new-password"
                                value={values.confirmPassword}
                                onChange={handleChange('confirmPassword')}
                                error={Boolean(errors.confirmPassword)}
                                helperText={errors.confirmPassword}
                                required
                                fullWidth
                            />

                            <Button
                                type="submit"
                                variant="contained"
                                size="large"
                                fullWidth
                                disabled={isSubmitting}
                                sx={{
                                    mt: 1,
                                    py: 1.5,
                                    borderRadius: 2.5,
                                    textTransform: 'none',
                                    fontSize: 16,
                                    fontWeight: 700,
                                }}
                            >
                                {isSubmitting ? 'Creando cuenta...' : 'Registrarme'}
                            </Button>

                            <Typography variant="body2" color="text.secondary" textAlign="center">
                                ¿Ya tienes cuenta?{' '}
                                <Box
                                    component={Link}
                                    href="/login"
                                    sx={{
                                        color: 'primary.main',
                                        textDecoration: 'none',
                                        fontWeight: 600,
                                    }}
                                >
                                    Inicia sesión
                                </Box>
                            </Typography>
                        </Stack>
                    </Box>
                </Paper>
            </Box>
        </GuestGuard>
    );
};

export default Page;
