// Sign in / sign up — URL `/login`. A REAL auth form: it POSTs to the api's
// `/auth/*` routes (contributed by @voltro/plugin-auth on api-cms), which set
// the HttpOnly session cookie. State-changing auth routes are CSRF-protected, so
// we fetch a token first. On success we do a FULL navigation so the editor's SSR
// gate re-runs with the freshly-set cookie.
import type { ReactNode } from 'react'
import { useState, type FormEvent } from 'react'
import type { PageMeta } from '@voltro/web'
import { T, useT } from '@voltro/i18n'
import { getCatalog } from '../../locales'

export const renderMode = 'static' as const

export const meta = ({ locale }: { readonly locale: string }): PageMeta => ({
  title: getCatalog(locale)['meta.login.title'],
})

type Mode = 'signIn' | 'signUp'

async function submitAuth(mode: Mode, email: string, password: string): Promise<boolean> {
  const csrf = (await fetch('/auth/csrf').then((r) => r.json())) as { csrfToken: string }
  const path = mode === 'signUp' ? '/auth/sign-up' : '/auth/sign-in'
  const res = await fetch(path, {
    method: 'POST',
    headers: { 'content-type': 'application/json', 'x-csrf-token': csrf.csrfToken },
    body: JSON.stringify({ email, password }),
  })
  return res.ok
}

export default function Login(): ReactNode {
  const [mode, setMode] = useState<Mode>('signIn')
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [pending, setPending] = useState(false)
  const [failed, setFailed] = useState(false)
  const emailLabel = useT('auth.email')
  const passwordLabel = useT('auth.password')

  const onSubmit = (e: FormEvent): void => {
    e.preventDefault()
    setPending(true)
    setFailed(false)
    void submitAuth(mode, email, password)
      .then((ok) => {
        if (ok) {
          const from = new URLSearchParams(window.location.search).get('from') ?? '/'
          window.location.assign(from)
        } else {
          setFailed(true)
          setPending(false)
        }
      })
      .catch(() => {
        setFailed(true)
        setPending(false)
      })
  }

  return (
    <section className="hero">
      <h1><T id={mode === 'signUp' ? 'auth.signUp.heading' : 'auth.signIn.heading'} /></h1>
      <form className="auth-form" onSubmit={onSubmit}>
        <label>
          <span><T id="auth.email" /></span>
          <input
            type="email" required aria-label={emailLabel} value={email}
            onChange={(e) => setEmail(e.target.value)}
          />
        </label>
        <label>
          <span><T id="auth.password" /></span>
          <input
            type="password" required aria-label={passwordLabel} value={password}
            onChange={(e) => setPassword(e.target.value)}
          />
        </label>
        {failed ? <p className="error-text"><T id="auth.error" /></p> : null}
        <button type="submit" className="btn" disabled={pending}>
          <T id={pending ? 'auth.pending' : mode === 'signUp' ? 'auth.signUp.submit' : 'auth.signIn.submit'} />
        </button>
      </form>
      <p style={{ marginTop: '1rem' }}>
        <button
          type="button" className="link"
          onClick={() => { setMode((m) => (m === 'signIn' ? 'signUp' : 'signIn')); setFailed(false) }}
        >
          <T id={mode === 'signIn' ? 'auth.toggle.toSignUp' : 'auth.toggle.toSignIn'} />
        </button>
      </p>
    </section>
  )
}
