import type { HTMLAttributes } from "react";

import type {
  OrderStatus,
  ReviewDecision,
  StepStatus,
  WorkflowStepName,
} from "@/lib/types/backend";
import {
  ORDER_STATUS_META,
  REVIEW_DECISION_META,
  STEP_STATUS_META,
  WORKFLOW_STEP_META,
  type StatusMeta,
  type StatusTone,
} from "@/lib/types/status";

type StatusBadgeVariant =
  | "order"
  | "reviewDecision"
  | "stepStatus"
  | "workflowStep";

type StatusBadgeBaseProps = HTMLAttributes<HTMLSpanElement>;

type OrderStatusBadgeProps = StatusBadgeBaseProps & {
  status: OrderStatus;
  variant?: "order";
};

type ReviewDecisionBadgeProps = StatusBadgeBaseProps & {
  status: ReviewDecision;
  variant: "reviewDecision";
};

type StepStatusBadgeProps = StatusBadgeBaseProps & {
  status: StepStatus;
  variant: "stepStatus";
};

type WorkflowStepBadgeProps = StatusBadgeBaseProps & {
  status: WorkflowStepName | null;
  variant: "workflowStep";
};

export type StatusBadgeProps =
  | OrderStatusBadgeProps
  | ReviewDecisionBadgeProps
  | StepStatusBadgeProps
  | WorkflowStepBadgeProps;

const TONE_STYLES: Record<StatusTone, string> = {
  neutral:
    "border-[rgba(76,69,60,0.14)] bg-[rgba(110,98,84,0.08)] text-[var(--ink-muted)]",
  info: "border-[rgba(57,86,95,0.16)] bg-[rgba(57,86,95,0.1)] text-[#2e4d56]",
  warning:
    "border-[rgba(145,104,46,0.18)] bg-[rgba(202,164,97,0.14)] text-[#7a5323]",
  success:
    "border-[rgba(88,106,56,0.18)] bg-[rgba(110,127,82,0.14)] text-[#50633b]",
  danger:
    "border-[rgba(140,74,67,0.18)] bg-[rgba(140,74,67,0.12)] text-[#7f3f38]",
};

function joinClasses(...values: Array<string | false | null | undefined>) {
  return values.filter(Boolean).join(" ");
}

function getMetaFromRecord<T extends string>(
  record: Record<T, StatusMeta>,
  status: string,
  variant: StatusBadgeVariant,
): StatusMeta {
  const meta = record[status as T];

  if (!meta) {
    throw new Error(`Invalid status "${status}" for variant "${variant}".`);
  }

  return meta;
}

function resolveStatusMeta(props: StatusBadgeProps): StatusMeta {
  switch (props.variant) {
    case "reviewDecision":
      return getMetaFromRecord(REVIEW_DECISION_META, props.status, props.variant);
    case "stepStatus":
      return getMetaFromRecord(STEP_STATUS_META, props.status, props.variant);
    case "workflowStep":
      if (props.status === null) {
        return { label: "未开始", tone: "neutral" };
      }

      return getMetaFromRecord(WORKFLOW_STEP_META, props.status, props.variant);
    case "order":
    case undefined:
      return getMetaFromRecord(ORDER_STATUS_META, props.status, "order");
  }
}

export function StatusBadge({ className, ...props }: StatusBadgeProps) {
  const meta = resolveStatusMeta(props);

  return (
    <span
      data-tone={meta.tone}
      className={joinClasses(
        "inline-flex items-center rounded-full border px-2 py-0.5 font-[var(--font-mono)] text-[11px] uppercase tracking-[0.14em]",
        TONE_STYLES[meta.tone],
        className,
      )}
      {...props}
    >
      {meta.label}
    </span>
  );
}
