<?php
/**
 * Fare calculation (mirror booking-pricing.ts).
 *
 * @package DatvetaucaotocBooking
 */

declare(strict_types=1);

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class Datvetau_Booking_Pricing {

	public static function parse_display_date( string $value ): ?DateTimeImmutable {
		$value = trim( $value );
		if ( preg_match( '/^(\d{2})-(\d{2})-(\d{4})$/', $value, $m ) ) {
			return DateTimeImmutable::createFromFormat( 'Y-m-d', $m[3] . '-' . $m[2] . '-' . $m[1] ) ?: null;
		}
		if ( preg_match( '/^\d{4}-\d{2}-\d{2}$/', $value ) ) {
			return new DateTimeImmutable( $value );
		}
		return null;
	}

	public static function age_from_birth_date( string $birth_date, string $reference_date ): int {
		$birth = self::parse_display_date( $birth_date );
		$ref   = self::parse_display_date( $reference_date ) ?? new DateTimeImmutable( $reference_date );
		if ( ! $birth || ! $ref ) {
			return -1;
		}
		$age = (int) $ref->format( 'Y' ) - (int) $birth->format( 'Y' );
		$md  = (int) $ref->format( 'md' ) - (int) $birth->format( 'md' );
		if ( $md < 0 ) {
			--$age;
		}
		return $age;
	}

	public static function is_vietnamese_nationality( string $nationality ): bool {
		$n = strtolower( preg_replace( '/\s+/', '', trim( $nationality ) ) );
		return in_array( $n, array( 'việtnam', 'vietnam' ), true );
	}

	/**
	 * Giá theo hạng hành khách — NL/TE lấy từ chuyến (admin nhập); cao tuổi vẫn % NL.
	 *
	 * @param array<string,mixed> $trip row
	 */
	public static function unit_fare_vnd_from_trip( array $trip, string $category ): int {
		$adult  = (int) ( $trip['price_adult'] ?? $trip['price_adult_eco_base'] ?? 0 );
		$child  = (int) ( $trip['price_child'] ?? 0 );
		$senior = (int) ( $trip['price_senior'] ?? 0 );
		if ( 'child' === $category ) {
			return $child;
		}
		if ( 'senior' === $category ) {
			return $senior;
		}
		return $adult;
	}

	public static function passenger_fare_category( int $age, string $nationality ): string {
		if ( $age < 0 ) {
			return 'child';
		}
		if ( $age >= 60 && self::is_vietnamese_nationality( $nationality ) ) {
			return 'senior';
		}
		if ( $age >= 12 ) {
			return 'adult';
		}
		return 'child';
	}

	/**
	 * @param array<int,array<string,mixed>> $passengers
	 * @param array<string,mixed>            $outbound_trip row
	 * @param array<string,mixed>|null       $inbound_trip row
	 */
	public static function compute_total(
		string $trip_type,
		string $seat_class,
		array $passengers,
		array $outbound_trip,
		?array $inbound_trip
	): array {
		$legs = array( $outbound_trip );
		if ( 'round-trip' === $trip_type && $inbound_trip ) {
			$legs[] = $inbound_trip;
		}

		$total     = 0;
		$passenger_rows = array();

		foreach ( $passengers as $p ) {
			$ref_date = self::parse_display_date( (string) $outbound_trip['trip_date'] );
			$ref_str  = $ref_date ? $ref_date->format( 'd-m-Y' ) : (string) $outbound_trip['trip_date'];
			$age      = self::age_from_birth_date( (string) $p['birthDate'], $ref_str );
			$cat      = self::passenger_fare_category( $age, (string) $p['nationality'] );
			$unit       = self::unit_fare_vnd_from_trip( $outbound_trip, $cat );
			$legs_count = count( $legs );
			$subtotal   = 0;
			foreach ( $legs as $leg ) {
				$subtotal += self::unit_fare_vnd_from_trip( $leg, $cat );
			}
			$total += $subtotal;
			$passenger_rows[] = array(
				'fare_category'  => $cat,
				'unit_price_vnd' => $unit,
				'legs_count'     => $legs_count,
				'subtotal'       => $subtotal,
			);
		}

		return array(
			'total_vnd'      => $total,
			'ticket_count'   => count( $passengers ),
			'passenger_rows' => $passenger_rows,
		);
	}
}
