export type GameSliceMode =
  | "station"
  | "undocking"
  | "flight"
  | "travel"
  | "mining"
  | "docking"
  | "services"
  | "combat";

export type LegacyGameSliceMode =
  | GameSliceMode
  | "map"
  | "warp"
  | "combat"
  | "market"
  | "fitting"
  | "refining";

export type SliceService = "refining" | "fitting" | "market";

export type SliceVec3 = [number, number, number];

export type SliceTargetKind = "station" | "asteroid_belt" | "manual" | "hostile";

export type SliceTarget = {
  id: string;
  name: string;
  kind: SliceTargetKind;
  systemId: string;
  poiId?: string;
  position: SliceVec3;
};

export type SliceOperation =
  | { kind: "undocking"; startedAt: number; durationMs: number }
  | {
      kind: "travel";
      targetSystemId: string;
      targetPoiId: string;
      targetPoiName: string;
      target: SliceTarget;
      fromPosition: SliceVec3;
      targetPosition: SliceVec3;
      startedAt: number;
      durationMs: number;
    }
  | { kind: "docking"; stationPoiId: string; stationName: string; startedAt: number; durationMs: number }
  | { kind: "mining"; ore: string; quantity: number; targetPoiId: string; targetName: string; repeat: boolean; startedAt: number; durationMs: number };

export type SliceObjectiveId =
  | "undock"
  | "navigate_to_belt"
  | "mine_ore"
  | "dock_at_station"
  | "refine_ore"
  | "fit_module"
  | "sell_goods"
  | "combat_trial";

export type SliceCargoItem = {
  item: string;
  category: "ore" | "mineral" | "loot" | "module";
  quantity: number;
  unitPrice: number;
};

export type SliceFittedModule = {
  id: string;
  name: string;
  type: string;
  slot: "high" | "med" | "low";
  cpu: number;
  power: number;
  active?: boolean;
};

export type SliceEvent =
  | { type: "station.undockStarted"; systemId: string; startedAt: number; durationMs: number }
  | { type: "station.dockStarted"; stationPoiId: string; stationName: string; startedAt: number; durationMs: number }
  | { type: "navigation.started"; targetSystemId: string; targetPoiId: string; targetPoiName: string; startedAt: number; durationMs: number }
  | { type: "navigation.targetSelected"; target: SliceTarget }
  | { type: "navigation.manualWaypointSelected"; target: SliceTarget }
  | { type: "navigation.approachStarted"; target: SliceTarget; fromPosition: SliceVec3; startedAt: number; durationMs: number }
  | { type: "navigation.arrived"; systemId: string; poiId: string; poiName: string }
  | { type: "station.docked"; systemId: string; stationPoiId: string; stationName: string }
  | { type: "station.undocked"; systemId: string }
  | { type: "mining.started"; ore: string; quantity: number; targetPoiId: string; targetName: string; repeat: boolean; startedAt: number; durationMs: number }
  | { type: "mining.completed"; ore: string; quantity: number }
  | { type: "mining.stopped" }
  | { type: "station.serviceOpened"; service: SliceService }
  | { type: "station.serviceClosed" }
  | { type: "refining.completed"; ore: string; inputQuantity: number; minerals: SliceCargoItem[] }
  | { type: "market.sold"; item: string; quantity: number; isk: number }
  | { type: "fitting.changed"; modules: SliceFittedModule[] }
  | { type: "combat.started" }
  | { type: "combat.victory"; targetName: string; bounty: number; loot: SliceCargoItem[] }
  | { type: "xp.awarded"; skill: string; amount: number }
  | { type: "zora.observed"; trigger: string };

export type GameSliceSession = {
  id: string;
  mode: GameSliceMode;
  currentSystemId: string;
  currentPoiId: string | null;
  dockedStationPoiId: string | null;
  dockedStationName: string | null;
  activeTravelSessionId: string | null;
  activeService: SliceService | null;
  activeOperation: SliceOperation | null;
  selectedTarget: SliceTarget | null;
  shipPosition: SliceVec3;
  navigationMessage: string | null;
  wallet: number;
  cargoCapacity: number;
  cargo: SliceCargoItem[];
  fittedModules: SliceFittedModule[];
  zoraModules: string[];
  skills: Record<string, { level: number; xp: number; nextLevel: number }>;
  completedObjectives: SliceObjectiveId[];
  activeObjectiveId: SliceObjectiveId;
  eventLog: Array<{ id: string; at: number; event: SliceEvent; message: string }>;
  updatedAt: number;
};
