import { Driver } from "../sections/chauffeur/planingChauffeur/types";
import { PeriodOfDay } from "./ammendment-passenger";
import { AddressData } from "./common";
import { Address } from "./establishment";
import { DaysOfWeek, WeekType } from "./passenger";
import { EtatTrajet, TypeTrajet } from "./trajet";

export enum SensTrip {
  DEPARTURE = 'DEPARTURE',
  RETURN = 'RETURN'
}

export enum CircuitState {
  CONTROLLED = 'CONTROLLED',
  UNCONTROLLED = 'UNCONTROLLED',
  ON_HOLD = 'ON_HOLD',
  UPDATED = 'UPDATED'
}

export type ICircuit = {
  id: string,
  etat: string,
  codeCircuit: string,
  intitule: string,
  clientDO?: string,
  chauffeur: string,
  type?: string,
  dateDebut: string,
  dateDernierAvenant: string,
  dateFin: string,
  etablissement: string,
  adresseEtablissement: AddressData,
  numeroContrat: string,
  departement: string,
  isActive: boolean;
  typeCalcul?: string;
  grillePrix?: string;
  colorCode?: string;
  observation?: string;
  numeroLot: string;
  dureeTrajet?: string;
};

export type IcircuitTrajet = {
  id: string,
  numeroTrajet: string;
  preparation: string;
  dateDebut: string;
  intitule: string;
  sensAR: Sens;
  ets: string;
  kmEtTemps: string;
  usagers: string[];
  codeTrajetCircuit: string;
  circuit: string;
  etat: EtatTrajet;
  chauffeur: string;
}

export interface IAvenant {
  id: string;
  dateApplication: string;
  etat: string;
  codeCircuit: string;
  codeAvenant: string;
  intitule: string;
  objetAvenant: string;
  type: string;
  dateFin: string;
  etablissement: string;
  chauffeur: string;
  departement: string;
  clientDO: string;
  isActive: boolean;
  objet?: string;
  typeCalcul?: string;

}

export enum Sens {
  Aller = 'aller',
  Retour = 'retour',
}
export enum TripType {
  NORMAL = 'NORMAL',
  PERSONALIZED = 'PERSONALIZED',
}
export enum PeriodOfDayTripShort {
  MORNING = 'Matin',
  EVENING = 'Soir',
  MIDI = 'Midi'
}
export enum Etat {
  NonControle = 'non_controle',
  Controle = 'controle',
}

export interface GenerateTripStatusDTO {
  disabled: boolean;
  reason: string;
}

export type IPreparationCircuit = {
  id: string,
  codeCircuit: string,
  intitule: string,
  dateDebut: string,
  dateFin: string,
  etablissement: string,
  etat?: string,
  kmAVide?: string,
  typeCalcul?: string,
  adresseEtablissement: AddressData,
  colorCode?: string,
  toll?: string,
  usagers?: string[],
  observation?: string,
};


// Backend Interfaces
export interface Circuit extends BaseDocument {
  circuitState: CircuitState;
  circuitCode: string;
  titled: string;
  driverName: string;
  startDate: string;
  endDate: string;
  lastAmendmentDate: string;
  establishmentName: string;
  establishmentAddress: string;
  contractId: number;
  contract: string;
  lotIds: string[];
  lotNames: string[];
  departmentName: string;
  timeTolerance: number;
  isSupported: boolean;
  isBilled: boolean;
  clientId: number;
  departmentId: number;
  calculationType: CalculationType;
  priceGrid: number;
  colorCode: string;
  isInternal: boolean;
  observation: string;
  mainDriver: number | null;
  mainEstablishment: number;
  active: boolean;
  idDocs: number[];
}
export interface SearchCircuitParams {
  id?: string;
  circuitCode?: string;
  circuitState?: CircuitState;
  driverName?: string;
  startDate?: string;
  endDate?: string;
  establishmentName?: string;
  contractCode?: number;
  lotNumber?: string;


