<?php
/**
 * Bookings + passengers persistence.
 *
 * @package DatvetaucaotocBooking
 */

declare(strict_types=1);

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class Datvetau_Booking_Booking_Repository {

	public static function list_all( int $limit = 100 ): array {
		return self::list_for_admin(
			array(
				'search' => '',
				'status' => '',
				'limit'  => $limit,
			)
		);
	}

	/**
	 * @param array{search?:string,status?:string,limit?:int} $filters
	 * @return array<int,array<string,mixed>>
	 */
	public static function list_for_admin( array $filters = array() ): array {
		global $wpdb;
		$table  = Datvetau_Booking_Database::table( 'bookings' );
		$search = trim( (string) ( $filters['search'] ?? '' ) );
		$status = sanitize_key( (string) ( $filters['status'] ?? '' ) );
		$limit  = max( 1, min( 500, (int) ( $filters['limit'] ?? 200 ) ) );

		$where = array( '1=1' );
		$args  = array();

		if ( in_array( $status, array( 'pending_payment', 'confirmed', 'cancelled' ), true ) ) {
			$where[] = 'status = %s';
			$args[]  = $status;
		}

		if ( '' !== $search ) {
			$like    = '%' . $wpdb->esc_like( $search ) . '%';
			$where[] = '(booking_code LIKE %s OR booker_name LIKE %s OR booker_phone LIKE %s)';
			$args[]  = $like;
			$args[]  = $like;
			$args[]  = $like;
		}

		$sql = 'SELECT * FROM ' . $table . ' WHERE ' . implode( ' AND ', $where ) . ' ORDER BY created_at DESC LIMIT %d';
		$args[] = $limit;

		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		return $wpdb->get_results( $wpdb->prepare( $sql, ...$args ), ARRAY_A ) ?: array();
	}

	public static function find_by_id( int $id ): ?array {
		global $wpdb;
		$table = Datvetau_Booking_Database::table( 'bookings' );
		$row   = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE id = %d", $id ), ARRAY_A );
		return $row ?: null;
	}

	public static function find_by_code( string $code ): ?array {
		global $wpdb;
		$table = Datvetau_Booking_Database::table( 'bookings' );
		$row   = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE booking_code = %s", $code ), ARRAY_A );
		return $row ?: null;
	}

	public static function passengers_for_booking( int $booking_id ): array {
		global $wpdb;
		$table = Datvetau_Booking_Database::table( 'passengers' );
		$sql   = $wpdb->prepare( "SELECT * FROM {$table} WHERE booking_id = %d ORDER BY id ASC", $booking_id );
		return $wpdb->get_results( $sql, ARRAY_A ) ?: array();
	}

	public static function insert_booking( array $booking, array $passengers ): int {
		global $wpdb;
		$b_table = Datvetau_Booking_Database::table( 'bookings' );
		$p_table = Datvetau_Booking_Database::table( 'passengers' );

		$wpdb->insert( $b_table, $booking );
		$booking_id = (int) $wpdb->insert_id;

		foreach ( $passengers as $p ) {
			$p['booking_id'] = $booking_id;
			$wpdb->insert( $p_table, $p );
		}

		return $booking_id;
	}

	public static function update_status( int $id, string $status ): void {
		global $wpdb;
		$table = Datvetau_Booking_Database::table( 'bookings' );
		$wpdb->update( $table, array( 'status' => $status ), array( 'id' => $id ) );
	}

	public static function generate_booking_code(): string {
		return 'DV' . gmdate( 'Ymd' ) . wp_rand( 1000, 9999 );
	}
}
