import { api } from '../auth/http';
import { URL_CONSTANTS } from '@/constants/URLS';

export const FIRST_MILE_STATUSES = [
  'PAYMENT_PENDING',
  'READY_TO_TRANSIT',
  'IN_TRANSIT',
  'RECEIVED_TO_PORT',
] as const;
export type FirstMileApiStatus = (typeof FIRST_MILE_STATUSES)[number];

export interface FirstMileBooking {
  id: string;
  reference: string;
  firstMilePickupAddress?: string | null;
  cargoFreeText?: string | null;
  cargoTotalWeightVgm: number;
  totalAmount: number;
  paymentCurrency?: string | null;
  scheduledDate?: string | null;
  company?: { id: string; name?: string; phone?: string | null; contactPersonName?: string | null; contactPersonPhone?: string | null } | null;
  serviceType?: { id: string; label?: string } | null;
  originYard?: { id: string; label?: string } | null;
  destinationYard?: { id: string; label?: string } | null;
  cargoType?: { id: string; label?: string; cargoTypeName?: string; name?: string } | null;
  freightType?: string | null;
  /** Attached server-side: the train schedule this booking rides. */
  trainSchedule?: { trainNumber: string | null; departureDate: string | null } | null;
  /** Container lines — total container count drives how many trucks are needed. */
  bookingContainers?: Array<{
    id: string;
    quantity: number;
    containerNumber?: string | null;
    containerSize?: string | null;
    containerType?: { id: string; name?: string; label?: string; code?: string } | null;
    /** Physical containers under this line — their real numbers (line-level
     *  containerNumber is often a TBD placeholder). */
    units?: Array<{ id: string; containerNumber?: string | null; sortOrder?: number }>;
  }>;
}

export interface FirstMileVehicle {
  id: string;
  plateNumber: string;
  manufacturer: string;
  model: string;
  vehicleType?: string | null;
  code?: string | null;
  powerPlateNo?: string | null;
  trailerPlateNo?: string | null;
  assignedDriverId?: string | null;
  assignedDriverName?: string | null;
  pricePerKm?: number | string | null;
  currency?: string | null;
}

export interface FirstMileRecord {
  id: string;
  bookingId: string;
  status: FirstMileApiStatus;
  advancedPayment: number;
  remainingPayment: number;
  estimatedKm?: number | null;
  exactKm?: number | null;
  vehicleId?: string | null;
  booking?: FirstMileBooking | null;
  vehicle?: FirstMileVehicle | null;
  /** Full set of vehicles serving this pickup (multi-truck). */
  vehicleAssignments?: Array<{
    id: string;
    vehicleId: string;
    containerNumber?: string | null;
    distanceKm?: number | null;
    tons?: number | null;
    quantity?: number | null;
    vehicle?: FirstMileVehicle | null;
  }>;
  /** Present only when an invoice has actually been generated (not on distance). */
  invoice?: { id: string; number: string; status: string } | null;
  createdAt: string;
  updatedAt: string;
}

export interface FirstMileListResponse {
  data: FirstMileRecord[];
  meta: { total: number; page: number; pageSize: number; totalPages: number };
}

const FM = URL_CONSTANTS.FIRST_MILE;

export const firstMileService = {
  list: (pageSize = 1000) =>
    api.get<FirstMileListResponse>(`${FM.BASE}?pageSize=${pageSize}`),
  getById: (id: string) => api.get<FirstMileRecord>(FM.BY_ID(id)),
  update: (id: string, data: { status?: FirstMileApiStatus; vehicleId?: string | null; estimatedKm?: number | null; exactKm?: number | null; paid?: boolean }) =>
    api.patch<FirstMileRecord>(FM.BY_ID(id), data),
  accept: (bookingReference: string) =>
    api.post<FirstMileRecord>(FM.ACCEPT(bookingReference)),
  remove: (id: string) =>
    api.delete<void>(FM.BY_ID(id)),
  setVehicles: (
    id: string,
    vehicles: Array<{
      vehicleId: string;
      containerNumber?: string | null;
      tons?: number | null;
      quantity?: number | null;
    }>,
  ) => api.post<FirstMileRecord>(`${FM.BASE}/${id}/vehicles`, { vehicles }),
  setDistances: (
    id: string,
    distances: Array<{ vehicleId: string; distanceKm: number }>,
    remainingPayment?: number,
  ) => api.post<FirstMileRecord>(`${FM.BASE}/${id}/distances`, { distances, remainingPayment }),
  generateInvoice: (id: string) =>
    api.post<{ id: string; invoiceNumber?: string } | null>(`${FM.BASE}/${id}/invoice`),
};
