import { sites } from "@/data/mock/sites";
import { seedVehicles } from "@/data/mock/vehicles";
import type {
  FleetSnapshot,
  SimulateEventPayload,
  VehicleMaster,
} from "@/lib/fleet/types";

const FLEET_ID = "fleet-muc-demo-001";
const FLEET_NAME = "Autohaus München Fleet (Demo)";

function cloneVehicles(): VehicleMaster[] {
  return structuredClone(seedVehicles);
}

let vehicles = cloneVehicles();

export function getSnapshot(): FleetSnapshot {
  return {
    fleetInventoryId: FLEET_ID,
    fleetName: FLEET_NAME,
    sites: structuredClone(sites),
    vehicles: structuredClone(vehicles),
    generatedAt: new Date().toISOString(),
  };
}

export function getVehicle(vin: string): VehicleMaster | undefined {
  const v = vehicles.find((x) => x.vin === vin);
  return v ? structuredClone(v) : undefined;
}

export function resetStore(): FleetSnapshot {
  vehicles = cloneVehicles();
  return getSnapshot();
}

function bumpTimestamp(iso?: string): string {
  return new Date().toISOString();
}

function mutateLocation(v: VehicleMaster): void {
  const site = sites.find((s) => s.id === v.expectedSiteId) ?? sites[0]!;
  // Nudge toward or away from expected zone center
  const zone = site.zones.find((z) => z.id === v.expectedZoneId) ?? site.zones[0]!;
  const [lat, lng] = zone.polygon[0]!;
  const drift = Math.random() > 0.5 ? 0.0004 : 0.008;
  const sign = Math.random() > 0.5 ? 1 : -1;
  v.location = {
    type: "Feature",
    geometry: {
      type: "Point",
      coordinates: [lng + sign * drift, lat + sign * drift * 0.6, 520],
    },
    properties: {
      heading: Math.floor(Math.random() * 360),
      timestamp: bumpTimestamp(),
    },
  };
  v.availability.timestamp = bumpTimestamp();
}

function mutateExterior(v: VehicleMaster): void {
  const open = Math.random() > 0.5;
  v.exterior = {
    ...v.exterior,
    timestamp: bumpTimestamp(),
    centralLock: open ? "UNLOCKED" : "LOCKED",
    frontLeftDoor: open ? "OPEN" : "CLOSED",
    rearRightWindow: open && Math.random() > 0.5 ? "OPEN" : "CLOSED",
  };
}

function mutateBattery(v: VehicleMaster): void {
  if (!v.battery) return;
  const delta = Math.floor(Math.random() * 12) - 4;
  const next = Math.min(
    100,
    Math.max(5, v.battery.batteryChargeLevelPercentage + delta),
  );
  const statuses = ["IDLE", "CHARGING", "ERROR", "DONE"] as const;
  v.battery = {
    ...v.battery,
    timestamp: bumpTimestamp(),
    batteryChargeLevelPercentage: next,
    estimatedDistanceToEmptyKm: Math.round(next * 4.2),
    chargingStatus: statuses[Math.floor(Math.random() * statuses.length)]!,
    chargerConnectionStatus:
      Math.random() > 0.6 ? "CONNECTED" : "DISCONNECTED",
  };
}

export function simulateEvent(payload: SimulateEventPayload = {}): VehicleMaster {
  const kind = payload.kind ?? "random";
  const pool = payload.vin
    ? vehicles.filter((v) => v.vin === payload.vin)
    : vehicles;
  if (!pool.length) throw new Error("VIN nicht gefunden");

  const target = pool[Math.floor(Math.random() * pool.length)]!;
  const resolved =
    kind === "random"
      ? (["location", "exterior", "battery"] as const)[
          Math.floor(Math.random() * 3)
        ]!
      : kind;

  if (resolved === "location") mutateLocation(target);
  else if (resolved === "exterior") mutateExterior(target);
  else mutateBattery(target);

  target.inventory.updatedAt = bumpTimestamp();
  return structuredClone(target);
}
