import type { ReactNode } from "react";
import { Box, Group, Paper, Stack, Text } from "@mantine/core";
import type { LucideIcon } from "lucide-react";
import { MapPin } from "lucide-react";

import { MiniRing, MiniSparkline } from "@/components/common/MiniGraph";
import type { OverviewAccent } from "@/components/overview/overview.styles";
import { freightBrand } from "@/theme/freight-brand";

/** Mini-graph variants a StatTile can render at its bottom. */
export type StatTileGraph = "area" | "line" | "ring" | "none";

/**
 * Shared visual building blocks for the Train Scheduling V2 surfaces.
 * Everything keys off the freight brand green so the list + detail pages
 * read as one cohesive, premium product.
 */

export const scheduleBrand = {
  /** Deep green → emerald hero wash used across scheduling surfaces. */
  heroGradient: `linear-gradient(135deg, ${freightBrand.primaryDark} 0%, ${freightBrand.primary} 48%, ${freightBrand.primaryLight} 120%)`,
  /** Soft tinted surface for cards on white backgrounds. */
  softSurface: `linear-gradient(135deg, ${freightBrand.mutedBg} 0%, #ffffff 60%, var(--mantine-color-gray-0) 100%)`,
  ring: freightBrand.ring,
  shadow: freightBrand.shadow,
  shadowSm: freightBrand.shadowSm,
  mutedBorder: freightBrand.mutedBorder,
} as const;

const STATUS_META: Record<
  string,
  { color: string; dot: string; label?: string }
> = {
  DRAFT: { color: "gray", dot: "var(--mantine-color-gray-5)" },
  SCHEDULED: { color: "edr-green", dot: freightBrand.primary },
  DISPATCHED: { color: "teal", dot: "var(--mantine-color-teal-6)" },
  ARRIVED: { color: "blue", dot: "var(--mantine-color-blue-6)" },
  CANCELLED: { color: "red", dot: "var(--mantine-color-red-6)" },
};

export function statusMeta(status: string) {
  return STATUS_META[status] ?? STATUS_META.DRAFT;
}

/**
 * Status pill with a leading status dot — clearer at a glance than a plain
 * badge and consistent everywhere a schedule status appears.
 */
export function StatusPill({
  status,
  size = "sm",
}: {
  status: string;
  size?: "sm" | "md";
}) {
  const meta = statusMeta(status);
  const isMd = size === "md";
  return (
    <Group
      gap={isMd ? 8 : 6}
      wrap="nowrap"
      style={{
        display: "inline-flex",
        padding: isMd ? "5px 12px" : "3px 10px",
        borderRadius: 999,
        background: `var(--mantine-color-${meta.color}-0)`,
        border: `1px solid var(--mantine-color-${meta.color}-2)`,
      }}
    >
      <Box
        w={isMd ? 8 : 7}
        h={isMd ? 8 : 7}
        style={{
          borderRadius: 999,
          background: meta.dot,
          boxShadow: `0 0 0 3px var(--mantine-color-${meta.color}-1)`,
          flexShrink: 0,
        }}
      />
      <Text
        size={isMd ? "sm" : "xs"}
        fw={600}
        c={`${meta.color}.8`}
        style={{ letterSpacing: 0.2, lineHeight: 1 }}
      >
        {meta.label ?? status}
      </Text>
    </Group>
  );
}

/**
 * Compact metric tile used in hero strips. `onDark` flips colors for use on
 * the green hero gradient.
 */
