import { type FormEvent, useState } from 'react'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { api } from '@/lib/api'
import { useAuth } from '@/store/auth'

interface AuthResponse {
  token: string
  memberId: string
}

interface BootstrapResponse {
  token: string
  memberId: string
  organizationId: string
}

interface MeResponse {
  email: string
  memberships: { scopeType: string; scopeId: string; role: string }[]
}

export function LoginPage() {
  const setAuth = useAuth((state) => state.setAuth)
  const [mode, setMode] = useState<'login' | 'bootstrap'>('login')
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [displayName, setDisplayName] = useState('')
  const [orgName, setOrgName] = useState('')
  const [busy, setBusy] = useState(false)

  async function submit(event: FormEvent) {
    event.preventDefault()
    setBusy(true)
    try {
      if (mode === 'bootstrap') {
        const result = await api.post<BootstrapResponse>('/api/identity/bootstrap', {
          organizationName: orgName,
          ownerEmail: email,
          ownerDisplayName: displayName,
          ownerPassword: password,
        })
        setAuth(result.token, result.memberId, result.organizationId, email)
      } else {
        const result = await api.post<AuthResponse>('/api/identity/auth/login', { email, password })
        setAuth(result.token, result.memberId, null, email)
        const me = await api.get<MeResponse>('/api/identity/me')
        const org = me.memberships.find((m) => m.scopeType === 'Organization')
        setAuth(result.token, result.memberId, org?.scopeId ?? null, me.email)
      }
    } catch (err) {
      toast.error((err as Error).message)
    } finally {
      setBusy(false)
    }
  }

  return (
    <main className="grid min-h-screen place-items-center bg-sidebar px-6">
      <Card className="w-full max-w-sm">
        <CardHeader>
          <div className="flex items-center gap-3">
            <span className="grid size-8 place-items-center rounded-md bg-primary font-bold text-primary-foreground">
              T
            </span>
            <CardTitle>TeamUp.AI</CardTitle>
          </div>
          <CardDescription>
            {mode === 'login' ? 'Sign in to your command center.' : 'Create the first owner of a new org.'}
          </CardDescription>
        </CardHeader>
        <CardContent>
          <form onSubmit={submit} className="flex flex-col gap-4">
            {mode === 'bootstrap' && (
              <LabeledInput id="org" label="Organization" value={orgName} onChange={setOrgName} />
            )}
            {mode === 'bootstrap' && (
              <LabeledInput id="name" label="Display name" value={displayName} onChange={setDisplayName} />
            )}
            <LabeledInput id="email" label="Email" type="email" value={email} onChange={setEmail} />
            <LabeledInput id="password" label="Password" type="password" value={password} onChange={setPassword} />

            <Button type="submit" disabled={busy}>
              {busy ? 'Working…' : mode === 'login' ? 'Sign in' : 'Bootstrap'}
            </Button>
            <Button
              type="button"
              variant="ghost"
              size="sm"
              onClick={() => setMode(mode === 'login' ? 'bootstrap' : 'login')}
            >
              {mode === 'login' ? 'First run? Bootstrap the owner' : 'Back to sign in'}
            </Button>
          </form>
        </CardContent>
      </Card>
    </main>
  )
}

function LabeledInput(props: {
  id: string
  label: string
  value: string
  onChange: (value: string) => void
  type?: string
}) {
  return (
    <div className="flex flex-col gap-2">
      <Label htmlFor={props.id}>{props.label}</Label>
      <Input
        id={props.id}
        type={props.type ?? 'text'}
        value={props.value}
        onChange={(event) => props.onChange(event.target.value)}
        required
      />
    </div>
  )
}
