import { useState, useEffect } from 'react'
import { Loader2 } from 'lucide-react'
import { toast } from 'sonner'
import { trpc } from '@/lib/trpc'
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Textarea } from '@/components/ui/textarea'
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '@/components/ui/select'

interface AddAccountDialogProps {
  open: boolean
  onOpenChange: (open: boolean) => void
}

const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/

export function AddAccountDialog({ open, onOpenChange }: AddAccountDialogProps) {
  const [tab, setTab] = useState<'token' | 'credentials'>('token')

  // Tab A — token
  const [email, setEmail] = useState('')
  const [token, setToken] = useState('')
  const [provider, setProvider] = useState('claude')

  // Tab B — credentials JSON
  const [credEmail, setCredEmail] = useState('')
  const [credProvider, setCredProvider] = useState('claude')
  const [configJsonText, setConfigJsonText] = useState('')
  const [credentialsText, setCredentialsText] = useState('')

  // Validation errors
  const [emailError, setEmailError] = useState('')
  const [tokenError, setTokenError] = useState('')
  const [credEmailError, setCredEmailError] = useState('')
  const [configJsonError, setConfigJsonError] = useState('')
  const [credentialsError, setCredentialsError] = useState('')
  const [serverError, setServerError] = useState('')

  const utils = trpc.useUtils()
  const providersQuery = trpc.listProviderNames.useQuery()

  const addByToken = trpc.addAccountByToken.useMutation({
    onSuccess: (data) => {
      const msg = data.upserted
        ? `Account updated — credentials refreshed for ${email}.`
        : `Account added: ${email}.`
      toast.success(msg)
      void utils.systemHealthCheck.invalidate()
      onOpenChange(false)
    },
    onError: (err) => {
      setServerError(err.message)
    },
  })

  const addAccount = trpc.addAccount.useMutation({
    onSuccess: () => {
      toast.success(`Account added: ${credEmail}.`)
      void utils.systemHealthCheck.invalidate()
      onOpenChange(false)
    },
    onError: (err) => {
      if (err.message.toLowerCase().includes('already exists')) {
        setCredEmailError(
          "An account with this email already exists. Use 'Update credentials' on the existing account instead."
        )
      } else {
        setServerError(err.message)
      }
    },
  })

  useEffect(() => {
    if (open) {
      setTab('token')
      setEmail(''); setToken(''); setProvider('claude')
      setCredEmail(''); setCredProvider('claude')
      setConfigJsonText(''); setCredentialsText('')
      setEmailError(''); setTokenError('')
      setCredEmailError(''); setConfigJsonError(''); setCredentialsError('')
      setServerError('')
    }
  }, [open])

  function handleSubmit() {
    setEmailError(''); setTokenError(''); setCredEmailError('')
    setConfigJsonError(''); setCredentialsError(''); setServerError('')

    if (tab === 'token') {
      let hasError = false
      if (email.trim() === '') {
        setEmailError('Required')
        hasError = true
      } else if (!EMAIL_REGEX.test(email)) {
        setEmailError('Enter a valid email address')
        hasError = true
      }
      if (token.trim() === '') {
        setTokenError('Required')
        hasError = true
      }
      if (hasError) return
      addByToken.mutate({ email, token, provider })
    } else {
      let hasError = false
      if (credEmail.trim() === '') {
        setCredEmailError('Required')
        hasError = true
      } else if (!EMAIL_REGEX.test(credEmail)) {
        setCredEmailError('Enter a valid email address')
        hasError = true
      }
      if (configJsonText.trim() !== '') {
        try {
          JSON.parse(configJsonText)
        } catch {
          setConfigJsonError('Invalid JSON')
          hasError = true
        }
      }
      if (credentialsText.trim() !== '') {
        try {
          JSON.parse(credentialsText)
        } catch {
          setCredentialsError('Invalid JSON')
          hasError = true
        }
      }
      if (hasError) return
      addAccount.mutate({
        email: credEmail,
        provider: credProvider,
        configJson: configJsonText.trim() || undefined,
        credentials: credentialsText.trim() || undefined,
      })
    }
  }

  const isPending = tab === 'token' ? addByToken.isPending : addAccount.isPending

  function renderProviderSelect(value: string, onChange: (v: string) => void) {
    if (providersQuery.isError) {
      return <Input value={value} onChange={(e) => onChange(e.target.value)} />
    }
    return (
      <Select value={value} onValueChange={onChange}>
        <SelectTrigger><SelectValue /></SelectTrigger>
        <SelectContent>
          {(providersQuery.data ?? ['claude']).map((p) => (
            <SelectItem key={p} value={p}>{p}</SelectItem>
          ))}
        </SelectContent>
      </Select>
    )
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Add Account</DialogTitle>
        </DialogHeader>

        <div className="flex border-b">
          <button
            type="button"
            onClick={() => {
              setTab('token')
              setCredEmail('')
              setCredProvider('claude')
              setConfigJsonText('')
              setCredentialsText('')
              setCredEmailError('')
              setConfigJsonError('')
              setCredentialsError('')
              setServerError('')
            }}
            className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
              tab === 'token'
                ? 'border-primary text-foreground'
                : 'border-transparent text-muted-foreground hover:text-foreground'
            }`}
          >
            By token
          </button>
          <button
            type="button"
            onClick={() => {
              setTab('credentials')
              setEmail('')
              setToken('')
              setEmailError('')
              setTokenError('')
              setServerError('')
            }}
            className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
              tab === 'credentials'
                ? 'border-primary text-foreground'
                : 'border-transparent text-muted-foreground hover:text-foreground'
            }`}
          >
            By credentials JSON
          </button>
        </div>

        {tab === 'token' ? (
          <div className="space-y-4">
            <div className="space-y-2">
              <Label>Email</Label>
              <Input
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                placeholder="user@example.com"
              />
              {emailError && <p className="text-sm text-destructive">{emailError}</p>}
            </div>
            <div className="space-y-2">
              <Label>Setup token (from `claude setup-token`)</Label>
              <Input
                value={token}
                onChange={(e) => setToken(e.target.value)}
              />
              {tokenError && <p className="text-sm text-destructive">{tokenError}</p>}
              {serverError && <p className="text-sm text-destructive">{serverError}</p>}
            </div>
            <div className="space-y-2">
              <Label>Provider</Label>
              {renderProviderSelect(provider, setProvider)}
            </div>
          </div>
        ) : (
          <div className="space-y-4">
            <div className="space-y-2">
              <Label>Email</Label>
              <Input
                value={credEmail}
                onChange={(e) => setCredEmail(e.target.value)}
                placeholder="user@example.com"
              />
              {credEmailError && <p className="text-sm text-destructive">{credEmailError}</p>}
            </div>
            <div className="space-y-2">
              <Label>Provider</Label>
              {renderProviderSelect(credProvider, setCredProvider)}
            </div>
            <div className="space-y-2">
              <Label>Config JSON (`.claude.json` content)</Label>
              <Textarea
                value={configJsonText}
                onChange={(e) => setConfigJsonText(e.target.value)}
                placeholder={`{ "oauthAccount": { ... } }`}
              />
              {configJsonError && <p className="text-sm text-destructive">{configJsonError}</p>}
            </div>
            <div className="space-y-2">
              <Label>Credentials JSON (`.credentials.json` content)</Label>
              <Textarea
                value={credentialsText}
                onChange={(e) => setCredentialsText(e.target.value)}
                placeholder={`{ "claudeAiOauth": { ... } }`}
              />
              {credentialsError && <p className="text-sm text-destructive">{credentialsError}</p>}
            </div>
            <p className="text-xs text-muted-foreground">
              Run `cw account extract` in your terminal to obtain these values.
            </p>
            {serverError && <p className="text-sm text-destructive">{serverError}</p>}
          </div>
        )}

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            type="submit"
            disabled={isPending}
            onClick={handleSubmit}
          >
            {isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
            Add Account
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
