import type { PassengerInfo } from "@/components/booking/booking-types";
import type { BookingTripType, MockTrip, SeatClass } from "@/config/booking-config";
import { parseDisplayDate } from "@/lib/booking-search";

export type PassengerFareCategory = "adult" | "child" | "senior";

export type FareLine = {
  category: PassengerFareCategory;
  label: string;
  unitPrice: number;
  count: number;
  subtotal: number;
};

export type LegPricing = {
  legLabel: string;
  lines: FareLine[];
  legTotal: number;
};

export type BookingPriceSummary = {
  seatClass: SeatClass;
  seatClassLabel: string;
  /** Số vé theo đầu người (một chiều hoặc khứ hồi đều 1 vé / hành khách). */
  ticketCount: number;
  legs: LegPricing[];
  aggregatedLines: FareLine[];
  totalVnd: number;
};

const CATEGORY_LABEL: Record<PassengerFareCategory, string> = {
  adult: "người lớn",
  child: "trẻ em",
  senior: "người cao tuổi",
};

/** Age on travel date (dd-mm-yyyy). Defaults reference to today if omitted. */
export function ageFromBirthDate(birthDate: string, referenceDate?: string): number {
  const birth = parseDisplayDate(birthDate);
  if (!birth) return -1;

  const reference = referenceDate ? parseDisplayDate(referenceDate) : new Date();
  if (!reference) return -1;

  let age = reference.getFullYear() - birth.getFullYear();
  const monthDiff = reference.getMonth() - birth.getMonth();
  if (monthDiff < 0 || (monthDiff === 0 && reference.getDate() < birth.getDate())) {
    age -= 1;
  }
  return age;
}

export function isVietnameseNationality(nationality: string): boolean {
  const normalized = nationality.trim().toLowerCase().replace(/\s+/g, "");
  return normalized === "việtnam" || normalized === "vietnam";
}

/** Mức giá theo hạng hành khách — lấy từ chuyến (admin nhập). */
export function unitFareVnd(
  trip: Pick<MockTrip, "priceVnd" | "priceChildVnd" | "priceSeniorVnd">,
  category: PassengerFareCategory,
): number {
  if (category === "child") {
    return trip.priceChildVnd;
  }
  if (category === "senior") {
    return trip.priceSeniorVnd;
  }
  return trip.priceVnd;
}

export function getPassengerFareCategory(age: number, nationality: string): PassengerFareCategory {
  if (age < 0) return "child";
  if (age >= 60 && isVietnameseNationality(nationality)) return "senior";
  if (age >= 12) return "adult";
  return "child";
}

function aggregateLines(lines: FareLine[]): FareLine[] {
  const map = new Map<string, FareLine>();
  for (const line of lines) {
    const key = `${line.category}-${line.unitPrice}`;
    const existing = map.get(key);
    if (existing) {
      existing.count += line.count;
      existing.subtotal += line.subtotal;
    } else {
      map.set(key, { ...line });
    }
  }
  return Array.from(map.values()).sort((a, b) => {
    const order = { adult: 0, senior: 1, child: 2 };
    return order[a.category] - order[b.category];
  });
}

function priceLeg(legLabel: string, trip: MockTrip, passengers: PassengerInfo[]): LegPricing {
  const bucket = new Map<string, FareLine>();

  for (const passenger of passengers) {
    const age = ageFromBirthDate(passenger.birthDate, trip.date);
    const category = getPassengerFareCategory(age, passenger.nationality);
    const unitPrice = unitFareVnd(trip, category);
    const key = `${category}-${unitPrice}`;
    const existing = bucket.get(key);
    if (existing) {
      existing.count += 1;
      existing.subtotal += unitPrice;
    } else {
      bucket.set(key, {
        category,
        label: CATEGORY_LABEL[category],
        unitPrice,
        count: 1,
        subtotal: unitPrice,
      });
    }
  }

  const lines = Array.from(bucket.values());
  const legTotal = lines.reduce((sum, line) => sum + line.subtotal, 0);
  return { legLabel, lines, legTotal };
}

export function computeBookingPriceSummary(input: {
  seatClass: SeatClass;
  tripType: BookingTripType;
  passengers: PassengerInfo[];
  outbound: MockTrip | null;
  inbound: MockTrip | null;
}): BookingPriceSummary | null {
  const { seatClass, tripType, passengers, outbound, inbound } = input;
  if (!outbound || passengers.length === 0) return null;

  const legs: LegPricing[] = [
    priceLeg(`Chiều đi: ${outbound.routeLabel} (${outbound.date} ${outbound.departure})`, outbound, passengers),
  ];

  if (tripType === "round-trip" && inbound) {
    legs.push(
      priceLeg(`Chiều về: ${inbound.routeLabel} (${inbound.date} ${inbound.departure})`, inbound, passengers),
    );
  }

  const allLines = legs.flatMap((leg) => leg.lines);
  const aggregatedLines = aggregateLines(allLines);
  const totalVnd = legs.reduce((sum, leg) => sum + leg.legTotal, 0);
  const ticketCount = passengers.length;

  return {
    seatClass,
    seatClassLabel: seatClass === "vip" ? "VIP" : "Eco",
    ticketCount,
    legs,
    aggregatedLines,
    totalVnd,
  };
}

/** Hiển thị theo đầu người; `line.count` có thể = người × số chiều (khứ hồi). */
export function formatPriceLine(line: FareLine, legCount: number): string {
  const unit = line.unitPrice.toLocaleString("vi-VN");
  const sub = line.subtotal.toLocaleString("vi-VN");
  const legs = Math.max(1, legCount);
  const people = line.count / legs;

  if (Number.isInteger(people) && people >= 1) {
    return `${people} ${line.label} (${unit} x ${line.count} = ${sub} VND)`;
  }

  return `${line.count} ${line.label} (${unit} x ${line.count} = ${sub} VND)`;
}
