import { useState } from 'react'
import { createFileRoute, Link } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import { UserCell } from '@/lib/useUserDisplay'
import {
  Alert,
  Badge,
  Button,
  EmptyState,
  IconButton,
  LoadingBlock,
  PageHeader,
  Panel,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeaderCell,
  TableRow,
} from '@/ui'
import {
  ArrowClockwiseIcon,
  ArrowsClockwiseIcon,
  KeyIcon,
  PaperPlaneTiltIcon,
  TrashIcon,
} from '@phosphor-icons/react'
import {
  useWebhookDeliveries,
  useWebhookSubscription,
} from '@/api/queries'
import {
  useDeleteWebhook,
  useRetryWebhookDelivery,
  useRotateWebhookSecret,
  useTestWebhook,
  useUpdateWebhook,
} from '@/api/mutations'
import type { WebhookTestPingResult } from '@/api/client'
import { SCOPE_DOT } from '@/lib/scope-style'
import { WebhookStatsCards } from '@/components/webhooks/WebhookStatsCards'
import { WebhookStatsHistogram } from '@/components/webhooks/WebhookStatsHistogram'

export const Route = createFileRoute('/webhooks/$id')({
  component: WebhookDetailPage,
})

const STATUS_BADGE: Record<string, 'success' | 'warning' | 'error' | 'neutral'> = {
  delivered: 'success',
  retrying: 'warning',
  pending: 'neutral',
  dlq: 'error',
}

