import { BellRing, MailPlus, Pencil, RefreshCcw, Save, Send, Trash2, X } from 'lucide-react'
import { startTransition, useCallback, useEffect, useMemo, useState } from 'react'
import { toast } from 'sonner'

import { Badge } from '@/components/ui/badge'
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 { Select } from '@/components/ui/select'
import { Skeleton } from '@/components/ui/skeleton'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import { Textarea } from '@/components/ui/textarea'
import { adminApi, ApiError } from '@/lib/api'
import type { NotificationDeliveryRecord, SubscriptionRecord } from '@/lib/types'

const CHANNEL_OPTIONS = [
  { value: 'email', label: 'Email' },
  { value: 'webhook', label: 'Webhook' },
  { value: 'discord', label: 'Discord Webhook' },
  { value: 'telegram', label: 'Telegram Bot API' },
  { value: 'ntfy', label: 'ntfy' },
  { value: 'web_push', label: 'Web Push / Browser Push' },
] as const

const DEFAULT_FILTERS = {
  event_types: ['post.published', 'digest.weekly', 'digest.monthly'],
}

function prettyJson(value: unknown) {
  if (!value || (typeof value === 'object' && !Array.isArray(value) && Object.keys(value as Record<string, unknown>).length === 0)) {
    return ''
  }
  return JSON.stringify(value, null, 2)
}

function emptyForm() {
  return {
    channelType: 'email',
    target: '',
    displayName: '',
    status: 'active',
    notes: '',
    filtersText: prettyJson(DEFAULT_FILTERS),
    metadataText: '',
  }
}

function parseOptionalJson(label: string, raw: string) {
  const trimmed = raw.trim()
  if (!trimmed) {
    return null
  }

  try {
    return JSON.parse(trimmed) as Record<string, unknown>
  } catch {
    throw new Error(`${label} 不是合法 JSON`)
  }
}

function normalizePreview(value: unknown) {
  const text = prettyJson(value)
  return text || '—'
}

