'use client'

import { useCallback, useEffect, useState } from 'react'
import { useParams, useRouter } from 'next/navigation'
import dynamic from 'next/dynamic'
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 { Switch } from '@/components/ui/switch'
import { Checkbox } from '@/components/ui/checkbox'
import { Separator } from '@/components/ui/separator'
import { Skeleton } from '@/components/ui/skeleton'
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from '@/components/ui/sheet'
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from '@/components/ui/alert-dialog'
import { toast } from 'sonner'
import {
  ArrowLeft,
  Save,
  Loader2,
  Settings,
  Eye,
  Trash2,
  AlertCircle,
} from 'lucide-react'

// Dynamically import editors to avoid SSR issues
const BlockEditor = dynamic(
  () => import('@/components/shared/block-editor').then((mod) => mod.BlockEditor),
  {
    ssr: false,
    loading: () => (
      <div className="mx-auto max-w-3xl min-h-[300px] rounded-lg border bg-muted/20 animate-pulse" />
    ),
  }
)

const ResourceRenderer = dynamic(
  () => import('@/components/shared/resource-renderer').then((mod) => mod.ResourceRenderer),
  {
    ssr: false,
    loading: () => (
      <div className="mx-auto max-w-3xl min-h-[200px] rounded-lg border bg-muted/20 animate-pulse" />
    ),
  }
)

const ROLE_OPTIONS = [
  { value: 'JURY_MEMBER', label: 'Jury Members' },
  { value: 'MENTOR', label: 'Mentors' },
  { value: 'OBSERVER', label: 'Observers' },
  { value: 'APPLICANT', label: 'Applicants' },
]

type AccessRule =
  | { type: 'everyone' }
  | { type: 'roles'; roles: string[] }
  | { type: 'jury_group'; juryGroupIds: string[] }
  | { type: 'round'; roundIds: string[] }

function parseAccessJson(accessJson: unknown): { mode: 'everyone' | 'roles'; roles: string[] } {
  if (!accessJson || !Array.isArray(accessJson) || accessJson.length === 0) {
    return { mode: 'everyone', roles: [] }
  }
  const firstRule = accessJson[0] as AccessRule
  if (firstRule.type === 'roles' && 'roles' in firstRule) {
    return { mode: 'roles', roles: firstRule.roles }
  }
  return { mode: 'everyone', roles: [] }
}

