export type RecapSkuRow = {
  machineName: string;
  sku: string;
  good: number;
  scrap: number;
  target: number | null;
  progressPct: number | null;
};

export type RecapMachine = {
  machineId: string;
  machineName: string;
  location: string | null;
  production: {
    goodParts: number;
    scrapParts: number;
    totalCycles: number;
    bySku: RecapSkuRow[];
  };
  oee: {
    avg: number | null;
    availability: number | null;
    performance: number | null;
    quality: number | null;
  };
  downtime: {
    totalMin: number;
    stopsCount: number;
    topReasons: Array<{
      reasonLabel: string;
      minutes: number;
      count: number;
    }>;
    ongoingStopMin: number | null;
  };
  workOrders: {
    completed: Array<{
      id: string;
      sku: string | null;
      goodParts: number;
      durationHrs: number;
    }>;
    active: {
      id: string;
      sku: string | null;
      progressPct: number | null;
      startedAt: string | null;
    } | null;
    moldChangeInProgress: boolean;
    moldChangeStartMs: number | null;
  };
  heartbeat: {
    lastSeenAt: string | null;
    uptimePct: number | null;
  };
};

export type RecapTimelineSegment =
  | {
      type: "production";
      startMs: number;
      endMs: number;
      durationSec: number;
      workOrderId: string | null;
      sku: string | null;
      label: string;
    }
  | {
      type: "mold-change";
      startMs: number;
      endMs: number;
      fromMoldId: string | null;
      toMoldId: string | null;
      durationSec: number;
      label: string;
    }
  | {
      type: "macrostop" | "microstop" | "slow-cycle";
      startMs: number;
      endMs: number;
      reason: string | null;
      reasonLabel?: string | null;
      durationSec: number;
      label: string;
    }
  | {
      type: "idle";
      startMs: number;
      endMs: number;
      durationSec: number;
      label: string;
    };

export type RecapTimelineResponse = {
  range: {
    start: string;
    end: string;
  };
  segments: RecapTimelineSegment[];
  hasData: boolean;
  generatedAt: string;
};

export type RecapResponse = {
  range: {
    start: string;
    end: string;
  };
  availableShifts: Array<{
    id: string;
    name: string;
  }>;
  machines: RecapMachine[];
};

export type RecapQuery = {
  orgId: string;
  machineId?: string;
  start?: Date;
  end?: Date;
  shift?: string;
};

export type RecapMachineStatus = "running" | "mold-change" | "stopped" | "offline" | "idle";

/**
 * Reason context — currently empty in practice because the only STOPPED cause
 * we can detect (given Node-RED's constraints) is machine_fault. Kept as a
 * struct so future expansion doesn't require a type change downstream.
 */
export type RecapStateContext = Record<string, never>;


export type RecapSummaryMachine = {
  machineId: string;
  name: string;
  location: string | null;
  status: RecapMachineStatus;
  oee: number | null;
  goodParts: number;
  scrap: number;
  stopsCount: number;
  lastSeenMs: number | null;
  lastActivityMin: number | null;
  offlineForMin: number | null;
  ongoingStopMin: number | null;
  stateContext: RecapStateContext;
  activeWorkOrderId: string | null;
  moldChange: {
    active: boolean;
    startMs: number | null;
    elapsedMin: number | null;
  } | null;
  miniTimeline: RecapTimelineSegment[];
};

export type RecapSummaryResponse = {
  generatedAt: string;
  range: {
    start: string;
    end: string;
    hours: number;
  };
  machines: RecapSummaryMachine[];
};

export type RecapRangeMode = "24h" | "shift" | "yesterday" | "custom";

export type RecapDowntimeTopRow = {
  reasonLabel: string;
  minutes: number;
  count: number;
  percent: number;
};

export type RecapWorkOrders = {
  completed: Array<{
    id: string;
    sku: string | null;
    goodParts: number;
    durationHrs: number;
  }>;
  active: {
    id: string;
    sku: string | null;
    progressPct: number | null;
    startedAt: string | null;
  } | null;
};

export type RecapMachineDetail = {
  machineId: string;
  name: string;
  location: string | null;
  status: RecapMachineStatus;
  oee: number | null;
  goodParts: number;
  scrap: number;
  stopsCount: number;
  stopMinutes: number;
  activeWorkOrderId: string | null;
  lastSeenMs: number | null;
  offlineForMin: number | null;
  ongoingStopMin: number | null;
  stateContext: RecapStateContext;
  moldChange: {
    active: boolean;
    startMs: number | null;
  } | null;
  timeline: RecapTimelineSegment[];
  productionBySku: RecapSkuRow[];
  downtimeTop: RecapDowntimeTopRow[];
  workOrders: RecapWorkOrders;
  heartbeat: {
    lastSeenAt: string | null;
    uptimePct: number | null;
    connectionStatus: "online" | "offline";
  };
};

export type RecapDetailResponse = {
  generatedAt: string;
  range: {
    requestedMode?: RecapRangeMode;
    mode: RecapRangeMode;
    start: string;
    end: string;
    shiftAvailable?: boolean;
    fallbackReason?: "shift-unavailable" | "shift-inactive";
  };
  machine: RecapMachineDetail;
};