function WebhookDetailPage() {
  const { id } = Route.useParams()
  const { t } = useTranslation()
  const sub = useWebhookSubscription(id)
  const [page, setPage] = useState(0)
  const [statusFilter, setStatusFilter] = useState<string | undefined>(undefined)
  const deliveries = useWebhookDeliveries(id, page, 50, statusFilter)
  const handleStatusToggle = (s: string) => {
    setPage(0)
    setStatusFilter((curr) => (curr === s ? undefined : s))
  }
  const rotateMut = useRotateWebhookSecret()
  const deleteMut = useDeleteWebhook()
  const updateMut = useUpdateWebhook()
  const retryMut = useRetryWebhookDelivery()
  const testMut = useTestWebhook()
  const [testResult, setTestResult] = useState<WebhookTestPingResult | null>(null)

  const handleTest = () => {
    setTestResult(null)
    testMut.mutate(id, {
      onSuccess: (r) => setTestResult(r),
      onError: (e) =>
        setTestResult({
          status: 'rejected',
          message: e instanceof Error ? e.message : String(e),
        }),
    })
  }

  const handleRetry = (deliveryId: number) => {
    if (!window.confirm(t('webhooks.deliveries.confirmRetry'))) return
    retryMut.mutate(deliveryId)
  }
  const [revealedSecret, setRevealedSecret] = useState<string | null>(null)

  const handleRotate = () => {
    if (!window.confirm(t('webhooks.confirmRotate'))) return
    rotateMut.mutate(id, {
      onSuccess: (s) => setRevealedSecret(s.hmacSecret),
    })
  }

  const handleDelete = () => {
    if (!sub.data) return
    if (!window.confirm(t('webhooks.confirmDelete', { name: sub.data.name }))) return
    deleteMut.mutate(id, {
      onSuccess: () => {
        window.location.assign('/webhooks')
      },
    })
  }

  if (sub.isLoading) return <LoadingBlock size="md" label={t('loading')} />
  if (sub.error || !sub.data) {
    return (
      <Alert variant="error" title={t('error.failed')}>
        {String(sub.error ?? t('webhooks.notFound'))}
      </Alert>
    )
  }

  const data = sub.data

  return (
    <div className="space-y-6">
      <PageHeader
        breadcrumb={
          <Link to="/webhooks" className="text-body text-ink-2 hover:text-accent">
            ← {t('nav.webhooks')}
          </Link>
        }
        title={data.name}
        description={data.description ?? data.url}
        actions={
          <div className="flex items-center gap-2">
            <Button
              variant="secondary"
              leftIcon={<PaperPlaneTiltIcon weight="bold" size={16} />}
              loading={testMut.isPending}
              onClick={handleTest}
            >
              {t('webhooks.action.test')}
            </Button>
            <Button
              variant="secondary"
              leftIcon={<KeyIcon weight="bold" size={16} />}
              loading={rotateMut.isPending}
              onClick={handleRotate}
            >
              {t('webhooks.action.rotateSecret')}
            </Button>
            <Button
              variant="ghost"
              leftIcon={<TrashIcon weight="bold" size={16} />}
              loading={deleteMut.isPending}
              onClick={handleDelete}
            >
              {t('webhooks.action.delete')}
            </Button>
          </div>
        }
      />

      {testResult && <TestResultAlert result={testResult} onDismiss={() => setTestResult(null)} />}

      <Panel>
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-4 p-4">
          <InfoRow label={t('webhooks.field.url')}>
            <code className="text-mono break-all">{data.url}</code>
          </InfoRow>
          <InfoRow label={t('webhooks.col.status')}>
            <div className="flex items-center gap-3">
              <Badge variant={data.active ? 'success' : 'neutral'}>
                {data.active ? t('webhooks.active') : t('webhooks.inactive')}
              </Badge>
              <button
                type="button"
                onClick={() => {
                  // Toggle active. PUT requires full payload — пересобираем
                  // из current state + переворачиваем active. Backend
                  // service treats PUT как full replace, поэтому все
                  // поля должны быть переданы.
                  updateMut.mutate({
                    id: data.id,
                    payload: {
                      name: data.name,
                      url: data.url,
                      scopeFilter: data.scopeFilter ?? undefined,
                      dictionaryFilter: data.dictionaryFilter ?? undefined,
                      eventTypeFilter: data.eventTypeFilter ?? undefined,
                      description: data.description ?? undefined,
                      active: !data.active,
                    },
                  })
                }}
                disabled={updateMut.isPending}
                className="text-cap text-accent hover:underline disabled:opacity-50"
              >
                {data.active
                  ? t('webhooks.action.deactivate', { defaultValue: 'Деактивировать' })
                  : t('webhooks.action.activate', { defaultValue: 'Активировать' })}
              </button>
            </div>
          </InfoRow>
          <InfoRow label={t('webhooks.field.scopeFilter')}>
            {data.scopeFilter && data.scopeFilter.length > 0 ? (
              <div className="flex gap-2">
                {data.scopeFilter.map((s) => (
                  <span
                    key={s}
                    className="text-cap inline-flex items-center gap-1"
                  >
                    <span className={`inline-block size-2 rounded-full ${SCOPE_DOT[s]}`} aria-hidden />
                    {s}
                  </span>
                ))}
              </div>
            ) : (
              <span className="text-cell text-mute">{t('webhooks.allScopes')}</span>
            )}
          </InfoRow>
          <InfoRow label={t('webhooks.field.dictionaryFilter')}>
            <span className="text-cell">
              {data.dictionaryFilter && data.dictionaryFilter.length > 0
                ? data.dictionaryFilter.join(', ')
                : t('webhooks.allDicts')}
            </span>
          </InfoRow>
          <InfoRow label={t('webhooks.field.eventTypeFilter')}>
            <span className="text-cell">
              {data.eventTypeFilter && data.eventTypeFilter.length > 0
                ? data.eventTypeFilter.join(', ')
                : t('webhooks.allEvents')}
            </span>
          </InfoRow>
          <InfoRow label="HMAC secret">
            <code className="text-mono">{data.hmacSecret}</code>
          </InfoRow>
          <InfoRow label={t('webhooks.field.createdBy')}>
            <span className="text-cell inline-flex items-center gap-1">
              <UserCell uuid={data.createdBy} /> · {new Date(data.createdAt).toLocaleString()}
            </span>
          </InfoRow>
        </div>
      </Panel>

      {/* Stats cards — счётчики per status + success rate. Aggregate
          из 4 параллельных queries с size=1 (cheap). */}
      <WebhookStatsCards subscriptionId={id} />

      {/* Time-series histogram — backend /stats?bucketBy=hour|day. SVG
          stacked bars без recharts depend'ы. 24h / 7d toggle. */}
      <WebhookStatsHistogram subscriptionId={id} />

      <div>
        <div className="flex items-center justify-between mb-3">
          <h2 className="font-sans text-title-md text-accent">
            {t('webhooks.deliveries.title')}
          </h2>
          <IconButton
            label={t('audit.filter.apply')}
            variant="default"
            icon={<ArrowsClockwiseIcon weight="regular" />}
            onClick={() => deliveries.refetch()}
          />
        </div>

        <div
          className="flex flex-wrap items-center gap-1.5 mb-3"
          role="group"
          aria-label={t('webhooks.deliveries.filter.label')}
        >
          {(['pending', 'retrying', 'delivered', 'dlq'] as const).map((s) => {
            const active = statusFilter === s
            return (
              <button
                key={s}
                type="button"
                onClick={() => handleStatusToggle(s)}
                aria-pressed={active}
                className={[
 'text-cap inline-flex items-center gap-1.5 px-2.5 py-1 rounded-sm border transition-colors',
                  active
                    ? 'border-accent bg-accent/8 text-accent'
                    : 'border-line bg-surface text-ink-2 hover:border-ink/40',
                ].join(' ')}
              >
                {s}
              </button>
            )
          })}
          {statusFilter && (
            <button
              type="button"
              onClick={() => {
                setPage(0)
                setStatusFilter(undefined)
              }}
              className="text-cell text-accent hover:underline ml-2"
            >
              {t('webhooks.deliveries.filter.clear')}
            </button>
          )}
        </div>

        {deliveries.isLoading ? (
          <LoadingBlock size="sm" />
        ) : !deliveries.data || deliveries.data.content.length === 0 ? (
          <EmptyState title={t('webhooks.deliveries.empty')} />
        ) : (
          <Panel>
            <Table>
              <TableHead>
                <TableRow>
                  <TableHeaderCell>{t('webhooks.deliveries.col.eventId')}</TableHeaderCell>
                  <TableHeaderCell>{t('webhooks.col.status')}</TableHeaderCell>
                  <TableHeaderCell>{t('webhooks.deliveries.col.attempts')}</TableHeaderCell>
                  <TableHeaderCell>{t('webhooks.deliveries.col.lastAttempt')}</TableHeaderCell>
                  <TableHeaderCell>{t('webhooks.deliveries.col.lastStatusCode')}</TableHeaderCell>
                  <TableHeaderCell>{t('webhooks.deliveries.col.lastError')}</TableHeaderCell>
                  <TableHeaderCell align="right">
                    {t('dict.col.actions')}
                  </TableHeaderCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {deliveries.data.content.map((d) => {
                  const canRetry = d.status === 'dlq' || d.status === 'retrying'
                  return (
                    <TableRow key={d.id}>
                      <TableCell>
                        <span className="text-mono">{d.outboxEventId}</span>
                      </TableCell>
                      <TableCell>
                        <Badge variant={STATUS_BADGE[d.status] ?? 'neutral'}>
                          {d.status}
                        </Badge>
                      </TableCell>
                      <TableCell>
                        <span className="text-mono">{d.attemptCount}</span>
                      </TableCell>
                      <TableCell>
                        <span className="text-cell text-ink-2">
                          {d.lastAttemptAt
                            ? new Date(d.lastAttemptAt).toLocaleString()
                            : '—'}
                        </span>
                      </TableCell>
                      <TableCell>
                        <span className="text-mono">
                          {d.lastStatusCode ?? '—'}
                        </span>
                      </TableCell>
                      <TableCell>
                        <span className="text-cell text-ink-2 line-clamp-2 max-w-md inline-block">
                          {d.lastError ?? '—'}
                        </span>
                      </TableCell>
                      <TableCell align="right">
                        {canRetry && (
                          <IconButton
                            label={t('webhooks.deliveries.action.retry')}
                            variant="default"
                            icon={<ArrowClockwiseIcon weight="regular" />}
                            disabled={retryMut.isPending}
                            onClick={() => handleRetry(d.id)}
                          />
                        )}
                      </TableCell>
                    </TableRow>
                  )
                })}
              </TableBody>
            </Table>
          </Panel>
        )}

        {deliveries.data && (deliveries.data.totalPages ?? 0) > 1 && (
          <div className="flex justify-center gap-2 mt-3">
            <Button
              variant="ghost"
              disabled={page === 0}
              onClick={() => setPage((p) => Math.max(0, p - 1))}
            >
              ←
            </Button>
            <span className="text-body text-ink-2 self-center">
              {page + 1} / {deliveries.data.totalPages}
            </span>
            <Button
              variant="ghost"
              disabled={(page + 1) >= (deliveries.data.totalPages ?? 0)}
              onClick={() => setPage((p) => p + 1)}
            >
              →
            </Button>
          </div>
        )}
      </div>

      {revealedSecret && (
        <RotateRevealModal
          secret={revealedSecret}
          onClose={() => setRevealedSecret(null)}
        />
      )}
    </div>
  )
}

