import type { ReactNode } from "react";
import { Box, Group, Progress, Text, Tooltip } from "@mantine/core";

import type { BookingWindowPhase } from "@/types/trainScheduling";

import "./batchVisuals.css";

/**
 * Shared visual building blocks for the batch board surfaces (list + detail).
 * Everything keys off the same booking-pipeline color language so the two
 * pages read as one clean, professional product on a white surface.
 */

export type BatchCounts = {
  allocated: number;
  selectedForBatch: number;
  ready: number;
  waiting: number;
  pendingContract: number;
  expired: number;
};

export const PIPELINE_STAGES: ReadonlyArray<{
  key: keyof BatchCounts;
  label: string;
  color: string;
  hint: string;
}> = [
  {
    key: "allocated",
    label: "Allocated",
    color: "edr-green",
    hint: "Assigned to wagons on the train",
  },
  {
    key: "selectedForBatch",
    label: "Selected",
    color: "orange",
    hint: "Picked by batch — customer notified to pay",
  },
  {
    key: "ready",
    label: "Ready",
    color: "teal",
    hint: "Contract signed — waiting for batch pick",
  },
  {
    key: "waiting",
    label: "Waiting",
    color: "blue",
    hint: "Paid — waiting for a slot",
  },
  {
    key: "pendingContract",
    label: "Pending contract",
    color: "gray",
    hint: "Contract not signed yet",
  },
  {
    key: "expired",
    label: "Expired",
    color: "red",
    hint: "Payment deadline missed",
  },
];

export function totalBookingCount(counts: BatchCounts): number {
  return PIPELINE_STAGES.reduce((sum, stage) => sum + counts[stage.key], 0);
}

/**
 * Stacked booking-pipeline bar: one colored segment per batch state, with an
 * optional dot legend underneath. Reads as a single glanceable funnel.
 */
export function BookingPipeline({
  counts,
  size = 10,
  showLegend = true,
}: {
  counts: BatchCounts;
  size?: number;
  showLegend?: boolean;
}) {
  const total = totalBookingCount(counts);
  const stages = PIPELINE_STAGES.filter((s) => counts[s.key] > 0);

  if (!total) {
    return (
      <Box>
        <Progress value={0} size={size} radius="xl" />
        <Text size="xs" c="dimmed" mt={6}>
          No bookings yet
        </Text>
      </Box>
    );
  }

  return (
    <Box>
      <Progress.Root size={size} radius="xl">
        {stages.map((stage) => (
          <Tooltip
            key={stage.key}
            label={`${counts[stage.key]} ${stage.label.toLowerCase()} — ${stage.hint}`}
            withArrow
          >
            <Progress.Section
              value={(counts[stage.key] / total) * 100}
              color={stage.color}
            />
          </Tooltip>
        ))}
      </Progress.Root>
      {showLegend ? (
        <Group gap={12} mt={9} wrap="wrap">
          {stages.map((stage) => (
            <Group key={stage.key} gap={5} wrap="nowrap">
              <Box
                w={8}
                h={8}
                style={{
                  borderRadius: 999,
                  background: `var(--mantine-color-${stage.color}-6)`,
                  flexShrink: 0,
                }}
              />
              <Text size="xs" c="dimmed">
                <Text component="span" size="xs" fw={700} c="dark.4">
                  {counts[stage.key]}
                </Text>{" "}
                {stage.label.toLowerCase()}
              </Text>
            </Group>
          ))}
        </Group>
      ) : null}
    </Box>
  );
}

const WINDOW_META: Record<string, { color: string; label: string; pulse: boolean }> = {
  OPEN: { color: "edr-green", label: "Window open", pulse: true },
  FULL: { color: "orange", label: "Full", pulse: false },
  CLOSED: { color: "gray", label: "Closed", pulse: false },
};

/**
 * Booking-window status pill with a status dot (pulsing while OPEN), styled for
 * a clean white surface.
 */
