'use client'

import { Suspense, useEffect, useMemo, useState } from 'react'
import { useRouter, useSearchParams } from 'next/navigation'
import BrandingLogo from '../ui/BrandingLogo'
import { clearToken, getApiBase, setToken } from '../lib/auth'

type InviteInfo = {
  code: string
  label?: string | null
  description?: string | null
  enabled: boolean
  is_expired?: boolean
  is_usable?: boolean
  expires_at?: string | null
  max_uses?: number | null
  use_count?: number | null
  remaining_uses?: number | null
  profile?: {
    id: number
    name: string
    description?: string | null
  } | null
}

const formatDate = (value?: string | null) => {
  if (!value) return 'Never'
  const date = new Date(value)
  if (Number.isNaN(date.valueOf())) return value
  return date.toLocaleString()
}

function SignupPageContent() {
  const router = useRouter()
  const searchParams = useSearchParams()
  const [inviteCode, setInviteCode] = useState(searchParams.get('code') ?? '')
  const [invite, setInvite] = useState<InviteInfo | null>(null)
  const [inviteLoading, setInviteLoading] = useState(false)
  const [loading, setLoading] = useState(false)
  const [username, setUsername] = useState('')
  const [password, setPassword] = useState('')
  const [confirmPassword, setConfirmPassword] = useState('')
  const [error, setError] = useState<string | null>(null)
  const [status, setStatus] = useState<string | null>(null)

  const canSubmit = useMemo(() => {
    return Boolean(invite?.is_usable && username.trim() && password && !loading)
  }, [invite, username, password, loading])

  const lookupInvite = async (code: string) => {
    const trimmed = code.trim()
    if (!trimmed) {
      setInvite(null)
      return
    }
    setInviteLoading(true)
    setError(null)
    setStatus(null)
    try {
      const baseUrl = getApiBase()
      const response = await fetch(`${baseUrl}/auth/invites/${encodeURIComponent(trimmed)}`)
      if (!response.ok) {
        const text = await response.text()
        throw new Error(text || 'Invite not found')
      }
      const data = await response.json()
      setInvite(data?.invite ?? null)
      setStatus('Invite loaded.')
    } catch (err) {
      console.error(err)
      setInvite(null)
      setError('Invite code not found or unavailable.')
    } finally {
      setInviteLoading(false)
    }
  }

  useEffect(() => {
    const initialCode = searchParams.get('code') ?? ''
    if (initialCode) {
      setInviteCode(initialCode)
      void lookupInvite(initialCode)
    }
  }, [searchParams])

  const submit = async (event: React.FormEvent) => {
    event.preventDefault()
    if (password !== confirmPassword) {
      setError('Passwords do not match.')
      return
    }
    if (!inviteCode.trim()) {
      setError('Invite code is required.')
      return
    }
    if (!invite?.is_usable) {
      setError('Invite is not usable. Refresh invite details or ask an admin for a new code.')
      return
    }
    setLoading(true)
    setError(null)
    setStatus(null)
    try {
      clearToken()
      const baseUrl = getApiBase()
      const response = await fetch(`${baseUrl}/auth/signup`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          invite_code: inviteCode,
          username: username.trim(),
          password,
        }),
      })
      if (!response.ok) {
        const text = await response.text()
        throw new Error(text || 'Sign-up failed')
      }
      const data = await response.json()
      if (data?.access_token) {
        setToken(data.access_token)
        window.location.href = '/'
        return
      }
      throw new Error('Sign-up did not return a token')
    } catch (err) {
      console.error(err)
      setError(err instanceof Error ? err.message : 'Unable to create account.')
    } finally {
      setLoading(false)
    }
  }

  return (
    <main className="card auth-card">
      <BrandingLogo className="brand-logo brand-logo--login" />
      <h1>Create account</h1>
      <p className="lede">Use an invite code from your admin to create a Magent account.</p>
      <form onSubmit={submit} className="auth-form">
        <label>
          Invite code
          <div className="invite-lookup-row">
            <input
              value={inviteCode}
              onChange={(e) => setInviteCode(e.target.value)}
              placeholder="Paste your invite code"
              autoCapitalize="characters"
            />
            <button
              type="button"
              className="ghost-button"
              disabled={inviteLoading}
              onClick={() => void lookupInvite(inviteCode)}
            >
              {inviteLoading ? 'Checking…' : 'Check invite'}
            </button>
          </div>
        </label>
        {invite && (
          <div className={`invite-summary ${invite.is_usable ? '' : 'is-disabled'}`}>
            <div className="invite-summary-row">
              <strong>{invite.label || invite.code}</strong>
              <span className={`small-pill ${invite.is_usable ? '' : 'is-muted'}`}>
                {invite.is_usable ? 'Usable' : 'Unavailable'}
              </span>
            </div>
            {invite.description && <p>{invite.description}</p>}
            <div className="admin-meta-row">
              <span>Code: {invite.code}</span>
              <span>Expires: {formatDate(invite.expires_at)}</span>
              <span>Remaining uses: {invite.remaining_uses ?? 'Unlimited'}</span>
              <span>Profile: {invite.profile?.name || 'None'}</span>
            </div>
          </div>
        )}
        <label>
          Username
          <input
            value={username}
            onChange={(e) => setUsername(e.target.value)}
            autoComplete="username"
          />
        </label>
        <label>
          Password
          <input
            type="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            autoComplete="new-password"
          />
        </label>
        <label>
          Confirm password
          <input
            type="password"
            value={confirmPassword}
            onChange={(e) => setConfirmPassword(e.target.value)}
            autoComplete="new-password"
          />
        </label>
        {error && <div className="error-banner">{error}</div>}
        {status && <div className="status-banner">{status}</div>}
        <div className="auth-actions">
          <button type="submit" disabled={!canSubmit}>
            {loading ? 'Creating account…' : 'Create account'}
          </button>
        </div>
        <button type="button" className="ghost-button" disabled={loading} onClick={() => router.push('/login')}>
          Back to sign in
        </button>
      </form>
    </main>
  )
}

export default function SignupPage() {
  return (
    <Suspense fallback={<main className="card auth-card">Loading sign-up…</main>}>
      <SignupPageContent />
    </Suspense>
  )
}
