import { Center, Loader, Modal, Text, Timeline } from "@mantine/core";
import { useQuery } from "@tanstack/react-query";
import {
  Activity,
  CircleDot,
  Route,
  Truck,
  UserCheck,
  UserMinus,
  UserPlus,
} from "lucide-react";

import {
  fleetHistoryService,
  type FleetHistoryEvent,
} from "@/services/fleet-history.service";
import type { FleetRecord } from "@/services/fleet/fleet.service";

export interface FleetHistoryModalProps {
  opened: boolean;
  onClose: () => void;
  entity: "driver" | "vehicle";
  record: FleetRecord | null;
}

const asObj = (r: FleetRecord | null) => (r ?? {}) as Record<string, unknown>;

const titleFor = (entity: "driver" | "vehicle", record: FleetRecord | null) => {
  const r = asObj(record);
  if (entity === "vehicle") {
    return `Vehicle history — ${r.plateNumber ?? r.code ?? ""}`.trim();
  }
  return `Driver history — ${[r.firstName, r.lastName]
    .filter(Boolean)
    .join(" ")}`.trim();
};

const mileLabel = (e: FleetHistoryEvent) =>
  e.metadata?.mile === "LAST" ? "Last-mile" : "First-mile";

const arrow = (from?: string | null, to?: string | null) =>
  `${from ?? "—"} → ${to ?? "—"}`;

const metaStr = (e: FleetHistoryEvent, key: string) => {
  const v = e.metadata?.[key];
  return typeof v === "string" && v ? v : null;
};

function describe(e: FleetHistoryEvent, entity: "driver" | "vehicle") {
  const vehiclePlate = metaStr(e, "vehiclePlate");
  const driverName = metaStr(e, "driverName") ?? (e.label || null);
  const bookingRef = metaStr(e, "bookingRef");

  // Compose the detail line with whatever the current view doesn't already
  // know: on a driver's timeline show which vehicle; always show the booking.
  const detail = (extra?: string) =>
    [
      entity === "driver" && vehiclePlate ? `Vehicle ${vehiclePlate}` : "",
      bookingRef ? `Booking ${bookingRef}` : "",
      extra ?? "",
    ]
      .filter(Boolean)
      .join(" · ");

  switch (e.eventType) {
    case "DRIVER_REGISTERED":
      return {
        icon: <UserCheck size={14} />,
        title: "Driver registered",
        text: e.toValue ? `Status: ${e.toValue}` : "",
      };
    case "VEHICLE_REGISTERED":
      return {
        icon: <Truck size={14} />,
        title: "Vehicle registered",
        text: e.toValue ? `Availability: ${e.toValue}` : "",
      };
    case "DRIVER_ASSIGNED":
      return {
        icon: <UserPlus size={14} />,
        title: entity === "vehicle" ? "Driver assigned" : "Assigned to vehicle",
        text:
          entity === "vehicle"
            ? driverName
              ? `Driver ${driverName}`
              : ""
            : vehiclePlate
              ? `Vehicle ${vehiclePlate}`
              : "",
      };
    case "DRIVER_UNASSIGNED":
      return {
        icon: <UserMinus size={14} />,
        title:
          entity === "vehicle"
            ? "Driver unassigned"
            : "Unassigned from vehicle",
        text:
          entity === "vehicle"
            ? driverName
              ? `Driver ${driverName}`
              : ""
            : vehiclePlate
              ? `Vehicle ${vehiclePlate}`
              : "",
      };
    case "VEHICLE_STATUS_CHANGED":
      return {
        icon: <CircleDot size={14} />,
        title: "Status changed",
        text: arrow(e.fromValue, e.toValue),
      };
    case "VEHICLE_AVAILABILITY_CHANGED":
      return {
        icon: <Activity size={14} />,
        title: `Marked ${e.toValue ?? ""}`.trim(),
        text: e.fromValue ? arrow(e.fromValue, e.toValue) : "",
      };
    case "MILE_VEHICLE_ASSIGNED":
      return {
        icon: <Route size={14} />,
        title: `${mileLabel(e)}: vehicle assigned`,
        text: detail(e.label ? `Status: ${e.label}` : ""),
      };
    case "MILE_VEHICLE_RELEASED":
      return {
        icon: <Route size={14} />,
        title: `${mileLabel(e)}: vehicle released`,
        text: detail(),
      };
    case "MILE_STATUS_CHANGED":
      return {
        icon: <Route size={14} />,
        title: `${mileLabel(e)} status`,
        text: detail(arrow(e.fromValue, e.toValue)),
      };
    default:
      return { icon: <CircleDot size={14} />, title: e.eventType, text: "" };
  }
}

const fmt = (iso: string) => {
  const d = new Date(iso);
  return Number.isNaN(d.getTime()) ? iso : d.toLocaleString();
};

const FleetHistoryModal = ({
  opened,
  onClose,
  entity,
  record,
}: FleetHistoryModalProps) => {
  const id = asObj(record).id ? String(asObj(record).id) : "";

  const { data, isLoading } = useQuery({
    queryKey: ["fleet-history", entity, id],
    queryFn: () =>
      entity === "vehicle"
        ? fleetHistoryService.vehicle(id)
        : fleetHistoryService.driver(id),
    enabled: opened && Boolean(id),
  });

  const events = data ?? [];

  return (
    <Modal
      opened={opened}
      onClose={onClose}
      title={<Text fw={600}>{titleFor(entity, record)}</Text>}
      radius="lg"
      size="lg"
      centered
    >
      {isLoading ? (
        <Center py="xl">
          <Loader size="sm" />
        </Center>
      ) : events.length === 0 ? (
        <Text c="dimmed" ta="center" py="lg" size="sm">
          No history recorded yet. Activity appears here as this{" "}
          {entity} is assigned, reassigned, or its status changes.
        </Text>
      ) : (
        <Timeline active={events.length} bulletSize={24} lineWidth={2}>
          {events.map((e) => {
            const d = describe(e, entity);
            return (
              <Timeline.Item key={e.id} bullet={d.icon} title={d.title}>
                {d.text && (
                  <Text size="sm" c="dimmed">
                    {d.text}
                  </Text>
                )}
                <Text size="xs" mt={4} c="dimmed">
                  {fmt(e.createdAt)}
                </Text>
              </Timeline.Item>
            );
          })}
        </Timeline>
      )}
    </Modal>
  );
};

export default FleetHistoryModal;