export default function EditLearningResourcePage() {
  const params = useParams()
  const router = useRouter()
  const resourceId = params.id as string

  // Fetch resource
  const { data: resource, isLoading, error } = trpc.learningResource.get.useQuery({ id: resourceId })
  const { data: stats } = trpc.learningResource.getStats.useQuery({ id: resourceId })

  // Form state
  const [title, setTitle] = useState('')
  const [description, setDescription] = useState('')
  const [contentJson, setContentJson] = useState<string>('')
  const [externalUrl, setExternalUrl] = useState('')
  const [isPublished, setIsPublished] = useState(false)
  const [programId, setProgramId] = useState<string | null>(null)
  const [previewing, setPreviewing] = useState(false)

  // Access rules state
  const [accessMode, setAccessMode] = useState<'everyone' | 'roles'>('everyone')
  const [selectedRoles, setSelectedRoles] = useState<string[]>([])

  // API
  const { data: programs } = trpc.program.list.useQuery({ status: 'ACTIVE' })
  const utils = trpc.useUtils()
  const updateResource = trpc.learningResource.update.useMutation({
    onSuccess: () => {
      utils.learningResource.get.invalidate({ id: resourceId })
      utils.learningResource.list.invalidate()
    },
  })
  const deleteResource = trpc.learningResource.delete.useMutation({
    onSuccess: () => utils.learningResource.list.invalidate(),
  })
  const getUploadUrl = trpc.learningResource.getUploadUrl.useMutation()

  // Populate form when resource loads
  useEffect(() => {
    if (resource) {
      setTitle(resource.title)
      setDescription(resource.description || '')
      setContentJson(resource.contentJson ? JSON.stringify(resource.contentJson) : '')
      setExternalUrl(resource.externalUrl || '')
      setIsPublished(resource.isPublished)
      setProgramId(resource.programId)

      const { mode, roles } = parseAccessJson(resource.accessJson)
      setAccessMode(mode)
      setSelectedRoles(roles)
    }
  }, [resource])

  // Handle file upload for BlockNote
  const handleUploadFile = async (file: File): Promise<string> => {
    try {
      const { url, bucket, objectKey } = await getUploadUrl.mutateAsync({
        fileName: file.name,
        mimeType: file.type,
      })

      await fetch(url, {
        method: 'PUT',
        body: file,
        headers: { 'Content-Type': file.type },
      })

      const minioEndpoint = process.env.NEXT_PUBLIC_MINIO_ENDPOINT || 'http://localhost:9000'
      return `${minioEndpoint}/${bucket}/${objectKey}`
    } catch {
      toast.error('Failed to upload file')
      throw new Error('Upload failed')
    }
  }

  const buildAccessJson = (): AccessRule[] | null => {
    if (accessMode === 'everyone') return null
    if (accessMode === 'roles' && selectedRoles.length > 0) {
      return [{ type: 'roles', roles: selectedRoles }]
    }
    return null
  }

  const handleSubmit = useCallback(async () => {
    if (!title.trim()) {
      toast.error('Please enter a title')
      return
    }

    try {
      await updateResource.mutateAsync({
        id: resourceId,
        programId,
        title,
        description: description || null,
        contentJson: contentJson ? JSON.parse(contentJson) : undefined,
        accessJson: buildAccessJson(),
        externalUrl: externalUrl || null,
        isPublished,
      })

      toast.success('Resource updated')
    } catch (error) {
      toast.error(error instanceof Error ? error.message : 'Failed to update resource')
    }
  }, [title, description, contentJson, externalUrl, isPublished, programId, accessMode, selectedRoles, resourceId])

  const handleDelete = async () => {
    try {
      await deleteResource.mutateAsync({ id: resourceId })
      toast.success('Resource deleted')
      router.push('/admin/learning')
    } catch (error) {
      toast.error(error instanceof Error ? error.message : 'Failed to delete resource')
    }
  }

  // Ctrl+S save
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if ((e.ctrlKey || e.metaKey) && e.key === 's') {
        e.preventDefault()
        handleSubmit()
      }
    }
    window.addEventListener('keydown', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [handleSubmit])

  if (isLoading) {
    return (
      <div className="flex min-h-screen flex-col">
        <div className="sticky top-0 z-30 flex items-center justify-between border-b bg-background/95 px-4 py-2">
          <Skeleton className="h-8 w-20" />
          <div className="flex gap-2">
            <Skeleton className="h-8 w-20" />
            <Skeleton className="h-8 w-20" />
            <Skeleton className="h-8 w-16" />
          </div>
        </div>
        <div className="flex-1 px-4 py-8">
          <div className="mx-auto max-w-3xl space-y-4">
            <Skeleton className="h-10 w-2/3" />
            <Skeleton className="h-6 w-1/3" />
            <Skeleton className="h-px w-full" />
            <Skeleton className="h-96 w-full" />
          </div>
        </div>
      </div>
    )
  }

  if (error || !resource) {
    return (
      <div className="space-y-6 p-6">
        <Alert variant="destructive">
          <AlertCircle className="h-4 w-4" />
          <AlertTitle>Resource not found</AlertTitle>
          <AlertDescription>
            The resource you&apos;re looking for does not exist.
          </AlertDescription>
        </Alert>
        <Button onClick={() => router.back()}>
          <ArrowLeft className="mr-2 h-4 w-4" />
          Back
        </Button>
      </div>
    )
  }

  return (
    <div className="flex min-h-screen flex-col">
      {/* Sticky toolbar */}
      <div className="sticky top-0 z-30 flex items-center justify-between border-b bg-background/95 px-4 py-2 backdrop-blur supports-[backdrop-filter]:bg-background/60">
        <Button variant="ghost" size="sm" onClick={() => router.back()}>
          <ArrowLeft className="mr-2 h-4 w-4" />
          Back
        </Button>

        <div className="flex items-center gap-2">
          <Button
            variant={previewing ? 'default' : 'outline'}
            size="sm"
            onClick={() => setPreviewing(!previewing)}
          >
            <Eye className="mr-2 h-4 w-4" />
            {previewing ? 'Edit' : 'Preview'}
          </Button>

          <Sheet>
            <SheetTrigger asChild>
              <Button variant="outline" size="sm">
                <Settings className="mr-2 h-4 w-4" />
                Settings
              </Button>
            </SheetTrigger>
            <SheetContent className="overflow-y-auto">
              <SheetHeader>
                <SheetTitle>Resource Settings</SheetTitle>
                <SheetDescription>
                  Configure publishing, access, and metadata
                </SheetDescription>
              </SheetHeader>

              <div className="mt-6 space-y-6">
                {/* Publish toggle */}
                <div className="flex items-center justify-between">
                  <div>
                    <Label>Published</Label>
                    <p className="text-sm text-muted-foreground">
                      Make visible to users
                    </p>
                  </div>
                  <Switch
                    checked={isPublished}
                    onCheckedChange={setIsPublished}
                  />
                </div>

                <Separator />

                {/* Program */}
                <div className="space-y-2">
                  <Label>Program</Label>
                  <Select
                    value={programId || 'global'}
                    onValueChange={(v) => setProgramId(v === 'global' ? null : v)}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="Select program" />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="global">Global (All Programs)</SelectItem>
                      {programs?.map((program) => (
                        <SelectItem key={program.id} value={program.id}>
                          {program.year} Edition
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>

                <Separator />

                {/* Access Rules */}
                <div className="space-y-3">
                  <Label>Access Rules</Label>
                  <Select value={accessMode} onValueChange={(v) => setAccessMode(v as 'everyone' | 'roles')}>
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="everyone">Everyone</SelectItem>
                      <SelectItem value="roles">By Role</SelectItem>
                    </SelectContent>
                  </Select>

                  {accessMode === 'roles' && (
                    <div className="space-y-2 rounded-lg border p-3">
                      {ROLE_OPTIONS.map((role) => (
                        <label key={role.value} className="flex items-center gap-2 text-sm">
                          <Checkbox
                            checked={selectedRoles.includes(role.value)}
                            onCheckedChange={(checked) => {
                              setSelectedRoles(
                                checked
                                  ? [...selectedRoles, role.value]
                                  : selectedRoles.filter((r) => r !== role.value)
                              )
                            }}
                          />
                          {role.label}
                        </label>
                      ))}
                    </div>
                  )}
                </div>

                <Separator />

                {/* External URL */}
                <div className="space-y-2">
                  <Label>External URL</Label>
                  <Input
                    type="url"
                    value={externalUrl}
                    onChange={(e) => setExternalUrl(e.target.value)}
                    placeholder="https://example.com/resource"
                  />
                  <p className="text-xs text-muted-foreground">
                    Optional link to an external resource
                  </p>
                </div>

                <Separator />

                {/* Statistics */}
                {stats && (
                  <div className="space-y-2">
                    <Label>Statistics</Label>
                    <div className="grid grid-cols-2 gap-4 rounded-lg border p-3">
                      <div>
                        <p className="text-2xl font-semibold">{stats.totalViews}</p>
                        <p className="text-xs text-muted-foreground">Total views</p>
                      </div>
                      <div>
                        <p className="text-2xl font-semibold">{stats.uniqueUsers}</p>
                        <p className="text-xs text-muted-foreground">Unique users</p>
                      </div>
                    </div>
                  </div>
                )}

                <Separator />

                {/* Danger Zone */}
                <div className="space-y-2">
                  <Label className="text-destructive">Danger Zone</Label>
                  <AlertDialog>
                    <AlertDialogTrigger asChild>
                      <Button
                        variant="outline"
                        size="sm"
                        className="w-full text-destructive hover:bg-destructive hover:text-destructive-foreground"
                      >
                        <Trash2 className="mr-2 h-4 w-4" />
                        Delete Resource
                      </Button>
                    </AlertDialogTrigger>
                    <AlertDialogContent>
                      <AlertDialogHeader>
                        <AlertDialogTitle>Delete Resource</AlertDialogTitle>
                        <AlertDialogDescription>
                          Are you sure you want to delete &quot;{resource.title}&quot;?
                          This action cannot be undone.
                        </AlertDialogDescription>
                      </AlertDialogHeader>
                      <AlertDialogFooter>
                        <AlertDialogCancel>Cancel</AlertDialogCancel>
                        <AlertDialogAction
                          onClick={handleDelete}
                          className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
                        >
                          {deleteResource.isPending ? (
                            <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                          ) : null}
                          Delete
                        </AlertDialogAction>
                      </AlertDialogFooter>
                    </AlertDialogContent>
                  </AlertDialog>
                </div>
              </div>
            </SheetContent>
          </Sheet>

          <Button
            size="sm"
            onClick={handleSubmit}
            disabled={updateResource.isPending || !title.trim()}
          >
            {updateResource.isPending ? (
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
            ) : (
              <Save className="mr-2 h-4 w-4" />
            )}
            Save
          </Button>
        </div>
      </div>

      {/* Content area */}
      <div className="flex-1 px-4 py-8">
        {previewing ? (
          <ResourceRenderer
            title={title || 'Untitled'}
            description={description || null}
            contentJson={contentJson ? JSON.parse(contentJson) : null}
          />
        ) : (
          <div className="mx-auto max-w-3xl space-y-4">
            {/* Inline title */}
            <input
              type="text"
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              placeholder="Untitled"
              className="w-full border-0 bg-transparent text-3xl font-bold tracking-tight text-foreground placeholder:text-muted-foreground/40 focus:outline-none sm:text-4xl"
            />

            {/* Inline description */}
            <input
              type="text"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="Add a description..."
              className="w-full border-0 bg-transparent text-lg text-muted-foreground placeholder:text-muted-foreground/30 focus:outline-none"
            />

            {/* Divider */}
            <hr className="border-border" />

            {/* Block editor */}
            <BlockEditor
              key={resourceId}
              initialContent={contentJson || undefined}
              onChange={setContentJson}
              onUploadFile={handleUploadFile}
              className="min-h-[400px]"
            />
          </div>
        )}
      </div>
    </div>
  )
}
