import { Head } from '@inertiajs/react'
import { CircleAlert, UserRoundCheck } from 'lucide-react'
import type { FormEvent } from 'react'
import { useState } from 'react'

import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { t } from '@/lib/i18n'
import { formatAbsolute } from '@/lib/format'
import { route } from '@/lib/routes'

interface Props {
  valid: boolean
  email: string
  token: string
  expires_at: string | null
}

export default function AcceptInvitation({ valid, email, token, expires_at }: Props) {
  const [password, setPassword] = useState('')
  const [confirmation, setConfirmation] = useState('')
  const [error, setError] = useState('')
  const [submitting, setSubmitting] = useState(false)

  const submit = async (event: FormEvent) => {
    event.preventDefault()
    setError('')
    setSubmitting(true)
    try {
      const response = await fetch(route('invitation.accept', { token }), {
        method: 'POST',
        credentials: 'same-origin',
        headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrfToken() },
        body: JSON.stringify({ password, password_confirmation: confirmation }),
      })
      const body = await response.json()
      if (!response.ok) {
        setError(t(`invitation.error.${body.error?.code ?? 'UNKNOWN'}` as Parameters<typeof t>[0]))
        return
      }
      window.location.assign(body.redirect)
    } catch {
      setError(t('invitation.error.NETWORK'))
    } finally {
      setSubmitting(false)
    }
  }

  return (
    <div className="bg-background text-foreground flex min-h-screen items-center justify-center px-4">
      <Head title={t('invitation.title')} />
      <main className="flex w-full max-w-sm flex-col gap-6">
        <div className="flex flex-col items-center gap-2 text-center">
          <span className="bg-muted flex size-11 items-center justify-center rounded-xl"><UserRoundCheck aria-hidden /></span>
          <h1 className="text-2xl font-semibold tracking-tight">{t('invitation.title')}</h1>
          <p className="text-muted-foreground text-sm text-pretty">{t('invitation.description')}</p>
        </div>
        {!valid ? (
          <Alert variant="critical">
            <CircleAlert />
            <AlertTitle>{t('invitation.invalid.title')}</AlertTitle>
            <AlertDescription>{t('invitation.invalid.description')}</AlertDescription>
          </Alert>
        ) : (
          <form onSubmit={submit} className="flex flex-col gap-4">
            {expires_at ? <p className="text-muted-foreground text-center text-sm">{t('invitation.expiresAt', { expires: formatAbsolute(expires_at, 'America/New_York') })}</p> : null}
            <div className="grid gap-2">
              <label htmlFor="invited-email" className="text-sm font-medium">{t('login.email')}</label>
              <Input id="invited-email" value={email} disabled />
            </div>
            <div className="grid gap-2">
              <label htmlFor="new-password" className="text-sm font-medium">{t('invitation.password')}</label>
              <Input id="new-password" type="password" autoComplete="new-password" value={password} onChange={(event) => setPassword(event.target.value)} required />
              <p className="text-muted-foreground text-xs">{t('invitation.password.help')}</p>
            </div>
            <div className="grid gap-2">
              <label htmlFor="confirm-password" className="text-sm font-medium">{t('invitation.password.confirm')}</label>
              <Input id="confirm-password" type="password" autoComplete="new-password" value={confirmation} onChange={(event) => setConfirmation(event.target.value)} required />
            </div>
            {error ? <p role="alert" className="text-destructive text-sm">{error}</p> : null}
            <Button type="submit" disabled={submitting}>{submitting ? t('invitation.submitting') : t('invitation.submit')}</Button>
          </form>
        )}
      </main>
    </div>
  )
}

function csrfToken(): string {
  const entry = document.cookie.split('; ').find((chunk) => chunk.startsWith('csrftoken='))
  return entry ? decodeURIComponent(entry.slice('csrftoken='.length)) : ''
}