function TestResultAlert({
  result,
  onDismiss,
}: {
  result: WebhookTestPingResult
  onDismiss: () => void
}) {
  const { t } = useTranslation()
  const variant =
    result.status === 'success' ? 'success' : result.status === 'failure' ? 'error' : 'warning'
  const titleKey =
    result.status === 'success'
      ? 'webhooks.test.success'
      : result.status === 'failure'
        ? 'webhooks.test.failure'
        : 'webhooks.test.rejected'
  return (
    <Alert
      variant={variant}
      title={t(titleKey)}
      action={
        <button
          type="button"
          className="text-cell text-ink-2 hover:text-ink"
          onClick={onDismiss}
        >
          ✕
        </button>
      }
    >
      <div className="space-y-1 text-body">
        {result.httpStatus != null && (
          <div>
            <span className="text-cap text-mute mr-2">
              HTTP
            </span>
            <span className="font-mono">{result.httpStatus}</span>
          </div>
        )}
        {result.latencyMs != null && (
          <div>
            <span className="text-cap text-mute mr-2">
              {t('webhooks.test.latency')}
            </span>
            <span className="font-mono">{result.latencyMs} ms</span>
          </div>
        )}
        {result.message && (
          <div className="text-mono text-ink whitespace-pre-wrap break-all">
            {result.message}
          </div>
        )}
      </div>
    </Alert>
  )
}

function InfoRow({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div>
      <div className="text-cap text-mute mb-1">
        {label}
      </div>
      <div>{children}</div>
    </div>
  )
}

function RotateRevealModal({
  secret,
  onClose,
}: {
  secret: string
  onClose: () => void
}) {
  const { t } = useTranslation()
  return (
    <div
      className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4"
      onClick={onClose}
    >
      <div
        className="bg-surface rounded-lg p-6 max-w-xl w-full space-y-4"
        onClick={(e) => e.stopPropagation()}
      >
        <h3 className="font-sans text-title-lg text-accent">
          {t('webhooks.secret.rotatedTitle')}
        </h3>
        <Alert variant="warning" title={t('webhooks.secret.warningTitle')}>
          {t('webhooks.secret.rotatedWarning')}
        </Alert>
        <div className="bg-ink/5 border border-line rounded-md p-3">
          <code className="text-mono break-all">{secret}</code>
        </div>
        <div className="flex justify-end">
          <Button variant="primary" onClick={onClose}>
            {t('webhooks.secret.acknowledge')}
          </Button>
        </div>
      </div>
    </div>
  )
}