export function SubscriptionsPage() {
  const [subscriptions, setSubscriptions] = useState<SubscriptionRecord[]>([])
  const [deliveries, setDeliveries] = useState<NotificationDeliveryRecord[]>([])
  const [loading, setLoading] = useState(true)
  const [refreshing, setRefreshing] = useState(false)
  const [submitting, setSubmitting] = useState(false)
  const [digesting, setDigesting] = useState<'weekly' | 'monthly' | null>(null)
  const [actioningId, setActioningId] = useState<number | null>(null)
  const [editingId, setEditingId] = useState<number | null>(null)
  const [form, setForm] = useState(emptyForm())

  const loadData = useCallback(async (showToast = false) => {
    try {
      if (showToast) {
        setRefreshing(true)
      }
      const [nextSubscriptions, nextDeliveries] = await Promise.all([
        adminApi.listSubscriptions(),
        adminApi.listSubscriptionDeliveries(),
      ])
      startTransition(() => {
        setSubscriptions(nextSubscriptions)
        setDeliveries(nextDeliveries)
      })
      if (showToast) {
        toast.success('订阅中心已刷新。')
      }
    } catch (error) {
      if (error instanceof ApiError && error.status === 401) {
        return
      }
      toast.error(error instanceof ApiError ? error.message : '无法加载订阅中心。')
    } finally {
      setLoading(false)
      setRefreshing(false)
    }
  }, [])

  useEffect(() => {
    void loadData(false)
  }, [loadData])

  const activeCount = useMemo(
    () => subscriptions.filter((item) => item.status === 'active').length,
    [subscriptions],
  )

  const queuedOrRetryCount = useMemo(
    () => deliveries.filter((item) => item.status === 'queued' || item.status === 'retry_pending').length,
    [deliveries],
  )

  const resetForm = useCallback(() => {
    setEditingId(null)
    setForm(emptyForm())
  }, [])

  const submitForm = useCallback(async () => {
    try {
      setSubmitting(true)
      const payload = {
        channelType: form.channelType,
        target: form.target,
        displayName: form.displayName || null,
        status: form.status,
        notes: form.notes || null,
        filters: parseOptionalJson('filters', form.filtersText),
        metadata: parseOptionalJson('metadata', form.metadataText),
      }

      if (editingId) {
        await adminApi.updateSubscription(editingId, payload)
        toast.success('订阅目标已更新。')
      } else {
        await adminApi.createSubscription(payload)
        toast.success('订阅目标已创建。')
      }

      resetForm()
      await loadData(false)
    } catch (error) {
      toast.error(error instanceof Error ? error.message : '保存订阅失败。')
    } finally {
      setSubmitting(false)
    }
  }, [editingId, form, loadData, resetForm])

  if (loading) {
    return (
      <div className="space-y-6">
        <Skeleton className="h-40 rounded-3xl" />
        <Skeleton className="h-[640px] rounded-3xl" />
      </div>
    )
  }

  return (
    <div className="space-y-6">
      <div className="flex flex-col gap-4 xl:flex-row xl:items-end xl:justify-between">
        <div className="space-y-3">
          <Badge variant="secondary">订阅与推送</Badge>
          <div>
            <h2 className="text-3xl font-semibold tracking-tight">订阅中心 / 异步投递 / 汇总简报</h2>
            <p className="mt-2 max-w-3xl text-sm leading-7 text-muted-foreground">
              这里统一管理邮件订阅、Webhook / Discord / Telegram / ntfy / Web Push 推送目标；当前投递走异步队列，并支持 retry pending 状态追踪。
            </p>
          </div>
        </div>

        <div className="flex flex-wrap items-center gap-3">
          <Button variant="outline" onClick={() => void loadData(true)} disabled={refreshing}>
            <RefreshCcw className="h-4 w-4" />
            {refreshing ? '刷新中...' : '刷新'}
          </Button>
          <Button
            variant="secondary"
            disabled={digesting !== null}
            onClick={async () => {
              try {
                setDigesting('weekly')
                const result = await adminApi.sendSubscriptionDigest('weekly')
                toast.success(`周报已入队：queued ${result.queued}，skipped ${result.skipped}`)
                await loadData(false)
              } catch (error) {
                toast.error(error instanceof ApiError ? error.message : '发送周报失败。')
              } finally {
                setDigesting(null)
              }
            }}
          >
            <Send className="h-4 w-4" />
            {digesting === 'weekly' ? '入队中...' : '发送周报'}
          </Button>
          <Button
            disabled={digesting !== null}
            onClick={async () => {
              try {
                setDigesting('monthly')
                const result = await adminApi.sendSubscriptionDigest('monthly')
                toast.success(`月报已入队：queued ${result.queued}，skipped ${result.skipped}`)
                await loadData(false)
              } catch (error) {
                toast.error(error instanceof ApiError ? error.message : '发送月报失败。')
              } finally {
                setDigesting(null)
              }
            }}
          >
            <BellRing className="h-4 w-4" />
            {digesting === 'monthly' ? '入队中...' : '发送月报'}
          </Button>
        </div>
      </div>

      <div className="grid gap-6 xl:grid-cols-[0.98fr_1.02fr]">
        <Card>
          <CardHeader>
            <CardTitle>{editingId ? `编辑订阅 #${editingId}` : '新增订阅目标'}</CardTitle>
            <CardDescription>
              当前共有 {subscriptions.length} 个订阅目标，其中 {activeCount} 个处于启用状态，当前待处理/重试中的投递 {queuedOrRetryCount} 条。
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="space-y-2">
              <Label>频道类型</Label>
              <Select
                value={form.channelType}
                onChange={(event) => setForm((current) => ({ ...current, channelType: event.target.value }))}
              >
                {CHANNEL_OPTIONS.map((item) => (
                  <option key={item.value} value={item.value}>
                    {item.label}
                  </option>
                ))}
              </Select>
            </div>
            <div className="space-y-2">
              <Label>目标地址</Label>
              <Input
                value={form.target}
                onChange={(event) => setForm((current) => ({ ...current, target: event.target.value }))}
                placeholder={
                  form.channelType === 'email'
                    ? 'name@example.com'
                    : form.channelType === 'ntfy'
                      ? 'topic-name 或 https://ntfy.example.com/topic'
                      : form.channelType === 'web_push'
                        ? 'https://push-service/...'
                        : 'https://...'
                }
              />
            </div>
            <div className="space-y-2">
              <Label>显示名称</Label>
              <Input
                value={form.displayName}
                onChange={(event) =>
                  setForm((current) => ({ ...current, displayName: event.target.value }))
                }
                placeholder="例如 站长邮箱 / Discord 运维群"
              />
            </div>
            <div className="grid gap-4 md:grid-cols-2">
              <div className="space-y-2">
                <Label>状态</Label>
                <Select
                  value={form.status}
                  onChange={(event) => setForm((current) => ({ ...current, status: event.target.value }))}
                >
                  <option value="active">active</option>
                  <option value="paused">paused</option>
                  <option value="pending">pending</option>
                  <option value="unsubscribed">unsubscribed</option>
                </Select>
              </div>
              <div className="space-y-2">
                <Label>备注</Label>
                <Input
                  value={form.notes}
                  onChange={(event) => setForm((current) => ({ ...current, notes: event.target.value }))}
                  placeholder="用途、机器人说明、负责人等"
                />
              </div>
            </div>
            <div className="space-y-2">
              <Label>filters（JSON）</Label>
              <Textarea
                value={form.filtersText}
                onChange={(event) => setForm((current) => ({ ...current, filtersText: event.target.value }))}
                placeholder='{"event_types":["post.published","digest.weekly"]}'
                className="min-h-32 font-mono text-xs"
              />
            </div>
            <div className="space-y-2">
              <Label>metadata（JSON，可选）</Label>
              <Textarea
                value={form.metadataText}
                onChange={(event) => setForm((current) => ({ ...current, metadataText: event.target.value }))}
                placeholder='{"owner":"ops","source":"manual"}'
                className="min-h-28 font-mono text-xs"
              />
            </div>
            <div className="flex flex-wrap gap-3">
              <Button className="flex-1" disabled={submitting} onClick={() => void submitForm()}>
                {editingId ? <Save className="h-4 w-4" /> : <MailPlus className="h-4 w-4" />}
                {submitting ? '保存中...' : editingId ? '保存修改' : '保存订阅目标'}
              </Button>
              {editingId ? (
                <Button variant="outline" disabled={submitting} onClick={resetForm}>
                  <X className="h-4 w-4" />
                  取消编辑
                </Button>
              ) : null}
            </div>
          </CardContent>
        </Card>

        <Card>
          <CardHeader className="flex flex-row items-start justify-between gap-4">
            <div>
              <CardTitle>当前订阅目标</CardTitle>
              <CardDescription>支持单条测试、编辑 filters / metadata，以及删除。</CardDescription>
            </div>
            <Badge variant="outline">{subscriptions.length} 个</Badge>
          </CardHeader>
          <CardContent>
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>频道</TableHead>
                  <TableHead>目标</TableHead>
                  <TableHead>状态</TableHead>
                  <TableHead>偏好</TableHead>
                  <TableHead className="text-right">操作</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {subscriptions.map((item) => (
                  <TableRow key={item.id}>
                    <TableCell>
                      <div className="space-y-1">
                        <div className="font-medium">{item.display_name ?? item.channel_type}</div>
                        <div className="text-xs uppercase tracking-[0.16em] text-muted-foreground">
                          {item.channel_type}
                        </div>
                      </div>
                    </TableCell>
                    <TableCell className="max-w-[280px] break-words text-sm text-muted-foreground">
                      <div>{item.target}</div>
                      <div className="mt-1 text-xs text-muted-foreground/80">
                        manage_token: {item.manage_token ? '已生成' : '—'} · verified: {item.verified_at ? 'yes' : 'no'}
                      </div>
                    </TableCell>
                    <TableCell>
                      <div className="space-y-1">
                        <Badge variant={item.status === 'active' ? 'success' : 'secondary'}>
                          {item.status}
                        </Badge>
                        <div className="text-xs text-muted-foreground">
                          失败 {item.failure_count ?? 0} 次 · 最近 {item.last_delivery_status ?? '—'}
                        </div>
                      </div>
                    </TableCell>
                    <TableCell className="max-w-[260px] whitespace-pre-wrap break-words text-xs text-muted-foreground">
                      {normalizePreview(item.filters)}
                    </TableCell>
                    <TableCell className="text-right">
                      <div className="flex flex-wrap justify-end gap-2">
                        <Button
                          variant="outline"
                          size="sm"
                          onClick={() => {
                            setEditingId(item.id)
                            setForm({
                              channelType: item.channel_type,
                              target: item.target,
                              displayName: item.display_name ?? '',
                              status: item.status,
                              notes: item.notes ?? '',
                              filtersText: prettyJson(item.filters),
                              metadataText: prettyJson(item.metadata),
                            })
                          }}
                        >
                          <Pencil className="h-4 w-4" />
                          编辑
                        </Button>
                        <Button
                          variant="outline"
                          size="sm"
                          disabled={actioningId === item.id}
                          onClick={async () => {
                            try {
                              setActioningId(item.id)
                              await adminApi.testSubscription(item.id)
                              toast.success('测试通知已入队。')
                              await loadData(false)
                            } catch (error) {
                              toast.error(error instanceof ApiError ? error.message : '测试发送失败。')
                            } finally {
                              setActioningId(null)
                            }
                          }}
                        >
                          <Send className="h-4 w-4" />
                          测试
                        </Button>
                        <Button
                          variant="ghost"
                          size="sm"
                          disabled={actioningId === item.id}
                          onClick={async () => {
                            try {
                              setActioningId(item.id)
                              await adminApi.deleteSubscription(item.id)
                              toast.success('订阅目标已删除。')
                              if (editingId === item.id) {
                                resetForm()
                              }
                              await loadData(false)
                            } catch (error) {
                              toast.error(error instanceof ApiError ? error.message : '删除失败。')
                            } finally {
                              setActioningId(null)
                            }
                          }}
                        >
                          <Trash2 className="h-4 w-4" />
                          删除
                        </Button>
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </CardContent>
        </Card>
      </div>

      <Card>
        <CardHeader className="flex flex-row items-start justify-between gap-4">
          <div>
            <CardTitle>最近投递记录</CardTitle>
            <CardDescription>关注 attempts / next retry / response，确认异步投递与重试状态。</CardDescription>
          </div>
          <Badge variant="outline">{deliveries.length} 条</Badge>
        </CardHeader>
        <CardContent>
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>时间</TableHead>
                <TableHead>事件</TableHead>
                <TableHead>频道</TableHead>
                <TableHead>状态</TableHead>
                <TableHead>重试</TableHead>
                <TableHead>响应</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {deliveries.map((item) => (
                <TableRow key={item.id}>
                  <TableCell className="text-muted-foreground">{item.delivered_at ?? item.created_at}</TableCell>
                  <TableCell>
                    <div className="font-medium">{item.event_type}</div>
                    <div className="text-xs text-muted-foreground">#{item.subscription_id ?? '—'}</div>
                  </TableCell>
                  <TableCell>
                    <div className="space-y-1 text-sm">
                      <div>{item.channel_type}</div>
                      <div className="line-clamp-1 text-xs text-muted-foreground">{item.target}</div>
                    </div>
                  </TableCell>
                  <TableCell>
                    <Badge variant={item.status === 'sent' ? 'success' : item.status === 'retry_pending' ? 'warning' : 'secondary'}>
                      {item.status}
                    </Badge>
                  </TableCell>
                  <TableCell className="text-xs text-muted-foreground">
                    <div>attempts: {item.attempts_count}</div>
                    <div>next: {item.next_retry_at ?? '—'}</div>
                  </TableCell>
                  <TableCell className="max-w-[360px] whitespace-pre-wrap break-words text-sm text-muted-foreground">
                    {item.response_text ?? '—'}
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </CardContent>
      </Card>
    </div>
  )
}
