import { addDays, differenceInCalendarDays, format, isAfter, isBefore, parseISO } from "date-fns";
import { fr } from "date-fns/locale";
import type { Document, Trip, TripStep } from "@/types";
import { getTripDayForLocalDate, toLocalDateKey } from "@/services/travelerCalendar";

const dateKey = toLocalDateKey;

export function getLocalDateKey(date = new Date()) { return dateKey(date); }

export function getTodayTripDay(trip: Trip, now = new Date()): number | null {
  return getTripDayForLocalDate(trip.startDate, trip.endDate, now);
}

export function getPublishedSteps(trip: Trip): TripStep[] {
  return trip.steps.filter((step) => step.isPublished === true);
}

export function getVisibleDocuments(trip: Trip): Document[] {
  const visibleStepIds = new Set(getPublishedSteps(trip).map((step) => step.id));
  return trip.documents.filter((document) => !document.stepId || visibleStepIds.has(document.stepId));
}

export function getTripDayCount(trip: Trip): number {
  return Math.max(1, differenceInCalendarDays(parseISO(trip.endDate), parseISO(trip.startDate)) + 1);
}

export function getDefaultTripDay(trip: Trip, now = new Date()): number {
  const today = dateKey(now);
  if (today < trip.startDate) return 1;
  if (today > trip.endDate) return getTripDayCount(trip);
  return differenceInCalendarDays(now, parseISO(trip.startDate)) + 1;
}

export function getTripDayLabel(trip: Trip, day: number): string {
  return format(addDays(parseISO(trip.startDate), day - 1), "EEE d MMM", { locale: fr });
}

export function getTravelerValidation(step: TripStep, travelerId: string) {
  return step.validations?.find((validation) => validation.travelerId === travelerId)?.status ?? step.validationStatus ?? "pending";
}

export function sortTravelerTrips(trips: Trip[], now = new Date()) {
  const today = dateKey(now);
  const current = trips.filter((trip) => trip.startDate <= today && trip.endDate >= today).sort((a, b) => a.endDate.localeCompare(b.endDate));
  const upcoming = trips.filter((trip) => isAfter(parseISO(trip.startDate), parseISO(today))).sort((a, b) => a.startDate.localeCompare(b.startDate));
  const past = trips.filter((trip) => isBefore(parseISO(trip.endDate), parseISO(today))).sort((a, b) => b.endDate.localeCompare(a.endDate));
  return { current, upcoming, past };
}

export function getNextStep(trip: Trip, now = new Date()): TripStep | undefined {
  if (dateKey(now) < trip.startDate || dateKey(now) > trip.endDate) return undefined;
  const day = getDefaultTripDay(trip, now);
  const time = format(now, "HH:mm");
  return getPublishedSteps(trip).find((step) => step.day === day && (step.startTime || step.time) >= time);
}

export function buildMapsUrl(location: string): string {
  return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(location)}`;
}
