import { useTranslation } from 'react-i18next'
import { Badge, LoadingBlock, Modal, QueryErrorState } from '@/ui'
import { useChangelogDiff } from '@/api/queries'
import { UserCell } from '@/lib/useUserDisplay'
import { kindBadgeVariant, kindLabel } from './kind-meta'

/**
 * Side-by-side schema diff для одного changelog event'а. Lazy fetch'ит
 * полный before/after через `useChangelogDiff` когда modal открыт.
 *
 * <p>Layout:
 * <ul>
 *   <li>Header — event metadata (kind badge, version, дата, автор).</li>
 *   <li>Summary stripe — counts added/removed/changed properties.</li>
 *   <li>Two-column JSON panes (before | after). Pre-monospace, scrollable.</li>
 * </ul>
 *
 * <p>На narrow viewport панели stack'аются вертикально.
 */
export function ChangelogDiffModal({
  open,
  onClose,
  dictionaryName,
  entryId,
}: {
  open: boolean
  onClose: () => void
  dictionaryName: string
  entryId: number | undefined
}) {
  const { t } = useTranslation()
  const { data, isLoading, error, refetch } = useChangelogDiff(
    open ? dictionaryName : undefined,
    open ? entryId : undefined,
  )

  return (
    <Modal
      isOpen={open}
      onClose={onClose}
      size="full"
      title={t('changelog.diff.title', { defaultValue: 'Изменения схемы' })}
      description={
        data
          ? `${data.dictionaryName} · ${new Date(data.occurredAt).toLocaleString()}`
          : undefined
      }
    >
      {isLoading && <LoadingBlock size="md" label={t('loading')} />}
      {error && <QueryErrorState error={error} onRetry={() => refetch()} />}
      {data && (
        <div className="space-y-4">
          {/* Header strip — kind + author */}
          <div className="flex flex-wrap items-center gap-2">
            <Badge variant={kindBadgeVariant(data.kind)}>{kindLabel(data.kind, t)}</Badge>
            <span className="text-cell text-mute inline-flex items-center gap-1">
              {t('changelog.diff.by', { defaultValue: 'автор' })}:{' '}
              <UserCell uuid={data.publishedBy.sub} />
            </span>
          </div>

          {/* Summary counts */}
          <ChangelogSummary
            added={data.summary.added.length}
            removed={data.summary.removed.length}
            changed={data.summary.changed.length}
          />

          {/* Field-level lists (collapsed by default — info dense) */}
          {(data.summary.added.length > 0 ||
            data.summary.removed.length > 0 ||
            data.summary.changed.length > 0) && (
            <div className="rounded-lg border border-line bg-surface p-3 space-y-2 text-cell">
              {data.summary.added.length > 0 && (
                <PropList
                  label={t('changelog.diff.added', { defaultValue: 'Добавлены' })}
                  items={data.summary.added}
                  tone="success"
                />
              )}
              {data.summary.removed.length > 0 && (
                <PropList
                  label={t('changelog.diff.removed', { defaultValue: 'Удалены' })}
                  items={data.summary.removed}
                  tone="danger"
                />
              )}
              {data.summary.changed.length > 0 && (
                <PropList
                  label={t('changelog.diff.changed', { defaultValue: 'Изменены' })}
                  items={data.summary.changed}
                  tone="warn"
                />
              )}
            </div>
          )}

          {/* Side-by-side JSON */}
          <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
            <JsonPane
              title={t('changelog.diff.before', { defaultValue: 'До' })}
              data={data.before}
              empty={t('changelog.diff.beforeEmpty', {
                defaultValue: '— (первоначальное создание словаря)',
              })}
            />
            <JsonPane
              title={t('changelog.diff.after', { defaultValue: 'После' })}
              data={data.after}
              empty={t('changelog.diff.afterEmpty', {
                defaultValue: '— (нет proposed schema для этого события)',
              })}
            />
          </div>
        </div>
      )}
    </Modal>
  )
}

function ChangelogSummary({
  added,
  removed,
  changed,
}: {
  added: number
  removed: number
  changed: number
}) {
  return (
    <div className="flex flex-wrap items-center gap-3 text-mono text-cap tabular-nums">
      <SummaryChip label="+" count={added} tone="success" />
      <SummaryChip label="−" count={removed} tone="danger" />
      <SummaryChip label="~" count={changed} tone="warn" />
    </div>
  )
}

function SummaryChip({
  label,
  count,
  tone,
}: {
  label: string
  count: number
  tone: 'success' | 'danger' | 'warn'
}) {
  const cls =
    tone === 'success'
      ? 'text-aurora'
      : tone === 'danger'
        ? 'text-danger'
        : 'text-warn'
  return (
    <span className={`inline-flex items-center gap-1 ${cls}`}>
      <span className="font-bold">{label}</span>
      <span>{count}</span>
    </span>
  )
}

function PropList({
  label,
  items,
  tone,
}: {
  label: string
  items: string[]
  tone: 'success' | 'danger' | 'warn'
}) {
  const dotCls =
    tone === 'success'
      ? 'bg-aurora'
      : tone === 'danger'
        ? 'bg-danger'
        : 'bg-warn'
  return (
    <div>
      <div className="text-cap font-semibold uppercase tracking-wider text-mute mb-1">
        {label} ({items.length})
      </div>
      <ul className="flex flex-wrap gap-1.5">
        {items.map((p) => (
          <li
            key={p}
            className="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-sm border border-line bg-surface-2/40"
          >
            <span className={`size-1.5 rounded-full ${dotCls}`} aria-hidden />
            <code className="font-mono text-cell">{p}</code>
          </li>
        ))}
      </ul>
    </div>
  )
}

function JsonPane({
  title,
  data,
  empty,
}: {
  title: string
  data: unknown | null
  empty: string
}) {
  return (
    <div className="rounded-lg border border-line bg-surface overflow-hidden flex flex-col">
      <div className="px-3 py-2 border-b border-line text-cap font-semibold uppercase tracking-wider text-mute">
        {title}
      </div>
      <pre className="text-mono text-cell p-3 overflow-auto max-h-[60vh] bg-[#0c0a23] text-[#f0eaff]">
        {data === null || data === undefined ? empty : JSON.stringify(data, null, 2)}
      </pre>
    </div>
  )
}
