'use client'

import { useState, useCallback, useMemo } from 'react'
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import Papa from 'papaparse'
import { trpc } from '@/lib/trpc/client'
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 { Textarea } from '@/components/ui/textarea'
import { Badge } from '@/components/ui/badge'
import { Progress } from '@/components/ui/progress'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import {
  ArrowLeft,
  ArrowRight,
  AlertCircle,
  CheckCircle2,
  Loader2,
  Users,
  X,
  Mail,
  FileSpreadsheet,
} from 'lucide-react'
import { cn } from '@/lib/utils'

type Step = 'input' | 'preview' | 'sending' | 'complete'
type Role = 'JURY_MEMBER' | 'MENTOR' | 'OBSERVER'

interface ParsedUser {
  email: string
  name?: string
  isValid: boolean
  error?: string
  isDuplicate?: boolean
}

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

export default function MemberInvitePage() {
  const router = useRouter()
  const [step, setStep] = useState<Step>('input')
  const [inputMethod, setInputMethod] = useState<'textarea' | 'csv'>('textarea')
  const [emailsText, setEmailsText] = useState('')
  const [csvFile, setCsvFile] = useState<File | null>(null)
  const [role, setRole] = useState<Role>('JURY_MEMBER')
  const [expertiseTags, setExpertiseTags] = useState<string[]>([])
  const [tagInput, setTagInput] = useState('')
  const [parsedUsers, setParsedUsers] = useState<ParsedUser[]>([])
  const [sendProgress, setSendProgress] = useState(0)
  const [result, setResult] = useState<{ created: number; skipped: number } | null>(null)

  const bulkCreate = trpc.user.bulkCreate.useMutation()

  const parseEmailsFromText = useCallback((text: string): ParsedUser[] => {
    const lines = text.split(/[\n,;]+/).map((line) => line.trim()).filter(Boolean)
    const seenEmails = new Set<string>()
    return lines.map((line) => {
      const matchWithName = line.match(/^(.+?)\s*<(.+?)>$/)
      const email = matchWithName ? matchWithName[2].trim().toLowerCase() : line.toLowerCase()
      const name = matchWithName ? matchWithName[1].trim() : undefined
      const isValidFormat = emailRegex.test(email)
      const isDuplicate = seenEmails.has(email)
      if (isValidFormat && !isDuplicate) seenEmails.add(email)
      return {
        email, name, isValid: isValidFormat && !isDuplicate, isDuplicate,
        error: !isValidFormat ? 'Invalid email format' : isDuplicate ? 'Duplicate email' : undefined,
      }
    })
  }, [])

  const handleCSVUpload = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (!file) return
    setCsvFile(file)
    Papa.parse<Record<string, string>>(file, {
      header: true, skipEmptyLines: true,
      complete: (results) => {
        const seenEmails = new Set<string>()
        const users: ParsedUser[] = results.data.map((row) => {
          const emailKey = Object.keys(row).find((key) => key.toLowerCase() === 'email' || key.toLowerCase().includes('email'))
          const nameKey = Object.keys(row).find((key) => key.toLowerCase() === 'name' || key.toLowerCase().includes('name'))
          const email = emailKey ? row[emailKey]?.trim().toLowerCase() : ''
          const name = nameKey ? row[nameKey]?.trim() : undefined
          const isValidFormat = emailRegex.test(email)
          const isDuplicate = email ? seenEmails.has(email) : false
          if (isValidFormat && !isDuplicate && email) seenEmails.add(email)
          return {
            email, name, isValid: isValidFormat && !isDuplicate, isDuplicate,
            error: !email ? 'No email found' : !isValidFormat ? 'Invalid email format' : isDuplicate ? 'Duplicate email' : undefined,
          }
        })
        setParsedUsers(users.filter((u) => u.email))
        setStep('preview')
      },
    })
  }, [])

  const handleTextProceed = () => { setParsedUsers(parseEmailsFromText(emailsText)); setStep('preview') }
  const addTag = () => { const tag = tagInput.trim(); if (tag && !expertiseTags.includes(tag)) { setExpertiseTags([...expertiseTags, tag]); setTagInput('') } }
  const removeTag = (tag: string) => setExpertiseTags(expertiseTags.filter((t) => t !== tag))

  const summary = useMemo(() => {
    const validUsers = parsedUsers.filter((u) => u.isValid)
    const invalidUsers = parsedUsers.filter((u) => !u.isValid)
    const duplicateUsers = parsedUsers.filter((u) => u.isDuplicate)
    return { total: parsedUsers.length, valid: validUsers.length, invalid: invalidUsers.length, duplicates: duplicateUsers.length, validUsers, invalidUsers, duplicateUsers }
  }, [parsedUsers])

  const removeInvalidUsers = () => setParsedUsers(parsedUsers.filter((u) => u.isValid))

  const handleSendInvites = async () => {
    if (summary.valid === 0) return
    setStep('sending'); setSendProgress(0)
    try {
      const result = await bulkCreate.mutateAsync({
        users: summary.validUsers.map((u) => ({ email: u.email, name: u.name, role, expertiseTags: expertiseTags.length > 0 ? expertiseTags : undefined })),
      })
      setSendProgress(100); setResult(result); setStep('complete')
    } catch { setStep('preview') }
  }

  const resetForm = () => { setStep('input'); setEmailsText(''); setCsvFile(null); setParsedUsers([]); setResult(null); setSendProgress(0) }

  const steps: Array<{ key: Step; label: string }> = [
    { key: 'input', label: 'Input' }, { key: 'preview', label: 'Preview' },
    { key: 'sending', label: 'Send' }, { key: 'complete', label: 'Done' },
  ]
  const currentStepIndex = steps.findIndex((s) => s.key === step)

  const renderStep = () => {
    switch (step) {
      case 'input':
        return (
          <Card>
            <CardHeader>
              <CardTitle>Invite Members</CardTitle>
              <CardDescription>Add email addresses to invite new members to the platform</CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              <div className="flex gap-2">
                <Button type="button" variant={inputMethod === 'textarea' ? 'default' : 'outline'} size="sm" onClick={() => setInputMethod('textarea')}><Mail className="mr-2 h-4 w-4" />Enter Emails</Button>
                <Button type="button" variant={inputMethod === 'csv' ? 'default' : 'outline'} size="sm" onClick={() => setInputMethod('csv')}><FileSpreadsheet className="mr-2 h-4 w-4" />Upload CSV</Button>
              </div>
              {inputMethod === 'textarea' ? (
                <div className="space-y-2">
                  <Label htmlFor="emails">Email Addresses</Label>
                  <Textarea id="emails" value={emailsText} onChange={(e) => setEmailsText(e.target.value)} placeholder="Enter email addresses, one per line or comma-separated." rows={8} maxLength={10000} className="font-mono text-sm" />
                </div>
              ) : (
                <div className="space-y-2">
                  <Label>CSV File</Label>
                  <div className={cn('border-2 border-dashed rounded-lg p-6 text-center cursor-pointer transition-colors', 'hover:border-primary/50')} onClick={() => document.getElementById('csv-input')?.click()}>
                    <FileSpreadsheet className="mx-auto h-10 w-10 text-muted-foreground" />
                    <p className="mt-2 font-medium">{csvFile ? csvFile.name : 'Drop CSV file here or click to browse'}</p>
                    <Input id="csv-input" type="file" accept=".csv" onChange={handleCSVUpload} className="hidden" />
                  </div>
                </div>
              )}
              <div className="space-y-2">
                <Label htmlFor="role">Role</Label>
                <Select value={role} onValueChange={(v) => setRole(v as Role)}>
                  <SelectTrigger id="role"><SelectValue /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value="JURY_MEMBER">Jury Member</SelectItem>
                    <SelectItem value="MENTOR">Mentor</SelectItem>
                    <SelectItem value="OBSERVER">Observer</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-2">
                <Label htmlFor="expertise">Expertise Tags (Optional)</Label>
                <div className="flex gap-2">
                  <Input id="expertise" value={tagInput} onChange={(e) => setTagInput(e.target.value)} placeholder="e.g., Marine Biology" onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); addTag() } }} />
                  <Button type="button" variant="outline" onClick={addTag}>Add</Button>
                </div>
                {expertiseTags.length > 0 && (
                  <div className="flex flex-wrap gap-2 mt-2">
                    {expertiseTags.map((tag) => (
                      <Badge key={tag} variant="secondary" className="gap-1">{tag}<button type="button" onClick={() => removeTag(tag)} className="ml-1 hover:text-destructive"><X className="h-3 w-3" /></button></Badge>
                    ))}
                  </div>
                )}
              </div>
              <div className="flex justify-between pt-4">
                <Button variant="outline" asChild><Link href="/admin/members"><ArrowLeft className="mr-2 h-4 w-4" />Cancel</Link></Button>
                <Button onClick={handleTextProceed} disabled={inputMethod === 'textarea' && !emailsText.trim()}>Preview<ArrowRight className="ml-2 h-4 w-4" /></Button>
              </div>
            </CardContent>
          </Card>
        )
      case 'preview':
        return (
          <Card>
            <CardHeader><CardTitle>Preview Invitations</CardTitle><CardDescription>Review the list of users to invite</CardDescription></CardHeader>
            <CardContent className="space-y-6">
              <div className="grid gap-4 sm:grid-cols-3">
                <div className="rounded-lg bg-muted p-4 text-center"><p className="text-3xl font-bold">{summary.total}</p><p className="text-sm text-muted-foreground">Total</p></div>
                <div className="rounded-lg bg-green-500/10 p-4 text-center"><p className="text-3xl font-bold text-green-600">{summary.valid}</p><p className="text-sm text-muted-foreground">Valid</p></div>
                <div className="rounded-lg bg-red-500/10 p-4 text-center"><p className="text-3xl font-bold text-red-600">{summary.invalid}</p><p className="text-sm text-muted-foreground">Invalid</p></div>
              </div>
              {summary.invalid > 0 && (
                <div className="flex items-start gap-3 rounded-lg bg-amber-500/10 p-4 text-amber-700">
                  <AlertCircle className="h-5 w-5 shrink-0 mt-0.5" /><div className="flex-1"><p className="font-medium">{summary.invalid} email(s) have issues</p></div>
                  <Button variant="outline" size="sm" onClick={removeInvalidUsers} className="shrink-0">Remove Invalid</Button>
                </div>
              )}
              <div className="rounded-lg border max-h-80 overflow-y-auto">
                <Table>
                  <TableHeader><TableRow><TableHead>Email</TableHead><TableHead>Name</TableHead><TableHead>Status</TableHead></TableRow></TableHeader>
                  <TableBody>
                    {parsedUsers.map((user, index) => (
                      <TableRow key={index} className={cn(!user.isValid && 'bg-red-500/5')}>
                        <TableCell className="font-mono text-sm">{user.email}</TableCell>
                        <TableCell>{user.name || '-'}</TableCell>
                        <TableCell>{user.isValid ? <Badge variant="outline" className="text-green-600"><CheckCircle2 className="mr-1 h-3 w-3" />Valid</Badge> : <Badge variant="destructive">{user.error}</Badge>}</TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              </div>
              <div className="flex justify-between pt-4">
                <Button variant="outline" onClick={() => { setParsedUsers([]); setStep('input') }}><ArrowLeft className="mr-2 h-4 w-4" />Back</Button>
                <Button onClick={handleSendInvites} disabled={summary.valid === 0 || bulkCreate.isPending}>
                  {bulkCreate.isPending ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Users className="mr-2 h-4 w-4" />}
                  Create {summary.valid} Member{summary.valid !== 1 ? 's' : ''}
                </Button>
              </div>
              {bulkCreate.error && <div className="flex items-center gap-2 rounded-lg bg-destructive/10 p-4 text-destructive"><AlertCircle className="h-5 w-5" /><span>{bulkCreate.error.message}</span></div>}
            </CardContent>
          </Card>
        )
      case 'sending':
        return (
          <Card><CardContent className="flex flex-col items-center justify-center py-12"><Loader2 className="h-12 w-12 animate-spin text-primary" /><p className="mt-4 font-medium">Creating members...</p><Progress value={sendProgress} className="mt-4 w-48" /></CardContent></Card>
        )
      case 'complete':
        return (
          <Card>
            <CardContent className="flex flex-col items-center justify-center py-12">
              <div className="flex h-16 w-16 items-center justify-center rounded-full bg-green-500/10"><CheckCircle2 className="h-8 w-8 text-green-600" /></div>
              <p className="mt-4 text-xl font-semibold">Members Created!</p>
              <p className="text-muted-foreground text-center max-w-sm mt-2">{result?.created} member{result?.created !== 1 ? 's' : ''} created successfully.{result?.skipped ? ` ${result.skipped} skipped (already exist).` : ''}</p>
              <div className="mt-6 flex gap-3">
                <Button variant="outline" asChild><Link href="/admin/members">View Members</Link></Button>
                <Button onClick={resetForm}>Invite More</Button>
              </div>
            </CardContent>
          </Card>
        )
    }
  }

  return (
    <div className="space-y-6">
      <div className="flex items-center gap-4">
        <Button variant="ghost" asChild className="-ml-4"><Link href="/admin/members"><ArrowLeft className="mr-2 h-4 w-4" />Back to Members</Link></Button>
      </div>
      <div>
        <h1 className="text-2xl font-semibold tracking-tight">Invite Members</h1>
        <p className="text-muted-foreground">Add new members to the platform</p>
      </div>
      <div className="flex items-center justify-center gap-2">
        {steps.map((s, index) => (
          <div key={s.key} className="flex items-center">
            {index > 0 && <div className={cn('h-0.5 w-8 mx-1', index <= currentStepIndex ? 'bg-primary' : 'bg-muted')} />}
            <div className={cn('flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium', index === currentStepIndex ? 'bg-primary text-primary-foreground' : index < currentStepIndex ? 'bg-primary/20 text-primary' : 'bg-muted text-muted-foreground')}>{index + 1}</div>
          </div>
        ))}
      </div>
      {renderStep()}
    </div>
  )
}
