'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,
  Upload,
  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
}

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

export default function UserInvitePage() {
  const router = useRouter()
  const [step, setStep] = useState<Step>('input')

  // Input state
  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('')

  // Parsed users
  const [parsedUsers, setParsedUsers] = useState<ParsedUser[]>([])

  // Send progress
  const [sendProgress, setSendProgress] = useState(0)

  // Result
  const [result, setResult] = useState<{ created: number; skipped: number } | null>(null)

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

  // Parse emails from textarea
  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) => {
      // Try to extract name and email like "Name <email@example.com>" or just "email@example.com"
      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)
      }

      const isValid = isValidFormat && !isDuplicate

      return {
        email,
        name,
        isValid,
        isDuplicate,
        error: !isValidFormat
          ? 'Invalid email format'
          : isDuplicate
            ? 'Duplicate email'
            : undefined,
      }
    })
  }, [])

  // Parse CSV file
  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) => {
            // Try to find email column (case-insensitive)
            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)
            }

            const isValid = isValidFormat && !isDuplicate

            return {
              email,
              name,
              isValid,
              isDuplicate,
              error: !email
                ? 'No email found'
                : !isValidFormat
                  ? 'Invalid email format'
                  : isDuplicate
                    ? 'Duplicate email'
                    : undefined,
            }
          })

          setParsedUsers(users.filter((u) => u.email))
          setStep('preview')
        },
        error: (error) => {
          console.error('CSV parse error:', error)
        },
      })
    },
    []
  )

  // Handle text input and proceed to preview
  const handleTextProceed = () => {
    const users = parseEmailsFromText(emailsText)
    setParsedUsers(users)
    setStep('preview')
  }

  // Add expertise tag
  const addTag = () => {
    const tag = tagInput.trim()
    if (tag && !expertiseTags.includes(tag)) {
      setExpertiseTags([...expertiseTags, tag])
      setTagInput('')
    }
  }

  // Remove expertise tag
  const removeTag = (tag: string) => {
    setExpertiseTags(expertiseTags.filter((t) => t !== tag))
  }

  // Summary stats
  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])

  // Remove invalid users
  const removeInvalidUsers = () => {
    setParsedUsers(parsedUsers.filter((u) => u.isValid))
  }

  // Send invites
  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 (error) {
      console.error('Bulk create failed:', error)
      setStep('preview')
    }
  }

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

  // Steps indicator
  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 Users</CardTitle>
              <CardDescription>
                Add email addresses to invite new jury members or observers
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              {/* Input Method Toggle */}
              <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>

              {/* Input Area */}
              {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.
You can also use format: Name <email@example.com>"
                    rows={8}
                    maxLength={10000}
                    className="font-mono text-sm"
                  />
                  <p className="text-xs text-muted-foreground">
                    One email per line, or separated by commas
                  </p>
                </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>
                    <p className="text-sm text-muted-foreground">
                      CSV should have an &quot;email&quot; column, optionally a &quot;name&quot; column
                    </p>
                    <Input
                      id="csv-input"
                      type="file"
                      accept=".csv"
                      onChange={handleCSVUpload}
                      className="hidden"
                    />
                  </div>
                </div>
              )}

              {/* Role Selection */}
              <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>
                <p className="text-xs text-muted-foreground">
                  {role === 'JURY_MEMBER'
                    ? 'Can evaluate assigned projects'
                    : role === 'MENTOR'
                      ? 'Can view and mentor assigned projects'
                      : 'Read-only access to dashboards'}
                </p>
              </div>

              {/* Expertise Tags */}
              <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>

              {/* Actions */}
              <div className="flex justify-between pt-4">
                <Button variant="outline" asChild>
                  <Link href="/admin/users">
                    <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">
              {/* Summary Stats */}
              <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>

              {/* Invalid users warning */}
              {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>
                    <p className="text-sm mt-1">
                      {summary.duplicates > 0 && (
                        <span>{summary.duplicates} duplicate(s). </span>
                      )}
                      {summary.invalid - summary.duplicates > 0 && (
                        <span>{summary.invalid - summary.duplicates} invalid format(s). </span>
                      )}
                      These will be excluded from the invitation.
                    </p>
                  </div>
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={removeInvalidUsers}
                    className="shrink-0"
                  >
                    Remove Invalid
                  </Button>
                </div>
              )}

              {/* Settings Summary */}
              <div className="flex flex-wrap gap-4 text-sm">
                <div>
                  <span className="text-muted-foreground">Role:</span>{' '}
                  <Badge variant="outline">{role.replace('_', ' ')}</Badge>
                </div>
                {expertiseTags.length > 0 && (
                  <div className="flex items-center gap-2">
                    <span className="text-muted-foreground">Tags:</span>
                    {expertiseTags.map((tag) => (
                      <Badge key={tag} variant="secondary" className="text-xs">
                        {tag}
                      </Badge>
                    ))}
                  </div>
                )}
              </div>

              {/* Users Table */}
              <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>

              {/* Actions */}
              <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} User{summary.valid !== 1 ? 's' : ''}
                </Button>
              </div>

              {/* Error */}
              {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 users...</p>
              <p className="text-sm text-muted-foreground">
                Please wait while we process your request
              </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">Users Created!</p>
              <p className="text-muted-foreground text-center max-w-sm mt-2">
                {result?.created} user{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/users">View Users</Link>
                </Button>
                <Button onClick={resetForm}>Invite More</Button>
              </div>
            </CardContent>
          </Card>
        )
    }
  }

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center gap-4">
        <Button variant="ghost" asChild className="-ml-4">
          <Link href="/admin/users">
            <ArrowLeft className="mr-2 h-4 w-4" />
            Back to Users
          </Link>
        </Button>
      </div>

      <div>
        <h1 className="text-2xl font-semibold tracking-tight">Invite Users</h1>
        <p className="text-muted-foreground">
          Add new jury members or observers to the platform
        </p>
      </div>

      {/* Progress indicator */}
      <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>
  )
}