  titled?: string;
  supported?: boolean;
  calculationType?: CalculationType;
  minPriceGrid?: number;
  colorCode?: string;
  billed?: boolean;
  internal?: boolean;
  observation?: string;
  active?: boolean;

  createdAt?: string;
  updatedAt?: string;
  sortBy?: string;
  sortDirection?: 'asc' | 'desc';
  page?: number;
  size?: number;
}

export interface BaseDocument {
  id: string;
  createdAt: string;
  updatedAt: string;
}


export enum CalculationType {
  URBAN = 'URBAN',
  RURAL = 'RURAL'
}

export interface SaveCircuit {
  circuitState: CircuitState;
  circuitCode: string;
  timeTolerance: number;
  titled: string;
  startDate: string;
  endDate: string;
  mainDriver: number | null;
  mainEstablishment: number;
  observation: string;
  contractId: number;
  colorCode: string;
  calculationType: CalculationType;
  lotIds: string[];
}

export interface CircuitAssignmentRequest {
  passengerIds: number[];
  circuitId: string;
}

export const circuitStateOptions = [
  { value: CircuitState.CONTROLLED, label: 'Contrôlé' },
  { value: CircuitState.UNCONTROLLED, label: 'Non contrôlé' },
  { value: CircuitState.ON_HOLD, label: 'En attente' },
  { value: CircuitState.UPDATED, label: 'Mis à jour' }
];

export const calculationTypeOptions = [
  { value: CalculationType.URBAN, label: 'Calcul pour les Coûts' },
  { value: CalculationType.RURAL, label: 'Autres calculs' }
];

export interface ITripDriverAssignment extends BaseDocument {
  assignmentStartDate: string;
  assignmentEndDate: string;
  tripId: string | string[];
  driverId: number;
  replacedByDriverId: number;
  observations: string;
  isActive: boolean;
  weeklyAssignmentSchedule: WeekTypeSchedule[];
}

export interface ITripDriverAssignmentDetails extends BaseDocument {
  tripId: string;
  tripTitled: string;
  driverId: number;
  driverName: string;
  assignmentStartDate: string;
  assignmentEndDate: string;
  weeklyAssignmentSchedule: WeekTypeSchedule[];
  observations: string;
}
export interface ITripDriverAssignmentList extends BaseDocument {
  id: string;
  tripTitled: string;
  driverName: string;
  startHour: string;
  endHour: string;
  weeklyAssignmentSchedule: WeekTypeSchedule[];
  assignmentStartDate: string;
  assignmentEndDate: string;
  observations: string;
}
export interface ITripShort extends BaseDocument {
  tripTitled: string;
  circuitTitled: string;
  circuitCode: string;
  sensTrip: SensTrip;
  tripType: TripType;
  periodOfDay: PeriodOfDayTripShort;
}

export interface WeekTypeSchedule {
  weekType: WeekType;
  periods: DaySchedule[];
}

export interface DaySchedule {
  dayOfWeek: DaysOfWeek;
  periodOfDay: PeriodOfDay;
}

export interface AddPassengerToCircuit {
  circuitId: string;
  passengersIds: number[];
}

export interface RemovePassengerFromCircuit {
  circuitId: string;
  passengerId: number;
}

export interface AddPassengersToCircuitResponse {
  passengerId: number;
  firstName: string;
  lastName: string;
  birthDate: string;
  birthPlace: string;
  establishmentName: string;
  schoolClass: string;
  canDelete: boolean
}

export interface WeekdayPeriodObservationDTO {
  dayOfWeek: DaysOfWeek[];
  periodOfDay: PeriodOfDay;
}

export interface WeekTypeScheduleObservationDTO {
  weekType: WeekType;
  periods: WeekdayPeriodObservationDTO[];
}

export interface EstablishmentInfoTripDTO {
  establishmentCoordinates: Coordinates;
  arrivalTime: string;
  establishmentName: string;
  establishmentPhoneNumber?: string;
  establishmentAddress?: AddressData;
}

export interface PassengerInfoTripDTO {
  passengerId: number;
  passengerName: string;
  pickupCoordinates: Coordinates;
  departureTime: string;
  representativePhoneNumber?: string;
  passengerAddress?: AddressData;
}

