import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
import { STATUS_REGISTRY, RESERVATION_SOURCE_META, type Tone } from "@/lib/domain";

const badgeVariants = cva("inline-flex items-center gap-1.5 rounded-full border font-medium whitespace-nowrap leading-none", {
  variants: {
    tone: {
      positive: "bg-positive-50 text-positive-700 border-positive-500/20 dark:bg-positive-500/10 dark:text-positive-500 dark:border-positive-500/25",
      warning: "bg-warning-50 text-warning-700 border-warning-500/25 dark:bg-warning-500/10 dark:text-warning-500 dark:border-warning-500/25",
      negative: "bg-negative-50 text-negative-700 border-negative-500/20 dark:bg-negative-500/10 dark:text-negative-500 dark:border-negative-500/25",
      info: "bg-info-50 text-info-700 border-info-500/20 dark:bg-info-500/10 dark:text-info-500 dark:border-info-500/25",
      accent: "bg-accent-50 text-accent-700 border-accent-500/20 dark:bg-accent-500/10 dark:text-accent-500 dark:border-accent-500/25",
      neutral: "bg-surface-2 text-fg-muted border-border",
      brand: "bg-brand-50 text-brand-700 border-brand-500/20 dark:bg-brand-500/10 dark:text-brand-300 dark:border-brand-500/25",
      outline: "bg-transparent text-fg-muted border-border-strong",
    },
    size: {
      sm: "px-1.5 py-0.5 text-2xs",
      md: "px-2 py-1 text-xs",
      lg: "px-2.5 py-1.5 text-xs",
    },
  },
  defaultVariants: { tone: "neutral", size: "md" },
});

export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badgeVariants> {
  dot?: boolean;
}

export function Badge({ className, tone, size, dot, children, ...props }: BadgeProps) {
  return (
    <span className={cn(badgeVariants({ tone, size }), className)} {...props}>
      {dot ? <span className="size-1.5 rounded-full bg-current opacity-80" aria-hidden /> : null}
      {children}
    </span>
  );
}

const DOT_TONE: Record<Tone, string> = {
  positive: "bg-positive-500",
  warning: "bg-warning-500",
  negative: "bg-negative-500",
  info: "bg-info-500",
  accent: "bg-accent-500",
  neutral: "bg-stone-400",
};

/**
 * Global semantic status badge. Same visual for the same status across every
 * page. Uses a dot + label so state is not conveyed by colour alone.
 */
export function StatusBadge({ status, size = "md", className, prefix }: { status: string; size?: "sm" | "md" | "lg"; className?: string; prefix?: "CLEAN_" | "PRIO_" }) {
  const key = prefix ? `${prefix}${status}` : status;
  const meta = STATUS_REGISTRY[key] ?? { label: status.replace(/_/g, " ").toLowerCase(), tone: "neutral" as Tone };
  return (
    <Badge tone={meta.tone} size={size} className={cn("capitalize", className)} title={meta.description}>
      <span className={cn("size-1.5 rounded-full", DOT_TONE[meta.tone])} aria-hidden />
      {meta.label}
    </Badge>
  );
}

export function StatusDot({ status, prefix, className }: { status: string; prefix?: "CLEAN_" | "PRIO_"; className?: string }) {
  const key = prefix ? `${prefix}${status}` : status;
  const meta = STATUS_REGISTRY[key];
  return <span className={cn("inline-block size-2 rounded-full", DOT_TONE[meta?.tone ?? "neutral"], className)} title={meta?.label} />;
}

export function SourceBadge({ source, size = "md", className }: { source: string; size?: "sm" | "md"; className?: string }) {
  const meta = RESERVATION_SOURCE_META[source as keyof typeof RESERVATION_SOURCE_META] ?? { label: source, color: "#6B7280" };
  return (
    <Badge tone="outline" size={size} className={cn("gap-1.5", className)}>
      <span className="size-1.5 rounded-full" style={{ background: meta.color }} aria-hidden />
      {meta.label}
    </Badge>
  );
}

export const TONE_TEXT: Record<Tone, string> = {
  positive: "text-positive-600",
  warning: "text-warning-600",
  negative: "text-negative-600",
  info: "text-info-600",
  accent: "text-accent-600",
  neutral: "text-fg-muted",
};
export const TONE_BG: Record<Tone, string> = {
  positive: "bg-positive-500",
  warning: "bg-warning-500",
  negative: "bg-negative-500",
  info: "bg-info-500",
  accent: "bg-accent-500",
  neutral: "bg-stone-400",
};
export const TONE_SOFT: Record<Tone, string> = {
  positive: "bg-positive-50 text-positive-700 dark:bg-positive-500/10 dark:text-positive-500",
  warning: "bg-warning-50 text-warning-700 dark:bg-warning-500/10 dark:text-warning-500",
  negative: "bg-negative-50 text-negative-700 dark:bg-negative-500/10 dark:text-negative-500",
  info: "bg-info-50 text-info-700 dark:bg-info-500/10 dark:text-info-500",
  accent: "bg-accent-50 text-accent-700 dark:bg-accent-500/10 dark:text-accent-500",
  neutral: "bg-surface-2 text-fg-muted",
};
