<?php
/**
 * REST routes datvetau/v1.
 *
 * @package DatvetaucaotocBooking
 */

declare(strict_types=1);

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class Datvetau_Booking_REST_API {

	public static function register(): void {
		add_action( 'rest_api_init', array( self::class, 'register_routes' ) );
	}

	public static function register_routes(): void {
		register_rest_route(
			'datvetau/v1',
			'/routes',
			array(
				'methods'             => 'GET',
				'callback'            => array( self::class, 'get_routes' ),
				'permission_callback' => '__return_true',
			)
		);

		register_rest_route(
			'datvetau/v1',
			'/trip-dates',
			array(
				'methods'             => 'GET',
				'callback'            => array( self::class, 'get_trip_dates' ),
				'permission_callback' => '__return_true',
				'args'                => array(
					'route_slug' => array( 'required' => true, 'type' => 'string' ),
					'month'      => array( 'required' => true, 'type' => 'string' ),
					'seat_class' => array( 'default' => 'eco', 'type' => 'string' ),
				),
			)
		);

		register_rest_route(
			'datvetau/v1',
			'/trips',
			array(
				'methods'             => 'GET',
				'callback'            => array( self::class, 'get_trips' ),
				'permission_callback' => '__return_true',
				'args'                => array(
					'route_slug'  => array( 'required' => true, 'type' => 'string' ),
					'date'        => array( 'required' => true, 'type' => 'string' ),
					'seat_class'  => array( 'default' => 'eco', 'type' => 'string' ),
				),
			)
		);

		register_rest_route(
			'datvetau/v1',
			'/settings/public',
			array(
				'methods'             => 'GET',
				'callback'            => array( self::class, 'get_settings' ),
				'permission_callback' => '__return_true',
			)
		);

		register_rest_route(
			'datvetau/v1',
			'/bookings',
			array(
				'methods'             => 'POST',
				'callback'            => array( self::class, 'post_booking' ),
				'permission_callback' => array( self::class, 'verify_booking_nonce' ),
			)
		);
	}

	public static function verify_booking_nonce( WP_REST_Request $request ): bool {
		$nonce = $request->get_header( 'X-WP-Nonce' );
		if ( ! $nonce ) {
			$nonce = (string) $request->get_param( '_wpnonce' );
		}
		return (bool) wp_verify_nonce( $nonce, 'wp_rest' );
	}

	public static function get_routes(): WP_REST_Response {
		$routes = Datvetau_Booking_Route_Repository::list_active();
		$payload = array_map(
			static function ( array $r ) use ( $routes ) {
				$reverse_slug = null;
				if ( ! empty( $r['reverse_route_id'] ) ) {
					$rev = Datvetau_Booking_Route_Repository::find_by_id( (int) $r['reverse_route_id'] );
					$reverse_slug = $rev ? (string) $rev['slug'] : null;
				}
				return array(
					'id'               => (string) $r['slug'],
					'slug'             => (string) $r['slug'],
					'label'            => (string) $r['label'],
					'reverseRouteId'   => $r['reverse_route_id'] ? (int) $r['reverse_route_id'] : null,
					'reverseRouteSlug' => $reverse_slug,
				);
			},
			$routes
		);
		$response = new WP_REST_Response( $payload, 200 );
		$response->header( 'Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0' );

		return $response;
	}

	public static function get_trip_dates( WP_REST_Request $request ): WP_REST_Response {
		$slug  = sanitize_title( (string) $request->get_param( 'route_slug' ) );
		$month = (string) $request->get_param( 'month' );
		$seat  = in_array( $request->get_param( 'seat_class' ), array( 'eco', 'vip' ), true )
			? (string) $request->get_param( 'seat_class' )
			: 'eco';

		if ( ! preg_match( '/^\d{4}-\d{2}$/', $month ) ) {
			return new WP_REST_Response( array( 'dates' => array() ), 200 );
		}

		$route = Datvetau_Booking_Route_Repository::find_by_slug( $slug );
		if ( ! $route ) {
			return new WP_REST_Response( array( 'dates' => array() ), 200 );
		}

		$dates = Datvetau_Booking_Trip_Repository::list_trip_dates_in_month( (int) $route['id'], $month, $seat );
		$response = new WP_REST_Response( array( 'dates' => $dates ), 200 );
		$response->header( 'Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0' );

		return $response;
	}

	public static function get_trips( WP_REST_Request $request ): WP_REST_Response {
		$slug = sanitize_title( (string) $request->get_param( 'route_slug' ) );
		$date = (string) $request->get_param( 'date' );
		$seat = in_array( $request->get_param( 'seat_class' ), array( 'eco', 'vip' ), true )
			? (string) $request->get_param( 'seat_class' )
			: 'eco';

		$route = Datvetau_Booking_Route_Repository::find_by_slug( $slug );
		if ( ! $route ) {
			return new WP_REST_Response( array(), 200 );
		}

		if ( preg_match( '/^\d{2}-\d{2}-\d{4}$/', $date ) ) {
			$dt = Datvetau_Booking_Pricing::parse_display_date( $date );
			$date = $dt ? $dt->format( 'Y-m-d' ) : $date;
		}

		$rows = Datvetau_Booking_Trip_Repository::search( (int) $route['id'], $date, $seat );
		$trips = array_map(
			static fn( array $t ) => Datvetau_Booking_Trip_Repository::to_api_trip( $t, $route ),
			$rows
		);

		return new WP_REST_Response( $trips, 200 );
	}

	public static function get_settings(): WP_REST_Response {
		return new WP_REST_Response( Datvetau_Booking_Settings::public_payload(), 200 );
	}

	public static function post_booking( WP_REST_Request $request ): WP_REST_Response {
		$payload = $request->get_json_params();
		if ( ! is_array( $payload ) ) {
			return new WP_REST_Response( array( 'errors' => array( 'Payload không hợp lệ' ) ), 400 );
		}

		$result = Datvetau_Booking_Service::create_from_payload( $payload );
		if ( ! $result['success'] ) {
			return new WP_REST_Response( array( 'errors' => $result['errors'] ?? array() ), 409 );
		}

		return new WP_REST_Response( $result['data'], 201 );
	}
}