export interface TripCircuitDaysDTO extends BaseDocument {
  passengerInfoTrip: PassengerInfoTripDTO;
  establishmentInfoTrip: EstablishmentInfoTripDTO;
  observationSchedule: WeekTypeScheduleObservationDTO[];
}

export interface TripCircuitDTO extends BaseDocument {
  circuitTitled: string;
  sensTrip: SensTrip;
  distanceKm: number;
  duration: string;
  passengerInfo: PassengerInfo[];
  tripTitled: string;
  circuitCode: string;
  tripState: TripState;
  tripCircuitDays: TripCircuitDaysDTO[];
  passengerCount: number;
}

export interface PassengerInfo {
  name: string;
  id: number;
}

export enum TripState {
  CONTROLLED = 'CONTROLLED',
  UNCONTROLLED = 'UNCONTROLLED',
  MODIFIED = 'MODIFIED'
}

export const tripStateOptions = [
  { value: TripState.CONTROLLED, label: 'Contrôlé' },
  { value: TripState.UNCONTROLLED, label: 'Non contrôlé' },
  { value: TripState.MODIFIED, label: 'Modifié' }
];

export const sensTripOptions = [
  { value: SensTrip.DEPARTURE, label: 'Aller' },
  { value: SensTrip.RETURN, label: 'Retour' }
];

export const tripTypeOptions = [
  { value: TypeTrajet.personnalise, label: "Trajet personnalisé" },
  { value: TypeTrajet.Normal, label: "Trajet normal" },
];

export interface TripCircuitDetails extends BaseDocument {
  tripTitled: string;
  tripState: TripState;
  lastAmendmentDate: string;
  circuitTitled: string;
  tripType: string;
  customizedDate: string;
  hasTolls: boolean;
  sens: SensTrip;
  rotation: boolean;
  routeSheetNote: string;
  tripObservation: string;
  weeklySchedules: WeekTypeSchedule[];
  duration: string;
  distanceKm: number;
  shortestPath: any;
  tripHour: string;
  tripPoints: TripPointDetails[];
  contractShortResponseDTO: ContractShortResponseDTO;
  lot: LotDTO;
  driver?: string
}

export interface RouteToNext {
  distance: number;
  duration: number;
}

export interface ContractShortResponseDTO extends BaseDocument {
  title: string;
  contractCode: string;
  contractColor: string;
}

export interface LotDTO {
  id: number;
  lotNumber: string;
}

export interface TripPointDetails extends BaseDocument {
  routeToNext: RouteToNext;
  passengerDetailsTrip: PassengerDetailsTripDTO;
}
export interface PassengerDetailsTripDTO {
  fullName: string;
  establishmentName: string;
  pickupTime: string;
  startCoordinates: Coordinates;
}
export interface Coordinates {
  latitude: number;
  longitude: number;
}

export interface PassengerCircuitSearchDTO extends BaseDocument {
  firstName: string;
  lastName: string;
}

export interface GetPassengerDetailsRequestDTO {
  passengerId: number;
  weeklySchedules: WeekTypeSchedule[];
}

export interface GetPassengerDetailsResponseDTO {
  establishmentId: number;
  establishmentName: string;
  address: Address;
}

export interface TripDTO extends BaseDocument {
  startDate: string;
  tripTitle: string;
  tripDirection: SensTrip;
  isRotation: boolean;
  numberOfPassengers: number;
  numberOfEstablishments: number;
  circuitState: CircuitState;
  hasTolls: boolean;
  agencyName: string;
  client: string;
  tripType: TripType;
  isActive: boolean;
  circuitCode: string;
  circuitId: string;
  colorCode: string;
}

export interface TripListParams {
  id?: string;
  createdAt?: string;
  startDate?: string;
  title?: string;
  tripDirection?: SensTrip;
  isRotation?: boolean;
  hasTolls?: boolean;
  tripType?: TripType;
  sortBy?: string;
  sortDirection?: 'ASC' | 'DESC';
  page?: number;
  size?: number;
}

