'use client'

import { useEffect, useId, useState } from 'react'
import { createPortal } from 'react-dom'
import { useRouter } from 'next/navigation'
import { signIn } from 'next-auth/react'
import { AnimatePresence, motion } from 'framer-motion'
import LoginForm from '@/components/auth/LoginForm'
import RegisterForm from '@/components/auth/RegisterForm'

type AuthEntryModalProps = {
  open: boolean
  onClose: () => void
}

type ProviderMap = Record<string, { id: string; name: string }>

type Step = 'entry' | 'login' | 'register'

function FacebookGlyph({ className }: { className?: string }) {
  return (
    <svg className={className} viewBox="0 0 24 24" aria-hidden>
      <path
        fill="#1877F2"
        d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"
      />
    </svg>
  )
}

function AppleGlyph({ className }: { className?: string }) {
  return (
    <svg className={className} viewBox="0 0 24 24" fill="currentColor" aria-hidden>
      <path d="M17.05 19.965c-.96.954-2.063 2.903-3.466 2.956-1.324.058-1.668-.764-3.489-.764s-2.229.764-3.489.764c-1.436.054-2.53-1.437-3.49-2.388-2.396-2.34-4.21-6.615-1.756-9.502 1.225-1.436 2.945-2.34 4.655-2.388 1.437-.054 2.793 1.012 3.67 1.012.877 0 2.53-1.242 4.265-1.06.727.03 2.767.288 4.08 2.18-3.57 1.96-2.992 7.07.5 8.39zM14.02 3.78c.96-1.132 1.609-2.69 1.433-4.25-1.384.056-3.06.92-4.055 2.05-.889 1.03-1.667 2.69-1.457 4.28 1.54.12 3.12-.78 4.08-2.08z" />
    </svg>
  )
}

function GoogleGlyph({ className }: { className?: string }) {
  return (
    <svg className={className} viewBox="0 0 24 24" aria-hidden>
      <path
        fill="#4285F4"
        d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
      />
      <path
        fill="#34A853"
        d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
      />
      <path
        fill="#FBBC05"
        d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
      />
      <path
        fill="#EA4335"
        d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
      />
    </svg>
  )
}

function providerLabel(id: string, nameFallback: string): string {
  const idLower = id.toLowerCase()
  if (idLower.includes('facebook')) return 'Kontynuuj przez Facebook'
  if (idLower.includes('apple')) return 'Kontynuuj z Apple'
  if (idLower.includes('google')) return 'Kontynuuj przy użyciu konta Google'
  return `Kontynuuj przez ${nameFallback}`
}

function oauthIcon(id: string) {
  const k = id.toLowerCase()
  if (k.includes('facebook')) return <FacebookGlyph className="size-5 shrink-0" />
  if (k.includes('apple')) return <AppleGlyph className="size-5 shrink-0 text-gray-900" />
  if (k.includes('google')) return <GoogleGlyph className="size-5 shrink-0" />
  return null
}

const oauthOrder = ['facebook', 'apple', 'google'] as const

function sortOAuthIds(ids: string[]) {
  return [...ids].sort((a, b) => {
    const ia = oauthOrder.indexOf(a as (typeof oauthOrder)[number])
    const ib = oauthOrder.indexOf(b as (typeof oauthOrder)[number])
    const sa = ia === -1 ? oauthOrder.length : ia
    const sb = ib === -1 ? oauthOrder.length : ib
    return sa - sb
  })
}

function stepTitle(step: Step): string {
  if (step === 'login') return 'Logowanie'
  if (step === 'register') return 'Załóż konto'
  return 'Zacznij korzystać'
}

function stepSubtitle(step: Step): string | null {
  if (step === 'entry')
    return 'Utwórz konto lub zaloguj się, aby dodawać ogłoszenia na giełdzie i wygodnie korzystać z konta.'
  if (step === 'login')
    return 'Podaj hasło do konta lub wróć, by zmienić adres e‑mail lub skorzystać z innej metody logowania.'
  return 'Wypełnij formularz, aby założyć konto.'
}

