import Link from 'next/link'

import { Badge, EmptyState, Panel, PanelBody, PanelHeader } from '@/components/ui/display'
import { getI18n } from '@/lib/i18n/server'
import { formatDateTime } from '@/lib/i18n/translate'
import { cn } from '@/lib/cn'

type TimelineKind = 'commissioned' | 'maintenance' | 'incident' | 'prediction' | 'alert'

interface TimelineEvent {
  ts: number
  kind: TimelineKind
  title: string
  detail?: string
  href?: string
  code?: string
  severity?: 'info' | 'warning' | 'critical'
}

/** Marker colour per event kind. State colours are reserved for grid state, not history. */
const KIND_STYLE: Record<TimelineKind, string> = {
  commissioned: 'bg-info',
  maintenance: 'bg-brand',
  incident: 'bg-critical',
  prediction: 'bg-accent',
  alert: 'bg-watch',
}

export interface AssetTimelineSource {
  installedAt: Date
  maintenance: Array<{
    id: string
    code: string
    kind: string
    performedAt: Date | null
    scheduledAt: Date
    findings: string
    findingsAr: string
    healthBefore: number
    healthAfter: number
  }>
  incidents: Array<{
    id: string
    code: string
    title: string
    titleAr: string
    startedAt: Date
    severity: string
    wasPrevented: boolean
  }>
  predictions: Array<{
    id: string
    code: string
    eventType: string
    createdAt: Date
    riskScore: number
    status: string
  }>
  alerts: Array<{
    id: string
    code: string
    level: string
    title: string
    titleAr: string
    createdAt: Date
    status: string
  }>
}

/**
 * The asset's chronological record (§14).
 *
 * Maintenance, incidents, predictions and alerts each have their own panel elsewhere on
 * the passport, which answers "what happened in this category". This answers a different
 * question — "what happened to this asset, in order" — which is how a cause and its
 * consequence become visible: a deferred inspection, then a prediction, then the alert.
 */
export async function AssetTimeline({
  source,
  limit = 14,
  className,
}: {
  source: AssetTimelineSource
  limit?: number
  className?: string
}) {
  const { t, locale } = await getI18n()
  const ar = locale === 'ar'

  const events: TimelineEvent[] = [
    {
      ts: source.installedAt.getTime(),
      kind: 'commissioned' as const,
      title: t('assets.timeline.commissioned'),
      severity: 'info' as const,
    },
    ...source.maintenance.map((entry) => ({
      ts: (entry.performedAt ?? entry.scheduledAt).getTime(),
      kind: 'maintenance' as const,
      code: entry.code,
      title: t(`maintenance.kind.${entry.kind}`),
      detail: ar ? entry.findingsAr : entry.findings,
      severity: 'info' as const,
    })),
    ...source.incidents.map((entry) => ({
      ts: entry.startedAt.getTime(),
      kind: 'incident' as const,
      code: entry.code,
      title: ar ? entry.titleAr : entry.title,
      detail: entry.wasPrevented ? t('incidents.wasPrevented') : t(`severity.${entry.severity}`),
      href: `/incidents/${encodeURIComponent(entry.code)}`,
      severity: entry.wasPrevented ? ('info' as const) : ('critical' as const),
    })),
    ...source.predictions.map((entry) => ({
      ts: entry.createdAt.getTime(),
      kind: 'prediction' as const,
      code: entry.code,
      title: t(`eventType.${entry.eventType}`),
      detail: `${t('common.riskScore')} ${Math.round(entry.riskScore)}% · ${t(`predictions.status.${entry.status}`)}`,
      href: `/predictions/${encodeURIComponent(entry.code)}`,
      severity: 'warning' as const,
    })),
    ...source.alerts.map((entry) => ({
      ts: entry.createdAt.getTime(),
      kind: 'alert' as const,
      code: entry.code,
      title: ar ? entry.titleAr : entry.title,
      detail: `${t(`alertLevel.${entry.level}`)} · ${t(`alertStatus.${entry.status}`)}`,
      href: `/alerts?focus=${encodeURIComponent(entry.code)}`,
      severity: 'warning' as const,
    })),
  ]
    .sort((a, b) => b.ts - a.ts)
    .slice(0, limit)

  return (
    <Panel className={className}>
      <PanelHeader
        title={t('assets.passport.timeline')}
        subtitle={t('assets.timeline.note')}
        action={<Badge tone="muted">{events.length}</Badge>}
      />
      {events.length === 0 ? (
        <EmptyState title={t('assets.timeline.empty')} />
      ) : (
        <PanelBody>
          <ol className="relative space-y-4">
            {/* The spine sits on the start edge so it works unchanged in both directions. */}
            <span
              aria-hidden
              className="absolute inset-y-1 w-px bg-border"
              style={{ insetInlineStart: '0.3125rem' }}
            />

            {events.map((event, index) => (
              <li key={`${event.kind}-${event.code ?? index}`} className="relative ps-6">
                <span
                  aria-hidden
                  className={cn(
                    'absolute top-1.5 size-2.5 rounded-full ring-4 ring-surface',
                    KIND_STYLE[event.kind],
                  )}
                  style={{ insetInlineStart: 0 }}
                />

                <div className="flex flex-wrap items-baseline justify-between gap-x-3 gap-y-1">
                  <div className="flex flex-wrap items-center gap-2">
                    <span className="text-[10px] font-semibold uppercase tracking-wide text-text-faint">
                      {t(`assets.timeline.${event.kind}`)}
                    </span>
                    {event.code ? (
                      <span className="font-mono text-[11px] text-text-muted">{event.code}</span>
                    ) : null}
                  </div>
                  <time
                    dateTime={new Date(event.ts).toISOString()}
                    className="tnum text-[11px] text-text-faint"
                  >
                    {formatDateTime(locale, event.ts)}
                  </time>
                </div>

                <p className="mt-1 text-sm text-text">
                  {event.href ? (
                    <Link href={event.href} className="transition-colors hover:text-brand">
                      {event.title}
                    </Link>
                  ) : (
                    event.title
                  )}
                </p>

                {event.detail ? (
                  <p className="mt-0.5 line-clamp-2 text-xs leading-relaxed text-text-muted">
                    {event.detail}
                  </p>
                ) : null}
              </li>
            ))}
          </ol>
        </PanelBody>
      )}
    </Panel>
  )
}