export interface TripDriverAssignmentSearchParams {
  circuitId: string;
  id?: string;
  tripTitled?: string;
  driverName?: string;
  assignmentStartDate?: string;
  assignmentEndDate?: string;
  startHour?: string;
  endHour?: string;
  sortBy?: string;
  sortDirection?: 'ASC' | 'DESC';
  page?: number;
  size?: number;
}

export interface DriverAssignmentRequestDTO {
  tripId?: string;
  circuitId?: string;
  maxDrivers?: number;
  maxDistanceKm?: number;
  startDate: string;
  endDate: string;
  schedules: WeekTypeSchedule[];
}

export interface WorkingHour {
  id: number;
  dayOfWeek: number;
  startHour: number;
  endHour: number;
}

export interface VehicleInfo {
  id: number;
  vehiculeName: string;
  seatCount: number;
  wheelchairSeats: number;
  supportsWheelchair: boolean;
}
export interface DriverScore {
  driverId: string;
  driverName: string;
  rank: number;
  emptyDistanceKm: number;
  currentPosition?: Coordinates;
  homeLat?: number;
  homeLng?: number;
  email?: string;
  phoneNumber?: string;
  hasActiveCircuit?: boolean;
  hasApplication?: boolean;
  vehicle?: VehicleInfo | null;
  workingHours?: WorkingHour[];
}

export interface TripRankingResponse {
  tripId: string;
  rankedDrivers: DriverScore[];
}

export interface CircuitRankingResponse {
  circuitId: string;
  globalRanking: DriverScore[];
}
export interface MultipleTripsRankingResponse {
  tripIds: string[];
  globalRanking: DriverScore[];
}

export interface ExportCircuitParams {
  id?: string;
  circuitCode?: string;
  circuitState?: CircuitState;
  titled?: string;
  isSupported?: boolean;
  calculationType?: CalculationType;
  minPriceGrid?: number;
  colorCode?: string;
  isBilled?: boolean;
  isInternal?: boolean;
  establishmentName?: string;
  driverName?: string;
  contractCode?: number;
  startDateAfter?: string;
  endDateBefore?: string;
  observation?: string;
  isActive?: boolean;
  createdAfter?: string;
  updatedBefore?: string;
  lastAmendmentDate?: string;
  userId: number;
}

export interface ExportTripParams {
  id?: string;
  startDate?: string;
  title?: string;
  tripDirection?: SensTrip;
  isRotation?: boolean;
  hasTolls?: boolean;
  tripType?: TripType;
  userId: number;
}

export interface DailyTripListParams {
  id?: string;
  title?: string;
  sens?: SensTrip;
  isAssigned?: boolean;
  numUsager?: number;
  establishment?: string;
  driverName?: string;
  vehicle?: string;
  tripType?: TripType;
  page?: number;
  size?: number;
  sortBy?: string;
  sortDirection?: 'asc' | 'desc';
}
export interface DailyTripDTO {
  id: string;
  title: string;
  numUsager: number;
  isAssigned: boolean;
  driverName: string;
  establishment: string;
  tripType: TripType;
  sens: SensTrip;
  vehicle: string;
  date?: string;
}

export enum DriverFilterType {
  ALL = 'ALL',
  WITH_CIRCUIT = 'WITH_CIRCUIT',
  WITHOUT_CIRCUIT = 'WITHOUT_CIRCUIT',
  WITH_APPLICATION = 'WITH_APPLICATION'
}

export interface DriverSearchRequestDTO {
  filterTypes: DriverFilterType[];
  searchRadius: number;
  startDate: string; // Format: YYYY-MM-DD
  endDate: string;   // Format: YYYY-MM-DD
  tripId?: string;
  circuitId?: string;
}

export interface DriverMapResponseDTO {
  driverId: number;
  fullName: string;
  email: string;
  phoneNumber: string | null;
  latitude: number;
  longitude: number;
  distanceFromCenter: number;
  emptyKm: number | null;
  hasActiveCircuit: boolean;
  hasApplication: boolean;
  score: number | null;
}