import { cn } from "@/lib/utils"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Skeleton } from "@/components/ui/skeleton"
import {
  EVENT_TYPE_LABELS,
  TIMELINE_DOT_COLOR,
  type OrderEventType,
  type OrderStatus,
} from "../shared/statusConfig"

// ─── Types ────────────────────────────────────────────────────────────────────

interface TimelineEvent {
  _id: string
  eventType: string
  source: string
  fromStatus?: string
  toStatus?: string
  payload?: string
  createdAt: number
}

interface Props {
  events: TimelineEvent[] | undefined
}

// ─── Helpers ──────────────────────────────────────────────────────────────────

function parsePayload(raw: string | undefined): Record<string, string> {
  if (!raw) return {}
  try {
    return JSON.parse(raw)
  } catch {
    return {}
  }
}

function getEventLabel(event: TimelineEvent): string {
  switch (event.eventType as OrderEventType) {
    case "status_change": {
      const from = event.fromStatus ?? "—"
      const to = event.toStatus ?? "—"
      return `Status changed: ${from} → ${to}`
    }
    case "label_created": {
      const p = parsePayload(event.payload)
      const suffix = p.trackingNumber ? ` · ${p.trackingNumber}` : ""
      return `${EVENT_TYPE_LABELS.label_created}${suffix}`
    }
    case "tracking_update": {
      const p = parsePayload(event.payload)
      const s = p.status ?? event.toStatus ?? ""
      return s
        ? `${EVENT_TYPE_LABELS.tracking_update}: ${s}`
        : EVENT_TYPE_LABELS.tracking_update
    }
    default: {
      const label = EVENT_TYPE_LABELS[event.eventType as OrderEventType]
      return label ?? event.eventType
    }
  }
}

function getDotColor(event: TimelineEvent): string {
  if (event.eventType === "status_change" && event.toStatus) {
    return (
      TIMELINE_DOT_COLOR[event.toStatus as OrderStatus] ??
      "text-muted-foreground"
    )
  }
  return "text-muted-foreground"
}

const SOURCE_LABELS: Record<string, string> = {
  admin: "by admin",
  stripe_webhook: "via payment",
  customer_cancel: "by customer",
  customer_return: "by customer",
  shippo_webhook: "via courier",
  fulfillment: "by system",
}

function formatEventDate(ts: number): string {
  const d = new Date(ts)
  const date = d.toLocaleDateString("en-GB", { day: "numeric", month: "short" })
  const time = d.toLocaleTimeString("en-GB", {
    hour: "2-digit",
    minute: "2-digit",
  })
  return `${date} · ${time}`
}

// ─── Skeleton ─────────────────────────────────────────────────────────────────

function TimelineSkeleton() {
  return (
    <div className="flex flex-col gap-4">
      {Array.from({ length: 4 }).map((_, i) => (
        <div key={i} className="flex items-start gap-3">
          <Skeleton className="mt-0.5 size-3 shrink-0 rounded-full" />
          <div className="flex flex-1 flex-col gap-1.5">
            <Skeleton className="h-4 w-3/4" />
            <Skeleton className="h-3 w-24" />
          </div>
          <Skeleton className="h-3 w-20 shrink-0" />
        </div>
      ))}
    </div>
  )
}

// ─── Component ────────────────────────────────────────────────────────────────

export function OrderTimelineCard({ events }: Props) {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Timeline</CardTitle>
      </CardHeader>
      <CardContent>
        {events === undefined ? (
          <TimelineSkeleton />
        ) : events.length === 0 ? (
          <p className="text-sm text-muted-foreground">No activity yet.</p>
        ) : (
          <ol className="flex flex-col">
            {events.map((event, index) => {
              const isLast = index === events.length - 1
              const dotColor = getDotColor(event)
              const sourceLabel =
                SOURCE_LABELS[event.source] ?? event.source

              return (
                <li key={event._id} className="flex items-start gap-3">
                  {/* Dot + vertical connector */}
                  <div className="flex flex-col items-center">
                    <span
                      className={cn(
                        "mt-1 size-2.5 shrink-0 rounded-full border-2 border-current",
                        dotColor,
                      )}
                      aria-hidden="true"
                    />
                    {!isLast && (
                      <span className="mt-1 w-px flex-1 bg-border" />
                    )}
                  </div>

                  {/* Event content */}
                  <div
                    className={cn(
                      "flex flex-1 items-start justify-between gap-4 pb-4",
                      isLast && "pb-0",
                    )}
                  >
                    <div className="flex flex-col gap-0.5">
                      <p className="text-sm">{getEventLabel(event)}</p>
                      <p className="text-xs text-muted-foreground">
                        {sourceLabel}
                      </p>
                    </div>
                    <time
                      dateTime={new Date(event.createdAt).toISOString()}
                      className="shrink-0 text-xs text-muted-foreground"
                    >
                      {formatEventDate(event.createdAt)}
                    </time>
                  </div>
                </li>
              )
            })}
          </ol>
        )}
      </CardContent>
    </Card>
  )
}
