import { FormEvent, useRef, useState } from "react"

import "../style/form.css"
import { Failure } from "../app/Failure.ts"
import { Link, useLocation, useNavigate } from "react-router-dom"
import { useAppFetcher } from "../App.tsx"
import { Authentication } from "../app/Fetcher.ts"

export interface RegisterPageProps {
    onSuccess: (auth: Authentication) => void
}

export default function RegisterPage({ onSuccess }: RegisterPageProps) {
    const usernameField = useRef<HTMLInputElement>(null)
    const passwordField = useRef<HTMLInputElement>(null)
    const confirmpasswordField = useRef<HTMLInputElement>(null)
    const emailField = useRef<HTMLInputElement>(null)

    const [errors, setErrors] = useState<Failure[]>([])
    const navigate = useNavigate()
    const location = useLocation()

    const fetcher = useAppFetcher()

    async function handleSubmit(e: FormEvent) {
        e.preventDefault()

        const username = usernameField.current!.value
        const password = passwordField.current!.value
        const confirmpassword = confirmpasswordField.current!.value
        const email = emailField.current!.value

        if (confirmpassword !== password) {
            setErrors([
                {
                    type: "password",
                    messages: [
                        "le mot de passe et la confirmation du mot de passe ne sont pas equivalent.",
                    ],
                },
            ])
            return
        }

        const response = await fetcher.fetchAPI("auth/register", {
            username,
            password,
            email,
        })

        if (response.ok) {
            const { token, expirationDate } = await response.json()
            const auth = { token, expirationDate: new Date(expirationDate) }
            navigate(location.state?.from || "/")

            onSuccess(auth)
            return
        }

        try {
            const failures = await response.json()
            setErrors(
                Object.entries<string[]>(failures).map(([type, messages]) => ({
                    type,
                    messages,
                })),
            )
        } catch (e) {
            setErrors([
                {
                    type: "internal error",
                    messages: ["an internal error occurred."],
                },
            ])
        }
    }

    return (
        <div className="container">
            <center>
                <h2>S'enregistrer</h2>
            </center>

            <div>
                {errors.map(({ type, messages }) =>
                    messages.map((message) => (
                        <p key={type} style={{ color: "red" }}>
                            {type} : {message}
                        </p>
                    )),
                )}
            </div>

            <form onSubmit={handleSubmit}>
                <div className="form-group">
                    <label htmlFor="username">Nom d'utilisateur :</label>
                    <input
                        ref={usernameField}
                        className="text-input"
                        type="text"
                        id="username"
                        name="username"
                        required
                    />

                    <label htmlFor="password">Mot de passe :</label>
                    <input
                        ref={passwordField}
                        className="password-input"
                        type="password"
                        id="password"
                        name="password"
                        required
                    />

                    <label htmlFor="confirmpassword">
                        Confirmer le mot de passe :
                    </label>
                    <input
                        ref={confirmpasswordField}
                        className="password-input"
                        type="password"
                        id="confirmpassword"
                        name="confirmpassword"
                        required
                    />

                    <label htmlFor="email">Email :</label>
                    <input
                        ref={emailField}
                        className="text-input"
                        type="text"
                        id="email"
                        name="email"
                        required
                    />

                    <label className="consentement">
                        <input type="checkbox" name="consentement" required />
                        En cochant cette case, j'accepte que mes données
                        personnelles, tel que mon adresse e-mail, soient
                        collectées et traitées conformément à la politique de
                        confidentialité de Sportify.
                    </label>

                    <Link to={"/login"} className="inscr">
                        Vous avez déjà un compte ?
                    </Link>
                </div>
                <div id="buttons">
                    <input
                        className="button"
                        type="submit"
                        value="Créer votre compte"
                    />
                </div>
            </form>
        </div>
    )
}
