'use client'

import { useState } from 'react'
import { trpc } from '@/lib/trpc/client'
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 { Switch } from '@/components/ui/switch'
import { Badge } from '@/components/ui/badge'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import { toast } from 'sonner'
import {
  Plus,
  Pencil,
  Trash2,
  GripVertical,
  ArrowUp,
  ArrowDown,
  FileText,
  Loader2,
} from 'lucide-react'

const MIME_TYPE_PRESETS = [
  { label: 'PDF', value: 'application/pdf' },
  { label: 'Images', value: 'image/*' },
  { label: 'Video', value: 'video/*' },
  { label: 'Word Documents', value: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' },
  { label: 'Excel', value: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' },
  { label: 'PowerPoint', value: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' },
]

function getMimeLabel(mime: string): string {
  const preset = MIME_TYPE_PRESETS.find((p) => p.value === mime)
  if (preset) return preset.label
  if (mime.endsWith('/*')) return mime.replace('/*', '')
  return mime
}

interface FileRequirementsEditorProps {
  roundId: string
}

interface RequirementFormData {
  name: string
  description: string
  acceptedMimeTypes: string[]
  maxSizeMB: string
  isRequired: boolean
}

const emptyForm: RequirementFormData = {
  name: '',
  description: '',
  acceptedMimeTypes: [],
  maxSizeMB: '',
  isRequired: true,
}

export function FileRequirementsEditor({ roundId }: FileRequirementsEditorProps) {
  const utils = trpc.useUtils()

  const { data: requirements = [], isLoading } = trpc.file.listRequirements.useQuery({ roundId })
  const createMutation = trpc.file.createRequirement.useMutation({
    onSuccess: () => {
      utils.file.listRequirements.invalidate({ roundId })
      toast.success('Requirement created')
    },
    onError: (err) => toast.error(err.message),
  })
  const updateMutation = trpc.file.updateRequirement.useMutation({
    onSuccess: () => {
      utils.file.listRequirements.invalidate({ roundId })
      toast.success('Requirement updated')
    },
    onError: (err) => toast.error(err.message),
  })
  const deleteMutation = trpc.file.deleteRequirement.useMutation({
    onSuccess: () => {
      utils.file.listRequirements.invalidate({ roundId })
      toast.success('Requirement deleted')
    },
    onError: (err) => toast.error(err.message),
  })
  const reorderMutation = trpc.file.reorderRequirements.useMutation({
    onSuccess: () => utils.file.listRequirements.invalidate({ roundId }),
    onError: (err) => toast.error(err.message),
  })

  const [dialogOpen, setDialogOpen] = useState(false)
  const [editingId, setEditingId] = useState<string | null>(null)
  const [form, setForm] = useState<RequirementFormData>(emptyForm)

  const openCreate = () => {
    setEditingId(null)
    setForm(emptyForm)
    setDialogOpen(true)
  }

  const openEdit = (req: typeof requirements[number]) => {
    setEditingId(req.id)
    setForm({
      name: req.name,
      description: req.description || '',
      acceptedMimeTypes: req.acceptedMimeTypes,
      maxSizeMB: req.maxSizeMB?.toString() || '',
      isRequired: req.isRequired,
    })
    setDialogOpen(true)
  }

  const handleSave = async () => {
    if (!form.name.trim()) {
      toast.error('Name is required')
      return
    }

    const maxSizeMB = form.maxSizeMB ? parseInt(form.maxSizeMB) : undefined

    if (editingId) {
      await updateMutation.mutateAsync({
        id: editingId,
        name: form.name.trim(),
        description: form.description.trim() || null,
        acceptedMimeTypes: form.acceptedMimeTypes,
        maxSizeMB: maxSizeMB || null,
        isRequired: form.isRequired,
      })
    } else {
      await createMutation.mutateAsync({
        roundId,
        name: form.name.trim(),
        description: form.description.trim() || undefined,
        acceptedMimeTypes: form.acceptedMimeTypes,
        maxSizeMB,
        isRequired: form.isRequired,
        sortOrder: requirements.length,
      })
    }

    setDialogOpen(false)
  }

  const handleDelete = async (id: string) => {
    await deleteMutation.mutateAsync({ id })
  }

  const handleMove = async (index: number, direction: 'up' | 'down') => {
    const newOrder = [...requirements]
    const swapIndex = direction === 'up' ? index - 1 : index + 1
    if (swapIndex < 0 || swapIndex >= newOrder.length) return
    ;[newOrder[index], newOrder[swapIndex]] = [newOrder[swapIndex], newOrder[index]]
    await reorderMutation.mutateAsync({
      roundId,
      orderedIds: newOrder.map((r) => r.id),
    })
  }

  const toggleMimeType = (mime: string) => {
    setForm((prev) => ({
      ...prev,
      acceptedMimeTypes: prev.acceptedMimeTypes.includes(mime)
        ? prev.acceptedMimeTypes.filter((m) => m !== mime)
        : [...prev.acceptedMimeTypes, mime],
    }))
  }

  const isSaving = createMutation.isPending || updateMutation.isPending

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center justify-between">
          <div>
            <CardTitle className="flex items-center gap-2">
              <FileText className="h-5 w-5" />
              File Requirements
            </CardTitle>
            <CardDescription>
              Define required files applicants must upload for this round
            </CardDescription>
          </div>
          <Button onClick={openCreate} size="sm">
            <Plus className="mr-1 h-4 w-4" />
            Add Requirement
          </Button>
        </div>
      </CardHeader>
      <CardContent>
        {isLoading ? (
          <div className="flex items-center justify-center py-8">
            <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
          </div>
        ) : requirements.length === 0 ? (
          <div className="text-center py-8 text-muted-foreground">
            No file requirements defined. Applicants can still upload files freely.
          </div>
        ) : (
          <div className="space-y-2">
            {requirements.map((req, index) => (
              <div
                key={req.id}
                className="flex items-center gap-3 rounded-lg border p-3 bg-background"
              >
                <div className="flex flex-col gap-0.5">
                  <Button
                    variant="ghost"
                    size="icon"
                    className="h-6 w-6"
                    onClick={() => handleMove(index, 'up')}
                    disabled={index === 0}
                  >
                    <ArrowUp className="h-3 w-3" />
                  </Button>
                  <Button
                    variant="ghost"
                    size="icon"
                    className="h-6 w-6"
                    onClick={() => handleMove(index, 'down')}
                    disabled={index === requirements.length - 1}
                  >
                    <ArrowDown className="h-3 w-3" />
                  </Button>
                </div>
                <GripVertical className="h-4 w-4 text-muted-foreground shrink-0" />
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 mb-1">
                    <span className="font-medium truncate">{req.name}</span>
                    <Badge variant={req.isRequired ? 'destructive' : 'secondary'} className="text-xs shrink-0">
                      {req.isRequired ? 'Required' : 'Optional'}
                    </Badge>
                  </div>
                  {req.description && (
                    <p className="text-sm text-muted-foreground line-clamp-1">{req.description}</p>
                  )}
                  <div className="flex flex-wrap gap-1 mt-1">
                    {req.acceptedMimeTypes.map((mime) => (
                      <Badge key={mime} variant="outline" className="text-xs">
                        {getMimeLabel(mime)}
                      </Badge>
                    ))}
                    {req.maxSizeMB && (
                      <Badge variant="outline" className="text-xs">
                        Max {req.maxSizeMB}MB
                      </Badge>
                    )}
                  </div>
                </div>
                <div className="flex items-center gap-1 shrink-0">
                  <Button variant="ghost" size="icon" className="h-8 w-8" onClick={() => openEdit(req)}>
                    <Pencil className="h-4 w-4" />
                  </Button>
                  <Button
                    variant="ghost"
                    size="icon"
                    className="h-8 w-8 text-destructive hover:text-destructive"
                    onClick={() => handleDelete(req.id)}
                    disabled={deleteMutation.isPending}
                  >
                    <Trash2 className="h-4 w-4" />
                  </Button>
                </div>
              </div>
            ))}
          </div>
        )}
      </CardContent>

      {/* Create/Edit Dialog */}
      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>{editingId ? 'Edit' : 'Add'} File Requirement</DialogTitle>
            <DialogDescription>
              Define what file applicants need to upload for this round.
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="req-name">Name *</Label>
              <Input
                id="req-name"
                value={form.name}
                onChange={(e) => setForm((p) => ({ ...p, name: e.target.value }))}
                placeholder="e.g., Executive Summary"
              />
            </div>

            <div className="space-y-2">
              <Label htmlFor="req-desc">Description</Label>
              <Textarea
                id="req-desc"
                value={form.description}
                onChange={(e) => setForm((p) => ({ ...p, description: e.target.value }))}
                placeholder="Describe what this file should contain..."
                rows={3}
              />
            </div>

            <div className="space-y-2">
              <Label>Accepted File Types</Label>
              <div className="flex flex-wrap gap-2">
                {MIME_TYPE_PRESETS.map((preset) => (
                  <Badge
                    key={preset.value}
                    variant={form.acceptedMimeTypes.includes(preset.value) ? 'default' : 'outline'}
                    className="cursor-pointer"
                    onClick={() => toggleMimeType(preset.value)}
                  >
                    {preset.label}
                  </Badge>
                ))}
              </div>
              <p className="text-xs text-muted-foreground">
                Leave empty to accept any file type
              </p>
            </div>

            <div className="space-y-2">
              <Label htmlFor="req-size">Max File Size (MB)</Label>
              <Input
                id="req-size"
                type="number"
                value={form.maxSizeMB}
                onChange={(e) => setForm((p) => ({ ...p, maxSizeMB: e.target.value }))}
                placeholder="No limit"
                min={1}
                max={5000}
              />
            </div>

            <div className="flex items-center justify-between">
              <div>
                <Label htmlFor="req-required">Required</Label>
                <p className="text-xs text-muted-foreground">
                  Applicants must upload this file
                </p>
              </div>
              <Switch
                id="req-required"
                checked={form.isRequired}
                onCheckedChange={(checked) => setForm((p) => ({ ...p, isRequired: checked }))}
              />
            </div>
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={() => setDialogOpen(false)}>
              Cancel
            </Button>
            <Button onClick={handleSave} disabled={isSaving}>
              {isSaving && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
              {editingId ? 'Update' : 'Create'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </Card>
  )
}
