'use client'

import { useState, useMemo } from 'react'
import { useDebounce } from '@/hooks/use-debounce'
import Link from 'next/link'
import { trpc } from '@/lib/trpc/client'
import { Button } from '@/components/ui/button'
import {
  Card,
  CardContent,
} from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Skeleton } from '@/components/ui/skeleton'
import { Input } from '@/components/ui/input'
import { Switch } from '@/components/ui/switch'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import {
  Plus,
  FileText,
  Pencil,
  ExternalLink,
  Search,
  GripVertical,
} from 'lucide-react'
import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  type DragEndEvent,
} from '@dnd-kit/core'
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { toast } from 'sonner'

type Resource = {
  id: string
  title: string
  description: string | null
  isPublished: boolean
  sortOrder: number
  externalUrl: string | null
  objectKey: string | null
  contentJson: unknown
  accessJson: unknown
  _count: { accessLogs: number }
  program: { id: string; name: string; year: number } | null
}

function getAccessSummary(accessJson: unknown): string {
  if (!accessJson || !Array.isArray(accessJson) || accessJson.length === 0) {
    return 'Everyone'
  }
  const rule = accessJson[0] as { type: string; roles?: string[] }
  if (rule.type === 'everyone') return 'Everyone'
  if (rule.type === 'roles' && rule.roles) {
    if (rule.roles.length === 1) return rule.roles[0].replace('_', ' ').toLowerCase()
    return `${rule.roles.length} roles`
  }
  if (rule.type === 'jury_group') return 'Jury groups'
  if (rule.type === 'round') return 'By round'
  return 'Custom'
}

function SortableResourceCard({
  resource,
  onTogglePublished,
}: {
  resource: Resource
  onTogglePublished: (id: string, published: boolean) => void
}) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: resource.id })

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
  }

  return (
    <Card
      ref={setNodeRef}
      style={style}
      className={isDragging ? 'opacity-50 shadow-lg' : ''}
    >
      <CardContent className="flex items-center gap-3 py-3">
        {/* Drag handle */}
        <button
          className="cursor-grab touch-none text-muted-foreground hover:text-foreground"
          aria-label="Drag to reorder"
          {...attributes}
          {...listeners}
        >
          <GripVertical className="h-4 w-4" />
        </button>

        {/* Icon */}
        <div className="flex h-9 w-9 items-center justify-center rounded-lg bg-muted shrink-0">
          <FileText className="h-4 w-4" />
        </div>

        {/* Title & meta */}
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2">
            <h3 className="font-medium truncate">{resource.title}</h3>
            {!resource.isPublished && (
              <Badge variant="secondary" className="text-xs">Draft</Badge>
            )}
          </div>
          <div className="flex items-center gap-2 text-xs text-muted-foreground mt-0.5">
            <span className="capitalize">{getAccessSummary(resource.accessJson)}</span>
            <span>&middot;</span>
            <span>{resource._count.accessLogs} views</span>
            {resource.program && (
              <>
                <span>&middot;</span>
                <span>{resource.program.year}</span>
              </>
            )}
          </div>
        </div>

        {/* Quick publish toggle */}
        <Switch
          checked={resource.isPublished}
          onCheckedChange={(checked) => onTogglePublished(resource.id, checked)}
          aria-label={resource.isPublished ? 'Unpublish' : 'Publish'}
        />

        {/* Actions */}
        <div className="flex items-center gap-1">
          {resource.externalUrl && (
            <a
              href={resource.externalUrl}
              target="_blank"
              rel="noopener noreferrer"
            >
              <Button variant="ghost" size="icon" className="h-8 w-8">
                <ExternalLink className="h-4 w-4" />
              </Button>
            </a>
          )}
          <Link href={`/admin/learning/${resource.id}`}>
            <Button variant="ghost" size="icon" className="h-8 w-8">
              <Pencil className="h-4 w-4" />
            </Button>
          </Link>
        </div>
      </CardContent>
    </Card>
  )
}

