import type { ApiRoute, MockTrip, SeatClass } from "@/config/booking-config";
import type { PublicPaymentSettings } from "@/config/booking-payment";
import type { BookerInfo, PassengerInfo } from "@/components/booking/booking-types";
import type { BookingTripType } from "@/config/booking-config";

declare global {
  interface Window {
    datvetauBookingConfig?: {
      restUrl: string;
      nonce: string;
    };
  }
}

function config() {
  const c = window.datvetauBookingConfig;
  if (!c?.restUrl) {
    throw new Error("datvetauBookingConfig chưa được cấu hình.");
  }
  return c;
}

async function apiGet<T>(path: string, query?: Record<string, string>): Promise<T> {
  const { restUrl, nonce } = config();
  const url = new URL(path.replace(/^\//, ""), restUrl.endsWith("/") ? restUrl : `${restUrl}/`);
  if (query) {
    Object.entries(query).forEach(([k, v]) => url.searchParams.set(k, v));
  }
  const res = await fetch(url.toString(), {
    headers: { "X-WP-Nonce": nonce },
    credentials: "same-origin",
  });
  if (!res.ok) {
    throw new Error(`API ${path} failed: ${res.status}`);
  }
  return res.json() as Promise<T>;
}

export type ApiTripRow = {
  id: string;
  routeId: string;
  routeLabel: string;
  date: string;
  dateIso: string;
  departure: string;
  arrival: string;
  operator: string;
  operatorLogo: string;
  priceVnd: number;
  priceChildVnd: number;
  priceSeniorVnd: number;
  availability: "available" | "sold_out";
  seatsRemaining: number;
};

export function mapApiTrip(row: ApiTripRow, direction: "a-to-b" | "b-to-a"): MockTrip {
  return {
    id: row.id,
    routeId: row.routeId,
    direction,
    routeLabel: row.routeLabel,
    date: row.date,
    departure: row.departure,
    arrival: row.arrival,
    operator: row.operator,
    operatorLogo: row.operatorLogo,
    priceVnd: row.priceVnd,
    priceChildVnd: row.priceChildVnd ?? 0,
    priceSeniorVnd: row.priceSeniorVnd ?? 0,
    availability: row.availability,
    seatsRemaining: row.seatsRemaining,
  };
}

export function fetchRoutes(): Promise<ApiRoute[]> {
  return apiGet<ApiRoute[]>("/routes");
}

export function fetchTripDates(
  routeSlug: string,
  monthYm: string,
  seatClass: SeatClass,
): Promise<{ dates: string[] }> {
  return apiGet<{ dates: string[] }>("/trip-dates", {
    route_slug: routeSlug,
    month: monthYm,
    seat_class: seatClass,
  });
}

export function fetchTrips(routeSlug: string, dateDisplay: string, seatClass: SeatClass): Promise<ApiTripRow[]> {
  return apiGet<ApiTripRow[]>("/trips", {
    route_slug: routeSlug,
    date: dateDisplay,
    seat_class: seatClass,
  });
}

export function fetchPublicSettings(): Promise<PublicPaymentSettings> {
  return apiGet<PublicPaymentSettings>("/settings/public");
}

export type CreateBookingPayload = {
  tripType: BookingTripType;
  seatClass: SeatClass;
  outboundTripId: number;
  inboundTripId?: number;
  booker: BookerInfo;
  passengers: PassengerInfo[];
};

export type CreateBookingResult = {
  bookingCode: string;
  totalVnd: number;
};

export async function createBooking(payload: CreateBookingPayload): Promise<CreateBookingResult> {
  const { restUrl, nonce } = config();
  const url = restUrl.endsWith("/") ? `${restUrl}bookings` : `${restUrl}/bookings`;
  const res = await fetch(url, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-WP-Nonce": nonce,
    },
    credentials: "same-origin",
    body: JSON.stringify(payload),
  });
  const body = (await res.json()) as { errors?: string[]; bookingCode?: string; totalVnd?: number };
  if (!res.ok) {
    const msg = body.errors?.join(" ") || "Không thể tạo đơn đặt vé.";
    throw new Error(msg);
  }
  if (!body.bookingCode) {
    throw new Error("Phản hồi đặt vé không hợp lệ.");
  }
  return { bookingCode: body.bookingCode, totalVnd: body.totalVnd ?? 0 };
}