export function WindowStatusPill({ status }: { status: string }) {
  const meta = WINDOW_META[status] ?? { color: "gray", label: status, pulse: false };
  return (
    <Group
      gap={6}
      wrap="nowrap"
      style={{
        display: "inline-flex",
        padding: "4px 11px",
        borderRadius: 999,
        background: `var(--mantine-color-${meta.color}-0)`,
        border: `1px solid var(--mantine-color-${meta.color}-2)`,
      }}
    >
      <Box
        w={7}
        h={7}
        className={meta.pulse ? "bb-pulse-dot" : undefined}
        style={{
          borderRadius: 999,
          flexShrink: 0,
          background: `var(--mantine-color-${meta.color}-6)`,
        }}
      />
      <Text
        size="xs"
        fw={700}
        c={`${meta.color}.8`}
        style={{ letterSpacing: 0.3, lineHeight: 1, whiteSpace: "nowrap" }}
      >
        {meta.label}
      </Text>
    </Group>
  );
}

/**
 * Small neutral info chip used in the page headers (date, loco, status, …).
 * Clean light surface that reads well on white.
 */
export function HeroChip({
  icon,
  children,
}: {
  icon?: ReactNode;
  children: ReactNode;
}) {
  return (
    <Group
      gap={6}
      wrap="nowrap"
      style={{
        display: "inline-flex",
        padding: "4px 10px",
        borderRadius: 8,
        background: "var(--mantine-color-gray-0)",
        border: "1px solid var(--mantine-color-gray-2)",
        color: "var(--mantine-color-gray-7)",
      }}
    >
      {icon}
      <Text size="xs" fw={600} c="gray.7" style={{ whiteSpace: "nowrap" }}>
        {children}
      </Text>
    </Group>
  );
}

const PHASE_META: Record<
  BookingWindowPhase,
  { color: string; label: string; pulse: boolean }
> = {
  PRE_WINDOW: { color: "gray", label: "Pre-window", pulse: false },
  OPEN: { color: "edr-green", label: "Booking open", pulse: true },
  DOC_REVIEW: { color: "yellow", label: "Doc review", pulse: true },
  PAYMENT: { color: "blue", label: "Payment", pulse: true },
  CLOSED_FOR_DAY: { color: "dark", label: "Closed for day", pulse: false },
  DONE: { color: "dark", label: "Done", pulse: false },
};

/**
 * Import booking-cycle phase pill (OPEN → DOC_REVIEW → PAYMENT → …) with an
 * optional cycle number. Same visual language as `WindowStatusPill`.
 */
export function WindowPhasePill({
  phase,
  cycleNo,
  size = "md",
}: {
  phase: BookingWindowPhase;
  cycleNo?: number;
  size?: "sm" | "md";
}) {
  const meta = PHASE_META[phase] ?? {
    color: "gray",
    label: phase,
    pulse: false,
  };
  const compact = size === "sm";
  return (
    <Group
      gap={6}
      wrap="nowrap"
      style={{
        display: "inline-flex",
        padding: compact ? "2px 8px" : "4px 11px",
        borderRadius: 999,
        background: `var(--mantine-color-${meta.color}-0)`,
        border: `1px solid var(--mantine-color-${meta.color}-2)`,
      }}
    >
      <Box
        w={compact ? 6 : 7}
        h={compact ? 6 : 7}
        className={meta.pulse ? "bb-pulse-dot" : undefined}
        style={{
          borderRadius: 999,
          flexShrink: 0,
          background: `var(--mantine-color-${meta.color}-6)`,
        }}
      />
      <Text
        size="xs"
        fw={700}
        c={`${meta.color}.8`}
        style={{ letterSpacing: 0.3, lineHeight: 1, whiteSpace: "nowrap" }}
      >
        {meta.label}
        {cycleNo && cycleNo > 1 ? ` · cycle ${cycleNo}` : ""}
      </Text>
    </Group>
  );
}
