'use client'

import { useState } from 'react'
import { useRouter } from 'next/navigation'
import { trpc } from '@/lib/trpc/client'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Badge } from '@/components/ui/badge'
import { Skeleton } from '@/components/ui/skeleton'
import { Switch } from '@/components/ui/switch'
import { Checkbox } from '@/components/ui/checkbox'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/components/ui/dialog'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog'
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from '@/components/ui/collapsible'
import {
  ArrowLeft,
  Plus,
  Pencil,
  Trash2,
  Loader2,
  Webhook,
  Send,
  ChevronDown,
  ChevronUp,
  Copy,
  Eye,
  EyeOff,
  RefreshCw,
  CheckCircle2,
  XCircle,
} from 'lucide-react'
import { toast } from 'sonner'
import { formatDate } from '@/lib/utils'

interface WebhookFormData {
  name: string
  url: string
  events: string[]
  headers: Array<{ key: string; value: string }>
  maxRetries: number
}

const defaultForm: WebhookFormData = {
  name: '',
  url: '',
  events: [],
  headers: [],
  maxRetries: 3,
}

export default function WebhooksPage() {
  const router = useRouter()
  const [dialogOpen, setDialogOpen] = useState(false)
  const [editingId, setEditingId] = useState<string | null>(null)
  const [deleteId, setDeleteId] = useState<string | null>(null)
  const [formData, setFormData] = useState<WebhookFormData>(defaultForm)
  const [expandedWebhook, setExpandedWebhook] = useState<string | null>(null)
  const [revealedSecrets, setRevealedSecrets] = useState<Set<string>>(new Set())
  const [deliveryPage, setDeliveryPage] = useState(1)

  const utils = trpc.useUtils()

  const { data: webhooks, isLoading } = trpc.webhook.list.useQuery()
  const { data: availableEvents } = trpc.webhook.getAvailableEvents.useQuery()

  const { data: deliveryLog, isLoading: loadingDeliveries } =
    trpc.webhook.getDeliveryLog.useQuery(
      { webhookId: expandedWebhook!, page: deliveryPage, pageSize: 10 },
      { enabled: !!expandedWebhook }
    )

  const createMutation = trpc.webhook.create.useMutation({
    onSuccess: () => {
      utils.webhook.list.invalidate()
      toast.success('Webhook created')
      closeDialog()
    },
    onError: (e) => toast.error(e.message),
  })

  const updateMutation = trpc.webhook.update.useMutation({
    onSuccess: () => {
      utils.webhook.list.invalidate()
      toast.success('Webhook updated')
      closeDialog()
    },
    onError: (e) => toast.error(e.message),
  })

  const deleteMutation = trpc.webhook.delete.useMutation({
    onSuccess: () => {
      utils.webhook.list.invalidate()
      toast.success('Webhook deleted')
      setDeleteId(null)
    },
    onError: (e) => toast.error(e.message),
  })

  const testMutation = trpc.webhook.test.useMutation({
    onSuccess: (data) => {
      const status = (data as Record<string, unknown>)?.status
      if (status === 'DELIVERED') {
        toast.success('Test webhook delivered successfully')
      } else {
        toast.error(`Test delivery status: ${String(status || 'unknown')}`)
      }
    },
    onError: (e) => toast.error(e.message),
  })

  const regenerateSecretMutation = trpc.webhook.regenerateSecret.useMutation({
    onSuccess: () => {
      utils.webhook.list.invalidate()
      toast.success('Secret regenerated')
    },
    onError: (e) => toast.error(e.message),
  })

  const closeDialog = () => {
    setDialogOpen(false)
    setEditingId(null)
    setFormData(defaultForm)
  }

  const openEdit = (webhook: Record<string, unknown>) => {
    setEditingId(String(webhook.id))
    const headers = webhook.headers as Array<{ key: string; value: string }> | undefined
    setFormData({
      name: String(webhook.name || ''),
      url: String(webhook.url || ''),
      events: Array.isArray(webhook.events) ? webhook.events.map(String) : [],
      headers: Array.isArray(headers) ? headers : [],
      maxRetries: Number(webhook.maxRetries || 3),
    })
    setDialogOpen(true)
  }

  const toggleEvent = (event: string) => {
    setFormData((prev) => ({
      ...prev,
      events: prev.events.includes(event)
        ? prev.events.filter((e) => e !== event)
        : [...prev.events, event],
    }))
  }

  const addHeader = () => {
    setFormData((prev) => ({
      ...prev,
      headers: [...prev.headers, { key: '', value: '' }],
    }))
  }

  const removeHeader = (index: number) => {
    setFormData((prev) => ({
      ...prev,
      headers: prev.headers.filter((_, i) => i !== index),
    }))
  }

  const updateHeader = (index: number, field: 'key' | 'value', value: string) => {
    setFormData((prev) => ({
      ...prev,
      headers: prev.headers.map((h, i) =>
        i === index ? { ...h, [field]: value } : h
      ),
    }))
  }

  const handleSubmit = () => {
    if (!formData.name || !formData.url || formData.events.length === 0) {
      toast.error('Please fill in name, URL, and select at least one event')
      return
    }

    const filteredHeaders = formData.headers.filter((h) => h.key)
    const headersRecord = filteredHeaders.length > 0
      ? Object.fromEntries(filteredHeaders.map((h) => [h.key, h.value]))
      : undefined

    const payload = {
      name: formData.name,
      url: formData.url,
      events: formData.events,
      headers: headersRecord,
      maxRetries: formData.maxRetries,
    }

    if (editingId) {
      updateMutation.mutate({ id: editingId, ...payload })
    } else {
      createMutation.mutate(payload)
    }
  }

  const copySecret = (secret: string) => {
    navigator.clipboard.writeText(secret)
    toast.success('Secret copied to clipboard')
  }

  const toggleSecretVisibility = (id: string) => {
    setRevealedSecrets((prev) => {
      const next = new Set(prev)
      if (next.has(id)) next.delete(id)
      else next.add(id)
      return next
    })
  }

  const toggleDeliveryLog = (webhookId: string) => {
    if (expandedWebhook === webhookId) {
      setExpandedWebhook(null)
    } else {
      setExpandedWebhook(webhookId)
      setDeliveryPage(1)
    }
  }

  const events = availableEvents || []
  const isPending = createMutation.isPending || updateMutation.isPending

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center gap-4">
        <Button variant="ghost" className="-ml-4" onClick={() => router.back()}>
          <ArrowLeft className="mr-2 h-4 w-4" />
          Back
        </Button>
      </div>

      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-semibold tracking-tight">Webhooks</h1>
          <p className="text-muted-foreground">
            Configure webhook endpoints for platform events
          </p>
        </div>
        <Dialog open={dialogOpen} onOpenChange={(open) => !open && closeDialog()}>
          <DialogTrigger asChild>
            <Button onClick={() => { setFormData(defaultForm); setEditingId(null); setDialogOpen(true) }}>
              <Plus className="mr-2 h-4 w-4" />
              Add Webhook
            </Button>
          </DialogTrigger>
          <DialogContent className="max-w-lg max-h-[90vh] overflow-y-auto">
            <DialogHeader>
              <DialogTitle>{editingId ? 'Edit Webhook' : 'Add Webhook'}</DialogTitle>
              <DialogDescription>
                Configure a webhook endpoint to receive platform events.
              </DialogDescription>
            </DialogHeader>

            <div className="space-y-4">
              <div className="space-y-2">
                <Label>Name</Label>
                <Input
                  placeholder="e.g., Slack Notifications"
                  value={formData.name}
                  onChange={(e) => setFormData({ ...formData, name: e.target.value })}
                />
              </div>

              <div className="space-y-2">
                <Label>URL</Label>
                <Input
                  placeholder="https://example.com/webhook"
                  type="url"
                  value={formData.url}
                  onChange={(e) => setFormData({ ...formData, url: e.target.value })}
                />
              </div>

              <div className="space-y-2">
                <Label>Events</Label>
                <div className="grid gap-2 sm:grid-cols-2">
                  {(events as string[]).map((event) => (
                    <div key={event} className="flex items-center gap-2">
                      <Checkbox
                        id={`event-${event}`}
                        checked={formData.events.includes(event)}
                        onCheckedChange={() => toggleEvent(event)}
                      />
                      <label
                        htmlFor={`event-${event}`}
                        className="text-sm cursor-pointer"
                      >
                        {event}
                      </label>
                    </div>
                  ))}
                </div>
              </div>

              <div className="space-y-2">
                <div className="flex items-center justify-between">
                  <Label>Custom Headers</Label>
                  <Button variant="outline" size="sm" onClick={addHeader}>
                    <Plus className="mr-1 h-3 w-3" />
                    Add
                  </Button>
                </div>
                {formData.headers.map((header, i) => (
                  <div key={i} className="flex gap-2">
                    <Input
                      placeholder="Header name"
                      value={header.key}
                      onChange={(e) => updateHeader(i, 'key', e.target.value)}
                      className="flex-1"
                    />
                    <Input
                      placeholder="Value"
                      value={header.value}
                      onChange={(e) => updateHeader(i, 'value', e.target.value)}
                      className="flex-1"
                    />
                    <Button
                      variant="ghost"
                      size="icon"
                      onClick={() => removeHeader(i)}
                    >
                      <Trash2 className="h-4 w-4" />
                    </Button>
                  </div>
                ))}
              </div>

              <div className="space-y-2">
                <Label>Max Retries</Label>
                <Input
                  type="number"
                  min={0}
                  max={10}
                  value={formData.maxRetries}
                  onChange={(e) =>
                    setFormData({ ...formData, maxRetries: parseInt(e.target.value) || 0 })
                  }
                />
              </div>

              {editingId && (
                <div className="flex items-center gap-2">
                  <Switch
                    id="webhook-active"
                    checked={
                      (webhooks as Array<Record<string, unknown>> | undefined)?.find(
                        (w) => String(w.id) === editingId
                      )?.isActive !== false
                    }
                    onCheckedChange={(checked) => {
                      updateMutation.mutate({ id: editingId, isActive: checked })
                    }}
                  />
                  <label htmlFor="webhook-active" className="text-sm cursor-pointer">
                    Active
                  </label>
                </div>
              )}
            </div>

            <DialogFooter>
              <Button variant="outline" onClick={closeDialog}>
                Cancel
              </Button>
              <Button onClick={handleSubmit} disabled={isPending}>
                {isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
                {editingId ? 'Update' : 'Create'}
              </Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
      </div>

      {/* Webhooks list */}
      {isLoading ? (
        <WebhooksSkeleton />
      ) : webhooks && (webhooks as unknown[]).length > 0 ? (
        <div className="space-y-4">
          {(webhooks as Array<Record<string, unknown>>).map((webhook) => {
            const webhookId = String(webhook.id)
            const webhookEvents = Array.isArray(webhook.events) ? webhook.events : []
            const isActive = Boolean(webhook.isActive)
            const secret = String(webhook.secret || '')
            const isRevealed = revealedSecrets.has(webhookId)
            const isExpanded = expandedWebhook === webhookId
            const recentDelivered = Number(webhook.recentDelivered || 0)
            const recentFailed = Number(webhook.recentFailed || 0)
            const deliveryCount = webhook._count
              ? Number((webhook._count as Record<string, unknown>).deliveries || 0)
              : 0

            return (
              <Card key={webhookId}>
                <CardHeader>
                  <div className="flex items-start justify-between">
                    <div className="space-y-1">
                      <CardTitle className="text-lg flex items-center gap-2">
                        {String(webhook.name)}
                        {isActive ? (
                          <Badge variant="default" className="text-xs">Active</Badge>
                        ) : (
                          <Badge variant="secondary" className="text-xs">Inactive</Badge>
                        )}
                      </CardTitle>
                      <CardDescription className="font-mono text-xs break-all max-w-md truncate">
                        {String(webhook.url)}
                      </CardDescription>
                    </div>
                    <div className="flex items-center gap-4 text-sm text-muted-foreground">
                      <span>{webhookEvents.length} events</span>
                      <div className="flex items-center gap-2">
                        <span className="flex items-center gap-1">
                          <CheckCircle2 className="h-3 w-3 text-green-500" />
                          {recentDelivered}
                        </span>
                        <span className="flex items-center gap-1">
                          <XCircle className="h-3 w-3 text-destructive" />
                          {recentFailed}
                        </span>
                      </div>
                    </div>
                  </div>
                </CardHeader>
                <CardContent className="space-y-4">
                  {/* Events */}
                  <div className="flex flex-wrap gap-1">
                    {webhookEvents.map((event: unknown) => (
                      <Badge key={String(event)} variant="outline" className="text-xs">
                        {String(event)}
                      </Badge>
                    ))}
                  </div>

                  {/* Secret */}
                  {secret && (
                    <div className="flex items-center gap-2">
                      <span className="text-xs text-muted-foreground">Secret:</span>
                      <code className="text-xs bg-muted rounded px-2 py-1 font-mono">
                        {isRevealed ? secret : '****************************'}
                      </code>
                      <Button
                        variant="ghost"
                        size="icon"
                        className="h-6 w-6"
                        onClick={() => toggleSecretVisibility(webhookId)}
                      >
                        {isRevealed ? <EyeOff className="h-3 w-3" /> : <Eye className="h-3 w-3" />}
                      </Button>
                      <Button
                        variant="ghost"
                        size="icon"
                        className="h-6 w-6"
                        onClick={() => copySecret(secret)}
                      >
                        <Copy className="h-3 w-3" />
                      </Button>
                    </div>
                  )}

                  {/* Actions */}
                  <div className="flex items-center gap-2 flex-wrap">
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => testMutation.mutate({ id: webhookId })}
                      disabled={testMutation.isPending}
                    >
                      {testMutation.isPending ? (
                        <Loader2 className="mr-2 h-3 w-3 animate-spin" />
                      ) : (
                        <Send className="mr-2 h-3 w-3" />
                      )}
                      Test
                    </Button>
                    <Button variant="outline" size="sm" onClick={() => openEdit(webhook)}>
                      <Pencil className="mr-2 h-3 w-3" />
                      Edit
                    </Button>
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => regenerateSecretMutation.mutate({ id: webhookId })}
                      disabled={regenerateSecretMutation.isPending}
                    >
                      <RefreshCw className="mr-2 h-3 w-3" />
                      Regenerate Secret
                    </Button>
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => setDeleteId(webhookId)}
                      className="text-destructive hover:text-destructive"
                    >
                      <Trash2 className="mr-2 h-3 w-3" />
                      Delete
                    </Button>
                  </div>

                  {/* Delivery log */}
                  {deliveryCount > 0 && (
                    <Collapsible
                      open={isExpanded}
                      onOpenChange={() => toggleDeliveryLog(webhookId)}
                    >
                      <CollapsibleTrigger asChild>
                        <Button variant="ghost" size="sm" className="w-full justify-between">
                          <span>Delivery Log ({deliveryCount})</span>
                          {isExpanded ? (
                            <ChevronUp className="h-4 w-4" />
                          ) : (
                            <ChevronDown className="h-4 w-4" />
                          )}
                        </Button>
                      </CollapsibleTrigger>
                      <CollapsibleContent>
                        <div className="mt-2 rounded-lg border overflow-hidden">
                          {loadingDeliveries ? (
                            <div className="p-4 space-y-2">
                              {[1, 2, 3].map((i) => (
                                <Skeleton key={i} className="h-8 w-full" />
                              ))}
                            </div>
                          ) : deliveryLog && deliveryLog.items.length > 0 ? (
                            <>
                              <Table>
                                <TableHeader>
                                  <TableRow>
                                    <TableHead>Timestamp</TableHead>
                                    <TableHead>Event</TableHead>
                                    <TableHead>Status</TableHead>
                                    <TableHead>Response</TableHead>
                                    <TableHead>Attempts</TableHead>
                                  </TableRow>
                                </TableHeader>
                                <TableBody>
                                  {(deliveryLog.items as Array<Record<string, unknown>>).map(
                                    (delivery, i) => (
                                      <TableRow key={i}>
                                        <TableCell className="font-mono text-xs">
                                          {delivery.createdAt
                                            ? formatDate(delivery.createdAt as string | Date)
                                            : ''}
                                        </TableCell>
                                        <TableCell className="text-xs">
                                          {String(delivery.event || '')}
                                        </TableCell>
                                        <TableCell>
                                          {delivery.status === 'DELIVERED' ? (
                                            <Badge variant="default" className="text-xs gap-1">
                                              <CheckCircle2 className="h-3 w-3" />
                                              OK
                                            </Badge>
                                          ) : delivery.status === 'PENDING' ? (
                                            <Badge variant="secondary" className="text-xs gap-1">
                                              Pending
                                            </Badge>
                                          ) : (
                                            <Badge variant="destructive" className="text-xs gap-1">
                                              <XCircle className="h-3 w-3" />
                                              Failed
                                            </Badge>
                                          )}
                                        </TableCell>
                                        <TableCell className="text-xs font-mono">
                                          {String(delivery.responseStatus || '-')}
                                        </TableCell>
                                        <TableCell className="text-xs">
                                          {String(delivery.attempts || 0)}
                                        </TableCell>
                                      </TableRow>
                                    )
                                  )}
                                </TableBody>
                              </Table>
                              {deliveryLog.totalPages > 1 && (
                                <div className="flex items-center justify-between p-2 border-t">
                                  <span className="text-xs text-muted-foreground">
                                    Page {deliveryLog.page} of {deliveryLog.totalPages}
                                  </span>
                                  <div className="flex gap-1">
                                    <Button
                                      variant="ghost"
                                      size="sm"
                                      disabled={deliveryPage <= 1}
                                      onClick={() => setDeliveryPage((p) => p - 1)}
                                    >
                                      Previous
                                    </Button>
                                    <Button
                                      variant="ghost"
                                      size="sm"
                                      disabled={deliveryPage >= deliveryLog.totalPages}
                                      onClick={() => setDeliveryPage((p) => p + 1)}
                                    >
                                      Next
                                    </Button>
                                  </div>
                                </div>
                              )}
                            </>
                          ) : (
                            <div className="p-4 text-center text-sm text-muted-foreground">
                              No deliveries recorded yet.
                            </div>
                          )}
                        </div>
                      </CollapsibleContent>
                    </Collapsible>
                  )}
                </CardContent>
              </Card>
            )
          })}
        </div>
      ) : (
        <Card>
          <CardContent className="flex flex-col items-center justify-center py-12 text-center">
            <Webhook className="h-12 w-12 text-muted-foreground/50" />
            <p className="mt-2 font-medium">No webhooks configured</p>
            <p className="text-sm text-muted-foreground">
              Add a webhook to receive real-time notifications about platform events.
            </p>
          </CardContent>
        </Card>
      )}

      {/* Delete confirmation */}
      <AlertDialog open={!!deleteId} onOpenChange={() => setDeleteId(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete Webhook</AlertDialogTitle>
            <AlertDialogDescription>
              Are you sure you want to delete this webhook? All delivery history will be lost.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              onClick={() => deleteId && deleteMutation.mutate({ id: deleteId })}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
            >
              {deleteMutation.isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
              Delete
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  )
}

function WebhooksSkeleton() {
  return (
    <div className="space-y-4">
      {[1, 2].map((i) => (
        <Card key={i}>
          <CardHeader>
            <Skeleton className="h-5 w-40" />
            <Skeleton className="h-4 w-64" />
          </CardHeader>
          <CardContent className="space-y-3">
            <div className="flex gap-1">
              <Skeleton className="h-5 w-24" />
              <Skeleton className="h-5 w-20" />
              <Skeleton className="h-5 w-28" />
            </div>
            <Skeleton className="h-8 w-32" />
          </CardContent>
        </Card>
      ))}
    </div>
  )
}
