'use client'

import { ReactNode, useState, useEffect } from 'react'
import { AuthDetails, AuthError, AuthResponse, getAuthDetails } from '../api'
import { useAuthContext } from '../contexts/AuthContext'
import { useStyles } from '../contexts/StylesContext'

interface AuthForm {
    submit: () => void
    authDetails: AuthDetails
    fetching: boolean
    response: AuthResponse | null
    errors: AuthError[]
}

export default function useAuthForm(
    submissionAction: () => Promise<AuthResponse>,
    responseAction?: (response: AuthResponse, authDetails: AuthDetails) => void,
): AuthForm {
    const auth = useAuthContext().auth
    const [fetching, setFetching] = useState<boolean>(false)
    const [response, setResponse] = useState<AuthResponse | null>(null)
    const [errors, setErrors] = useState<AuthError[]>([])
    const [authDetails, setAuthDetails] = useState<AuthDetails>(getAuthDetails(auth))

    function submit() {
        setFetching(true)
        submissionAction()
            .then((r) => {
                setResponse(r)
                setErrors(r.errors || [])
                setFetching(false)
                if (r && responseAction) {
                    responseAction(r, authDetails)
                }
                setAuthDetails(getAuthDetails(auth))
            })
            .catch((e) => {
                console.error(e)
                setFetching(false)
            })
    }

    return { submit, authDetails, fetching, response, errors }
}

interface AuthFieldProps {
    title: string
    name: string
    type: string
    init: string
    onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
    authErrors: AuthError[]
    placeholder?: string
    children?: ReactNode
}

export function AuthField({
    title,
    name,
    type,
    init,
    onChange,
    authErrors,
    placeholder,
    children,
}: AuthFieldProps) {
    const styles = useStyles()
    const [mounted, setMounted] = useState(false)
    const fieldErrors = authErrors.filter(err => err.param === name)

    useEffect(() => {
        setMounted(true)
    }, [])

    return (
        <div className={styles.field}>
            <label className={styles.fieldLabel}>{title}</label>
            {mounted ? (
                <input
                    type={type}
                    value={init}
                    onChange={onChange}
                    placeholder={placeholder}
                    className={styles.fieldInput}
                    autoComplete="off"
                />
            ) : (
                <div className={styles.fieldInput} style={{ minHeight: '2.75rem' }} />
            )}
            {fieldErrors.map((err, i) => (
                <p key={i} className={styles.fieldError}>{err.message}</p>
            ))}
            {children}
        </div>
    )
}


