'use client'

import { useState, ReactNode } from 'react'
import { useAllauthAPI } from '../contexts/APIContext'
import { useStyles } from '../contexts/StylesContext'
import useAuthForm, { AuthField } from './AuthForm'
import { AuthResponse, AuthDetails } from '../api'

interface FieldConfig {
    name: string
    title: string
    type: string
    placeholder?: string
}

interface FooterLink {
    href: string
    label: string
}

interface AuthFormPageProps {
    title: string
    subtitle?: string
    fields: FieldConfig[]
    submitLabel?: string
    submittingLabel?: string
    submitFn: (api: ReturnType<typeof useAllauthAPI>, data: Record<string, string>) => Promise<AuthResponse>
    onResponse: (response: AuthResponse, authDetails: AuthDetails, data: Record<string, string>) => void
    footerLinks?: FooterLink[]
    preFields?: ReactNode
    postFields?: ReactNode
    error?: string | null
}

export function AuthFormPage({
    title,
    subtitle,
    fields,
    submitLabel = 'Submit',
    submittingLabel = 'Submitting...',
    submitFn,
    onResponse,
    footerLinks,
    preFields,
    postFields,
    error: externalError,
}: AuthFormPageProps) {
    const api = useAllauthAPI()
    const styles = useStyles()

    const [data, setData] = useState<Record<string, string>>(() =>
        Object.fromEntries(fields.map(f => [f.name, '']))
    )

    const authForm = useAuthForm(
        () => submitFn(api, data),
        (response, authDetails) => onResponse(response, authDetails, data)
    )

    const handleSubmit = (e: React.FormEvent) => {
        e.preventDefault()
        authForm.submit()
    }

    const handleFieldChange = (fieldName: string) => (e: React.ChangeEvent<HTMLInputElement>) => {
        setData(prev => ({ ...prev, [fieldName]: e.target.value }))
    }

    const formErrors = authForm.errors.filter(err => !err.param || err.param === '__all__')

    return (
        <div className={styles.container}>
            <div className={styles.card}>
                <h1 className={styles.title}>{title}</h1>
                {subtitle && <p className={styles.subtitle}>{subtitle}</p>}

                {externalError && <p className={styles.error}>{externalError}</p>}
                {formErrors.length > 0 && (
                    <div className={styles.error}>
                        {formErrors.map((err, i) => (
                            <p key={i}>{err.message}</p>
                        ))}
                    </div>
                )}

                <form onSubmit={handleSubmit} className={styles.form} suppressHydrationWarning>
                    {preFields}

                    <div className={styles.fieldsContainer}>
                        {fields.map(field => (
                            <AuthField
                                key={field.name}
                                title={field.title}
                                name={field.name}
                                type={field.type}
                                init={data[field.name]}
                                onChange={handleFieldChange(field.name)}
                                authErrors={authForm.errors}
                                placeholder={field.placeholder}
                            />
                        ))}
                    </div>

                    {postFields}

                    <button
                        type="submit"
                        className={styles.submit}
                        disabled={authForm.fetching}
                    >
                        {authForm.fetching ? submittingLabel : submitLabel}
                    </button>
                </form>

                {footerLinks && footerLinks.length > 0 && (
                    <div className={styles.footer}>
                        {footerLinks.map((link, i) => (
                            <a key={i} href={link.href} className={styles.link}>
                                {link.label}
                            </a>
                        ))}
                    </div>
                )}
            </div>
        </div>
    )
}