export default function AuthEntryModal({ open, onClose }: AuthEntryModalProps) {
  const titleId = useId()
  const emailId = useId()
  const router = useRouter()

  const [mounted, setMounted] = useState(false)
  const [step, setStep] = useState<Step>('entry')
  const [email, setEmail] = useState('')
  /** Aktualny e-mail przy przełączaniu logowanie ↔ rejestracja */
  const [flowEmail, setFlowEmail] = useState('')
  const [busy, setBusy] = useState(false)
  const [oauthBusy, setOauthBusy] = useState<string | null>(null)
  const [formError, setFormError] = useState<string | null>(null)
  const [providers, setProviders] = useState<ProviderMap | null>(null)
  const [registeredNotice, setRegisteredNotice] = useState(false)

  /** Szary przycisk pusty; kolor jak po „Dalej” dopiero przy niepustym adresie po trim. */
  const emailTouched = email.trim().length >= 1
  const dalejEnabled = emailTouched && !busy

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

  useEffect(() => {
    if (!open) return
    setFormError(null)
    let cancelled = false
    ;(async () => {
      try {
        const r = await fetch('/api/auth/providers')
        const data = (await r.json()) as ProviderMap
        if (!cancelled && typeof data === 'object' && data !== null) {
          setProviders(data)
          return
        }
        if (!cancelled) setProviders({})
      } catch {
        if (!cancelled) setProviders({})
      }
    })()
    return () => {
      cancelled = true
    }
  }, [open])

  useEffect(() => {
    if (!open) {
      setStep('entry')
      setEmail('')
      setFlowEmail('')
      setFormError(null)
      setRegisteredNotice(false)
    }
  }, [open])

  useEffect(() => {
    if (!open) return
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose()
    }
    window.addEventListener('keydown', onKey)
    const prev = document.body.style.overflow
    document.body.style.overflow = 'hidden'
    return () => {
      window.removeEventListener('keydown', onKey)
      document.body.style.overflow = prev
    }
  }, [open, onClose])

  function goBackToEntry() {
    setStep('entry')
    setFormError(null)
    setRegisteredNotice(false)
  }

  async function onEmailNext(e: React.FormEvent) {
    e.preventDefault()
    setFormError(null)
    const trimmed = email.trim()
    if (!trimmed) {
      setFormError('Podaj adres e-mail.')
      return
    }
    setBusy(true)
    try {
      const res = await fetch('/api/auth/email-status', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email: trimmed }),
      })
      const data = (await res.json()) as { registered?: boolean; error?: string }
      if (!res.ok) {
        setFormError(data.error ?? 'Nie udało się sprawdzić adresu.')
        return
      }
      setFlowEmail(trimmed)
      setRegisteredNotice(false)
      if (data.registered) setStep('login')
      else setStep('register')
    } catch {
      setFormError('Błąd połączenia. Spróbuj ponownie.')
    } finally {
      setBusy(false)
    }
  }

  async function onOAuthClick(providerId: string) {
    setFormError(null)
    setOauthBusy(providerId)
    try {
      await signIn(providerId, { callbackUrl: '/' })
    } catch {
      setFormError('Logowanie nie powiodło się. Sprawdź konfigurację dostawcy (np. AUTH_GOOGLE_ID).')
    } finally {
      setOauthBusy(null)
    }
  }

  const oauthIds = providers
    ? sortOAuthIds(
        Object.keys(providers).filter((id) => id !== 'credentials'),
      )
    : []

  if (!mounted || typeof document === 'undefined') return null

  return createPortal(
    <AnimatePresence>
      {open ? (
        <motion.div
          key="auth-overlay"
          className="fixed inset-0 z-[200] flex items-center justify-center p-4 sm:p-6"
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          transition={{ duration: 0.2 }}
        >
          <motion.div
            className="absolute inset-0 bg-black/50 backdrop-blur-[1px]"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            onClick={onClose}
            aria-hidden
          />
          <motion.div
            key="auth-panel"
            role="dialog"
            aria-modal="true"
            aria-labelledby={titleId}
            id="auth-entry-dialog"
            className="relative z-[1] max-h-[min(92vh,720px)] w-full max-w-[23rem] overflow-y-auto overscroll-contain rounded-2xl bg-white p-6 shadow-2xl sm:p-8"
            initial={{ opacity: 0, scale: 0.96, y: 12 }}
            animate={{ opacity: 1, scale: 1, y: 0 }}
            exit={{ opacity: 0, scale: 0.98, y: 8 }}
            transition={{ type: 'spring', damping: 28, stiffness: 320 }}
            onClick={(e) => e.stopPropagation()}
          >
            <button
              type="button"
              onClick={onClose}
              className="absolute right-3 top-3 rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-900 focus-visible:outline focus-visible:ring-2 focus-visible:ring-[color:var(--logo-color-dark)] focus-visible:ring-offset-2 sm:right-4 sm:top-4"
              aria-label="Zamknij"
            >
              <svg className="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden>
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
              </svg>
            </button>

            {step !== 'entry' ? (
              <button
                type="button"
                onClick={goBackToEntry}
                className="mb-3 text-left text-sm font-medium text-[color:var(--logo-color-dark)] underline decoration-from-font underline-offset-2 hover:no-underline"
              >
                ← Wróć
              </button>
            ) : null}

            <h2 id={titleId} className="pr-10 text-2xl font-bold tracking-tight text-gray-900">
              {stepTitle(step)}
            </h2>
            <p className="mt-2 text-sm leading-relaxed text-gray-600">{stepSubtitle(step)}</p>

            {step === 'entry' ? (
              <>
                <form onSubmit={onEmailNext} className="mt-8 space-y-2">
                  {formError ? (
                    <p className="rounded-lg bg-red-50 px-3 py-2 text-sm text-red-800" role="alert">
                      {formError}
                    </p>
                  ) : null}
                  <div className="relative mt-2">
                    <input
                      id={emailId}
                      type="email"
                      inputMode="email"
                      autoComplete="email"
                      value={email}
                      onChange={(ev) => setEmail(ev.target.value)}
                      placeholder=" "
                      disabled={busy}
                      className="peer block w-full appearance-none rounded-lg border border-gray-300 bg-white px-3 pb-2.5 pt-5 text-sm text-gray-900 focus:border-[color:var(--logo-color-dark)] focus:outline-none focus:ring-1 focus:ring-[color:var(--logo-color-dark)] disabled:opacity-60"
                    />
                    <label
                      htmlFor={emailId}
                      className="pointer-events-none absolute left-3 top-2 z-10 origin-[0] -translate-y-1 scale-75 transform bg-white px-1 text-xs text-[color:var(--logo-color-dark)] duration-150 peer-placeholder-shown:top-4 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:scale-100 peer-placeholder-shown:text-gray-500 peer-focus:top-2 peer-focus:-translate-y-1 peer-focus:scale-75 peer-focus:text-[color:var(--logo-color-dark)]"
                    >
                      E-mail
                    </label>
                  </div>

                  <button
                    type="submit"
                    disabled={!dalejEnabled}
                    className={`mt-4 flex w-full items-center justify-center rounded-xl px-4 py-3.5 text-sm font-semibold shadow transition focus-visible:outline focus-visible:ring-2 focus-visible:ring-[color:var(--logo-color-dark)] focus-visible:ring-offset-2 ${
                      emailTouched
                        ? 'bg-[color:var(--logo-color-dark)] text-white hover:opacity-95 disabled:opacity-60'
                        : 'cursor-not-allowed bg-gray-200 text-gray-500'
                    }`}
                  >
                    {busy ? 'Chwileczkę…' : 'Dalej'}
                  </button>
                </form>

                <div className="relative my-7" aria-hidden>
                  <div className="absolute inset-0 flex items-center">
                    <div className="w-full border-t border-gray-200" />
                  </div>
                  <div className="relative flex justify-center text-xs font-semibold uppercase tracking-wide text-gray-500">
                    <span className="bg-white px-3">lub</span>
                  </div>
                </div>

                <div className="flex flex-col gap-2.5">
                  {oauthIds.length === 0 && providers !== null ? (
                    <p className="text-center text-xs text-gray-500">
                      Logowanie społecznościowe będzie dostępne po skonfigurowaniu zmiennych{' '}
                      <code className="rounded bg-gray-100 px-1">AUTH_GOOGLE_ID</code> /{' '}
                      <code className="rounded bg-gray-100 px-1">AUTH_FACEBOOK_ID</code> /{' '}
                      <code className="rounded bg-gray-100 px-1">AUTH_APPLE_ID</code> na serwerze.
                    </p>
                  ) : null}
                  {oauthIds.map((id) => {
                    const def = providers?.[id]
                    if (!def) return null
                    const loading = oauthBusy === id
                    return (
                      <button
                        key={id}
                        type="button"
                        disabled={loading || oauthBusy !== null}
                        onClick={() => onOAuthClick(id)}
                        className="flex w-full items-center justify-center gap-2.5 rounded-xl border border-gray-200 bg-white px-4 py-3 text-sm font-medium text-gray-900 shadow-sm transition hover:border-gray-300 hover:bg-gray-50 disabled:opacity-60 focus-visible:outline focus-visible:ring-2 focus-visible:ring-[color:var(--logo-color-dark)] focus-visible:ring-offset-2"
                      >
                        {oauthIcon(def.id)}
                        {loading ? 'Przekierowanie…' : providerLabel(def.id, def.name)}
                      </button>
                    )
                  })}
                </div>

                <p className="mt-8 border-t border-gray-100 pt-6 text-center text-sm text-gray-600">
                  <button
                    type="button"
                    onClick={() => {
                      setFlowEmail(email.trim())
                      setRegisteredNotice(false)
                      setStep('login')
                    }}
                    className="font-medium text-[color:var(--logo-color-dark)] underline decoration-from-font underline-offset-2 hover:no-underline"
                  >
                    Zaloguj przy użyciu e-mail i hasła
                  </button>
                </p>
              </>
            ) : null}

            {step === 'login' ? (
              <div className="mt-6">
                <LoginForm
                  variant="embedded"
                  initialEmail={flowEmail}
                  registeredNotice={registeredNotice}
                  onEmailDraftChange={setFlowEmail}
                  onAuthenticated={() => {
                    router.push('/profil')
                    router.refresh()
                    onClose()
                  }}
                  switchToRegister={() => {
                    setRegisteredNotice(false)
                    setStep('register')
                  }}
                />
              </div>
            ) : null}

            {step === 'register' ? (
              <div className="mt-6">
                <RegisterForm
                  variant="embedded"
                  initialEmail={flowEmail}
                  onEmailDraftChange={setFlowEmail}
                  onRegistrationSuccess={() => {
                    setRegisteredNotice(true)
                    setStep('login')
                  }}
                  switchToLogin={() => {
                    setRegisteredNotice(false)
                    setStep('login')
                  }}
                />
              </div>
            ) : null}
          </motion.div>
        </motion.div>
      ) : null}
    </AnimatePresence>,
    document.body,
  )
}
