import type { ReactNode } from "react"
import { AlertTriangle } from "lucide-react"

import { Card, CardContent, CardHeader } from "~/components/ui/card"
import { Skeleton } from "~/components/ui/skeleton"

type EmptyStateProps = {
  icon?: ReactNode
  title: string
  description?: ReactNode
  action?: ReactNode
  secondaryAction?: ReactNode
  /** When true, wrap the body in a bordered card frame. Default false —
   *  a bare dashed surface that reads as "nothing here yet". */
  framed?: boolean
}

/** Shared empty state. Centred icon disc + title + description + optional
 *  actions, using theme tokens only. Pair with EmptyState → ErrorState →
 *  content branching so a route never renders a bare blank surface. */
export function EmptyState({
  icon,
  title,
  description,
  action,
  secondaryAction,
  framed = false,
}: EmptyStateProps) {
  const body = (
    <div className="flex flex-col items-center gap-5 px-8 py-16 text-center">
      {icon ? (
        <div className="flex size-14 items-center justify-center rounded-2xl bg-primary/10 text-primary">
          {icon}
        </div>
      ) : null}
      <div className="space-y-2">
        <p className="text-title font-semibold tracking-tight">{title}</p>
        {description ? (
          <p className="mx-auto max-w-md text-[15px] leading-relaxed text-muted-foreground">
            {description}
          </p>
        ) : null}
      </div>
      {action || secondaryAction ? (
        <div className="mt-1 flex flex-wrap items-center justify-center gap-2">
          {action}
          {secondaryAction}
        </div>
      ) : null}
    </div>
  )
  if (framed) {
    return (
      <Card>
        <CardContent className="p-0">{body}</CardContent>
      </Card>
    )
  }
  return (
    <div className="overflow-hidden rounded-2xl border-2 border-dashed border-muted-foreground/20 bg-muted/30">
      {body}
    </div>
  )
}

/** Shared error state — a soft destructive-tinted banner. Used both by
 *  routes (data-fetch failures) and as the middle rung of the
 *  skeleton → error → empty → content grammar. */
export function ErrorState({
  title = "Something went wrong",
  message,
  action,
}: {
  title?: string
  message: string
  action?: ReactNode
}) {
  return (
    <div className="flex items-start gap-3 rounded-xl border border-destructive/30 bg-destructive/5 p-4">
      <AlertTriangle className="mt-0.5 size-4 shrink-0 text-destructive" />
      <div className="flex-1 space-y-1">
        <p className="text-sm font-medium text-destructive">{title}</p>
        <p className="text-sm text-muted-foreground">{message}</p>
      </div>
      {action ? <div className="shrink-0">{action}</div> : null}
    </div>
  )
}

/** Card-shaped loading placeholder for card lists/grids. */
export function LoadingCards({
  count = 3,
  variant = "row",
}: {
  count?: number
  variant?: "row" | "grid"
}) {
  const items = Array.from({ length: count })
  return (
    <div className={variant === "grid" ? "grid gap-5 sm:grid-cols-2" : "space-y-3"}>
      {items.map((_, i) => (
        <Card key={i}>
          <CardHeader className="space-y-2 pb-2">
            <Skeleton className="h-4 w-40" />
            <Skeleton className="h-3 w-64" />
          </CardHeader>
          <CardContent>
            <Skeleton className="h-3 w-3/4" />
          </CardContent>
        </Card>
      ))}
    </div>
  )
}