export function StatTile({
  icon: Icon,
  label,
  value,
  hint,
  onDark = false,
  accent = freightBrand.primary,
  graph = "none",
  graphAccent = "emerald",
  graphPct,
}: {
  icon?: LucideIcon;
  label: string;
  value: ReactNode;
  hint?: ReactNode;
  onDark?: boolean;
  accent?: string;
  /** Optional decorative mini-graph at the bottom (ignored on dark tiles). */
  graph?: StatTileGraph;
  graphAccent?: OverviewAccent;
  /** Percentage 0..100 for the ring variant. */
  graphPct?: number | null;
}) {
  // Mini-graphs only render on light tiles (the gradient reads poorly on dark).
  const showGraph = graph !== "none" && !onDark;

  return (
    <Paper
      p="md"
      radius="lg"
      style={
        onDark
          ? {
              background: "rgba(255,255,255,0.12)",
              border: "1px solid rgba(255,255,255,0.18)",
              backdropFilter: "blur(6px)",
            }
          : {
              background: "var(--mantine-color-gray-0)",
              border: "1px solid var(--mantine-color-gray-2)",
            }
      }
    >
      <Stack gap={8}>
        <Group gap="sm" wrap="nowrap" align="center">
          {Icon ? (
            <Box
              style={{
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                width: 38,
                height: 38,
                borderRadius: 10,
                flexShrink: 0,
                background: onDark ? "rgba(255,255,255,0.16)" : `${accent}1a`,
                color: onDark ? "white" : accent,
              }}
            >
              <Icon size={18} />
            </Box>
          ) : null}
          <Stack gap={1} style={{ minWidth: 0, flex: 1 }}>
            <Text
              fw={800}
              size="lg"
              lh={1.05}
              c={onDark ? "white" : "dark.5"}
              style={{ whiteSpace: "nowrap" }}
            >
              {value}
            </Text>
            <Text
              size="xs"
              fw={600}
              c={onDark ? "rgba(255,255,255,0.75)" : "dimmed"}
              truncate
            >
              {label}
              {hint ? <Text component="span" size="xs" c="dimmed"> · {hint}</Text> : null}
            </Text>
          </Stack>
          {showGraph && graph === "ring" ? (
            <MiniRing pct={graphPct ?? 0} accent={graphAccent} size={42} stroke={5}>
              <Text size="9px" fw={800} c="dark.4">
                {Math.round(graphPct ?? 0)}%
              </Text>
            </MiniRing>
          ) : null}
        </Group>

        {showGraph && graph !== "ring" ? (
          <MiniSparkline
            variant={graph}
            accent={graphAccent}
            baseline={(graphPct ?? 50) / 100}
            seed={label}
            height={20}
          />
        ) : null}
      </Stack>
    </Paper>
  );
}

/**
 * Origin → destination corridor visual: two anchored stops joined by a rail
 * line. `variant="compact"` is for dense table rows; `default` for cards.
 */
export function RouteCorridor({
  origin,
  destination,
  variant = "default",
  onDark = false,
}: {
  origin?: string | null;
  destination?: string | null;
  variant?: "default" | "compact";
  onDark?: boolean;
}) {
  const compact = variant === "compact";
  const dim = onDark ? "rgba(255,255,255,0.7)" : "var(--mantine-color-gray-5)";
  const strong = onDark ? "white" : "var(--mantine-color-gray-8)";
  const lineColor = onDark ? "rgba(255,255,255,0.4)" : "var(--mantine-color-gray-3)";
  const accent = onDark ? "white" : freightBrand.primary;

  return (
    <Group gap={compact ? 6 : 8} wrap="nowrap" align="center" style={{ minWidth: 0 }}>
      <Box
        w={compact ? 7 : 9}
        h={compact ? 7 : 9}
        style={{
          borderRadius: 999,
          flexShrink: 0,
          border: `2px solid ${accent}`,
          background: onDark ? "transparent" : "white",
        }}
      />
      <Text
        size={compact ? "sm" : "sm"}
        fw={600}
        c={strong}
        style={{ whiteSpace: "nowrap" }}
      >
        {origin ?? "—"}
      </Text>
      <Box
        style={{
          flex: 1,
          minWidth: compact ? 16 : 24,
          height: 0,
          borderTop: `2px dashed ${lineColor}`,
          position: "relative",
        }}
      >
        <MapPin
          size={compact ? 11 : 13}
          color={dim}
          style={{
            position: "absolute",
            top: "50%",
            left: "50%",
            transform: "translate(-50%, -50%)",
            background: onDark ? "transparent" : "white",
          }}
        />
      </Box>
      <Text
        size={compact ? "sm" : "sm"}
        fw={600}
        c={strong}
        style={{ whiteSpace: "nowrap" }}
      >
        {destination ?? "—"}
      </Text>
      <Box
        w={compact ? 7 : 9}
        h={compact ? 7 : 9}
        style={{
          borderRadius: 999,
          flexShrink: 0,
          background: accent,
        }}
      />
    </Group>
  );
}
