import { useEffect, useRef, useState, type ReactNode, type FormEvent } from 'react'
import { Button } from '../../primitives/Button/Button'
import { Input } from '../../primitives/Input/Input'
import { Checkbox } from '../../primitives/Checkbox/Checkbox'
import { FormField } from '../../primitives/FormField/FormField'
import { Alert } from '../../primitives/Alert/Alert'
import styles from './LoginForm.module.css'

export interface SocialProvider {
  label: string
  icon?: ReactNode
  onClick: () => void
}

export interface LoginFormProps {
  logo?: ReactNode
  title?: string
  socialProviders?: SocialProvider[]
  onSubmit?: (credentials: { email: string; password: string; remember: boolean }) => void
  onForgotPassword?: () => void
  onSignUp?: () => void
  error?: string
  loading?: boolean
  className?: string
}

interface FieldErrors {
  email?: string
  password?: string
}

const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/

function validate(email: string, password: string): FieldErrors {
  const errors: FieldErrors = {}
  if (!email) {
    errors.email = 'Email is required'
  } else if (!EMAIL_REGEX.test(email)) {
    errors.email = 'Please enter a valid email address'
  }
  if (!password) {
    errors.password = 'Password is required'
  } else if (password.length < 8) {
    errors.password = 'Password must be at least 8 characters'
  }
  return errors
}

export function LoginForm({
  logo,
  title = 'Sign in',
  socialProviders,
  onSubmit,
  onForgotPassword,
  onSignUp,
  error,
  loading = false,
  className,
}: LoginFormProps) {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [remember, setRemember] = useState(false)
  const [fieldErrors, setFieldErrors] = useState<FieldErrors>({})
  const [submitted, setSubmitted] = useState(false)
  const emailRef = useRef<HTMLInputElement>(null)

  // Auto-focus first input on mount
  useEffect(() => {
    emailRef.current?.focus()
  }, [])

  // Reset submitted flag when error prop changes (new server error from re-attempt)
  useEffect(() => {
    if (error) setSubmitted(false)
  }, [error])

  // Server error is shown from prop, hidden after next submit attempt
  const showServerError = error && !submitted

  const hasSocial = socialProviders && socialProviders.length > 0
  const hasCredentials = !!onSubmit
  const showDivider = hasSocial && hasCredentials

  function handleSubmit(e: FormEvent) {
    e.preventDefault()
    setSubmitted(true)
    const errors = validate(email, password)
    setFieldErrors(errors)
    if (Object.keys(errors).length === 0) {
      onSubmit?.({ email, password, remember })
    }
  }

  return (
    <div className={`${styles.loginForm} ${className ?? ''}`}>
      {logo && <div className={styles.logo}>{logo}</div>}
      <h2 className={styles.title}>{title}</h2>

      {showServerError && (
        <div className={styles.error}>
          <Alert variant="error">{error}</Alert>
        </div>
      )}

      {hasSocial && (
        <div className={styles.socialSection}>
          {socialProviders.map((provider) => (
            <Button
              key={provider.label}
              variant="secondary"
              className={styles.socialButton}
              onClick={provider.onClick}
              disabled={loading}
              type="button"
            >
              {provider.icon}
              {provider.label}
            </Button>
          ))}
        </div>
      )}

      {showDivider && (
        <div className={styles.divider}>
          <div className={styles.dividerLine} />
          <span className={styles.dividerText}>or</span>
          <div className={styles.dividerLine} />
        </div>
      )}

      {hasCredentials && (
        <form
          className={styles.fields}
          onSubmit={handleSubmit}
          aria-label="Sign in"
          noValidate
        >
          <FormField label="Email" htmlFor="login-email" required error={fieldErrors.email}>
            <Input
              ref={emailRef}
              id="login-email"
              type="email"
              placeholder="you@example.com"
              value={email}
              onChange={(e) => {
                setEmail(e.target.value)
                if (fieldErrors.email) setFieldErrors((prev) => ({ ...prev, email: undefined }))
              }}
              disabled={loading}
            />
          </FormField>

          <FormField label="Password" htmlFor="login-password" required error={fieldErrors.password}>
            <Input
              id="login-password"
              type="password"
              placeholder="••••••••"
              value={password}
              onChange={(e) => {
                setPassword(e.target.value)
                if (fieldErrors.password) setFieldErrors((prev) => ({ ...prev, password: undefined }))
              }}
              disabled={loading}
            />
          </FormField>

          <div className={styles.rememberRow}>
            <Checkbox
              label="Remember me"
              checked={remember}
              onChange={(e) => setRemember(e.target.checked)}
              disabled={loading}
            />
            {onForgotPassword && (
              <button
                type="button"
                className={styles.forgotLink}
                onClick={onForgotPassword}
              >
                Forgot password?
              </button>
            )}
          </div>

          <Button
            variant="primary"
            type="submit"
            loading={loading}
            className={styles.submitButton}
          >
            Sign in
          </Button>

          {onSignUp && (
            <div className={styles.signUpText}>
              Don&apos;t have an account?{' '}
              <button
                type="button"
                className={styles.signUpLink}
                onClick={onSignUp}
              >
                Sign up
              </button>
            </div>
          )}
        </form>
      )}

      {!hasCredentials && onSignUp && (
        <div className={styles.signUpText}>
          Don&apos;t have an account?{' '}
          <button
            type="button"
            className={styles.signUpLink}
            onClick={onSignUp}
          >
            Sign up
          </button>
        </div>
      )}
    </div>
  )
}
