import { api as apiClient } from '../auth/http';

import { URL_CONSTANTS } from '@/constants/URLS';
import { ruleEngineService } from './ruleEngine/ruleEngine.service';

export type RouteStatus = 'AVAILABLE' | 'MAINTENANCE' | 'DAMAGED' | 'STOP_WORKING';

/** Frozen from yard countries: ET→DJ EXPORT, DJ→ET IMPORT, same country DOMESTIC (intercity, disabled). */
export type RouteDirection = 'IMPORT' | 'EXPORT' | 'DOMESTIC';

export interface YardRef {
  id: string;
  code: string;
  label: string;
  country?: string;
}

export interface RouteMilestone {
  id: string;
  routeId: string;
  yardId: string;
  sequenceNo: number;
  distanceKm?: number | null;
  yard?: YardRef | null;
}

export interface RouteRecord {
  id: string;
  status: RouteStatus;
  direction?: RouteDirection;
  originYardId: string;
  destinationYardId: string;
  originYard?: YardRef | null;
  destinationYard?: YardRef | null;
  milestones?: RouteMilestone[];
}

/** Segment km are resolved server-side from configured yard distances. */
export interface SaveRoutePayload {
  milestones: Array<{ yardId: string }>;
  status?: RouteStatus;
}

/**
 * Human-readable route label: yard names, not yard codes. Staff read
 * "Addis Ababa → Dire Dawa", not "ADDIS_ABABA → DIRE_DAWA". Falls back to the
 * code only when a yard has no label.
 *
 * When milestones are present they ARE the full ordered corridor (origin first,
 * destination last), so the label shows every stop:
 * "Addis Ababa → Adama → Dire Dawa".
 */
export function formatRouteLabel(route: RouteRecord): string {
  const stops = [...(route.milestones ?? [])]
    .sort((a, b) => a.sequenceNo - b.sequenceNo)
    .map((m) => m.yard?.label ?? m.yard?.code)
    .filter((name): name is string => Boolean(name));
  if (stops.length >= 2) return stops.join(' → ');

  const origin =
    route.originYard?.label ?? route.originYard?.code ?? 'Origin';
  const dest =
    route.destinationYard?.label ?? route.destinationYard?.code ?? 'Destination';
  return `${origin} → ${dest}`;
}

export function totalRouteDistanceKm(route: RouteRecord): number {
  return (route.milestones ?? []).reduce(
    (sum, m) => sum + Number(m.distanceKm ?? 0),
    0,
  );
}

export const ROUTE_STATUS_OPTIONS: Array<{ value: RouteStatus; label: string }> = [
  { value: 'AVAILABLE', label: 'Available' },
  { value: 'MAINTENANCE', label: 'Maintenance' },
  { value: 'DAMAGED', label: 'Damaged' },
  { value: 'STOP_WORKING', label: 'Stop working' },
];

export const routesService = {
  getAll: (params?: { status?: RouteStatus; search?: string }) =>
    apiClient.get<RouteRecord[]>(URL_CONSTANTS.ROUTES.BASE, { params }),
  getById: (id: string) => apiClient.get<RouteRecord>(URL_CONSTANTS.ROUTES.BY_ID(id)),
  create: (data: SaveRoutePayload) => apiClient.post(URL_CONSTANTS.ROUTES.BASE, data),
  update: (id: string, data: Partial<SaveRoutePayload>) =>
    apiClient.patch(URL_CONSTANTS.ROUTES.BY_ID(id), data),
  deactivate: (id: string) => apiClient.delete(URL_CONSTANTS.ROUTES.BY_ID(id)),
  /** All active yards (page-walked — the yards list API caps pageSize at 100). */
  getYards: async (): Promise<YardRef[]> => {
    const rows = await ruleEngineService.listAll("yards", { isActive: true });
    return rows as unknown as YardRef[];
  },
};