export default function LearningHubPage() {
  const { data, isLoading } = trpc.learningResource.list.useQuery({ perPage: 100 })
  const resources = (data?.data || []) as Resource[]

  const [search, setSearch] = useState('')
  const debouncedSearch = useDebounce(search, 300)
  const [publishedFilter, setPublishedFilter] = useState('all')

  const utils = trpc.useUtils()
  const reorderMutation = trpc.learningResource.reorder.useMutation({
    onSuccess: () => utils.learningResource.list.invalidate(),
  })
  const updateMutation = trpc.learningResource.update.useMutation({
    onSuccess: () => utils.learningResource.list.invalidate(),
  })

  const sensors = useSensors(
    useSensor(PointerSensor),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  )

  const filteredResources = useMemo(() => {
    return resources.filter((resource) => {
      const matchesSearch =
        !debouncedSearch ||
        resource.title.toLowerCase().includes(debouncedSearch.toLowerCase())
      const matchesPublished =
        publishedFilter === 'all' ||
        (publishedFilter === 'published' && resource.isPublished) ||
        (publishedFilter === 'draft' && !resource.isPublished)
      return matchesSearch && matchesPublished
    })
  }, [resources, debouncedSearch, publishedFilter])

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event
    if (!over || active.id === over.id) return

    const oldIndex = filteredResources.findIndex((r) => r.id === active.id)
    const newIndex = filteredResources.findIndex((r) => r.id === over.id)
    if (oldIndex === -1 || newIndex === -1) return

    const reordered = arrayMove(filteredResources, oldIndex, newIndex)
    const items = reordered.map((r, i) => ({ id: r.id, sortOrder: i }))

    reorderMutation.mutate({ items }, {
      onError: () => toast.error('Failed to reorder'),
    })
  }

  const handleTogglePublished = (id: string, published: boolean) => {
    updateMutation.mutate({ id, isPublished: published }, {
      onSuccess: () => toast.success(published ? 'Published' : 'Unpublished'),
      onError: () => toast.error('Failed to update'),
    })
  }

  if (isLoading) {
    return (
      <div className="space-y-6">
        <div className="flex items-center justify-between">
          <div>
            <Skeleton className="h-8 w-48" />
            <Skeleton className="mt-2 h-4 w-72" />
          </div>
          <Skeleton className="h-9 w-32" />
        </div>
        <div className="flex flex-col gap-3 sm:flex-row sm:items-center">
          <Skeleton className="h-10 flex-1" />
          <Skeleton className="h-10 w-[160px]" />
        </div>
        <div className="grid gap-3">
          {[...Array(5)].map((_, i) => (
            <Card key={i}>
              <CardContent className="flex items-center gap-4 py-4">
                <Skeleton className="h-4 w-4" />
                <Skeleton className="h-9 w-9 rounded-lg" />
                <div className="flex-1 space-y-2">
                  <Skeleton className="h-5 w-48" />
                  <Skeleton className="h-3 w-32" />
                </div>
              </CardContent>
            </Card>
          ))}
        </div>
      </div>
    )
  }

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold">Learning Hub</h1>
          <p className="text-muted-foreground">
            Manage educational resources for program participants
          </p>
        </div>
        <Link href="/admin/learning/new">
          <Button>
            <Plus className="mr-2 h-4 w-4" />
            Add Resource
          </Button>
        </Link>
      </div>

      {/* Toolbar */}
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center">
        <div className="relative flex-1">
          <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
          <Input
            placeholder="Search resources..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="pl-9"
          />
        </div>
        <Select value={publishedFilter} onValueChange={setPublishedFilter}>
          <SelectTrigger className="w-[160px]">
            <SelectValue placeholder="All" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">All</SelectItem>
            <SelectItem value="published">Published</SelectItem>
            <SelectItem value="draft">Drafts</SelectItem>
          </SelectContent>
        </Select>
      </div>

      {/* Results count */}
      {resources.length > 0 && (
        <p className="text-sm text-muted-foreground">
          {filteredResources.length} of {resources.length} resources
          {reorderMutation.isPending && ' · Saving order...'}
        </p>
      )}

      {/* Resource List with DnD */}
      {filteredResources.length > 0 ? (
        <DndContext
          sensors={sensors}
          collisionDetection={closestCenter}
          onDragEnd={handleDragEnd}
        >
          <SortableContext
            items={filteredResources.map((r) => r.id)}
            strategy={verticalListSortingStrategy}
          >
            <div className="grid gap-3">
              {filteredResources.map((resource) => (
                <SortableResourceCard
                  key={resource.id}
                  resource={resource}
                  onTogglePublished={handleTogglePublished}
                />
              ))}
            </div>
          </SortableContext>
        </DndContext>
      ) : resources.length > 0 ? (
        <Card>
          <CardContent className="flex flex-col items-center justify-center py-8 text-center">
            <Search className="h-8 w-8 text-muted-foreground/40" />
            <p className="mt-2 text-sm text-muted-foreground">
              No resources match your filters
            </p>
          </CardContent>
        </Card>
      ) : (
        <Card>
          <CardContent className="flex flex-col items-center justify-center py-12 text-center">
            <FileText className="h-12 w-12 text-muted-foreground/40" />
            <h3 className="mt-3 text-lg font-medium">No resources yet</h3>
            <p className="mt-1 text-sm text-muted-foreground max-w-sm">
              Add learning materials like videos, documents, and links for program participants.
            </p>
            <Button className="mt-4" asChild>
              <Link href="/admin/learning/new">
                <Plus className="mr-2 h-4 w-4" />
                Add Resource
              </Link>
            </Button>
          </CardContent>
        </Card>
      )}
    </div>
  )
}
