<?php

declare( strict_types=1 );

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

/**
 * Public REST API for fields.
 * All endpoints always filter WHERE status = 'active'.
 * Full implementation in Phase 5 (booking widget).
 */
class Playard_API_Fields {

	private Playard_Field $field;

	public function __construct( Playard_Field $field ) {
		$this->field = $field;
	}

	public function register_routes(): void {
		register_rest_route( 'playard/v1', '/facility', [
			'methods'             => 'GET',
			'callback'            => [ $this, 'get_facility' ],
			'permission_callback' => '__return_true',
		] );

		register_rest_route( 'playard/v1', '/fields', [
			'methods'             => 'GET',
			'callback'            => [ $this, 'list_fields' ],
			// Public: field listing is public data shown on the booking widget.
			'permission_callback' => '__return_true',
			'args'                => [
				'sport' => [ 'required' => false, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field' ],
				'ids'   => [ 'required' => false, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field' ],
			],
		] );

		register_rest_route( 'playard/v1', '/fields/(?P<id>\d+)', [
			'methods'             => 'GET',
			'callback'            => [ $this, 'get_field' ],
			'permission_callback' => '__return_true',
			'args'                => [
				'id' => [ 'required' => true, 'type' => 'integer', 'sanitize_callback' => 'absint' ],
			],
		] );
	}

	public function get_facility( WP_REST_Request $request ): WP_REST_Response {
		$facility = playard_get_facility();

		if ( ! $facility ) {
			return new WP_REST_Response(
				playard_rest_error( 'not_found', __( 'Facility not configured.', 'playard' ) ),
				404
			);
		}

		return new WP_REST_Response( playard_rest_success( [
			'name'            => $facility->name,
			'description'     => (string) ( $facility->description ?? '' ),
			'address'         => (string) ( $facility->address ?? '' ),
			'lat'             => (float) ( $facility->lat ?? 0 ),
			'lng'             => (float) ( $facility->lng ?? 0 ),
			'logo_url'        => (string) ( $facility->logo_url ?? '' ),
			'cover_photo_url' => (string) ( $facility->cover_photo_url ?? '' ),
			'phone'           => (string) ( $facility->phone ?? '' ),
			'email'           => (string) ( $facility->email ?? '' ),
			'timezone'        => (string) ( $facility->timezone ?? '' ),
			'currency'        => (string) ( $facility->currency ?? 'USD' ),
			'currency_symbol' => playard_get_currency_symbol( (string) ( $facility->currency ?? 'USD' ) ),
			'open_time'       => substr( (string) ( $facility->open_time ?? '00:00:00' ), 0, 5 ),
			'close_time'      => substr( (string) ( $facility->close_time ?? '23:59:00' ), 0, 5 ),
			'open_days'       => json_decode( (string) ( $facility->open_days ?? '[]' ), true ) ?: [],
		] ), 200 );
	}

	public function list_fields( WP_REST_Request $request ): WP_REST_Response {
		$facility_id = playard_get_facility_id();

		if ( $facility_id < 1 ) {
			return new WP_REST_Response( playard_rest_success( [] ), 200 );
		}

		// Always active only — inactive fields never exposed to the public.
		$rows = $this->field->get_all( $facility_id, 'active' );

		$ids_param = sanitize_text_field( (string) ( $request->get_param( 'ids' ) ?? '' ) );

		if ( $ids_param !== '' ) {
			$ids  = array_filter( array_map( 'absint', explode( ',', $ids_param ) ), fn( int $n ) => $n > 0 );
			$rows = array_values( array_filter( $rows, fn( object $f ) => in_array( (int) $f->id, $ids, true ) ) );
		}

		$sport_filter = sanitize_text_field( (string) ( $request->get_param( 'sport' ) ?? '' ) );

		if ( $sport_filter !== '' ) {
			$rows = array_values( array_filter( $rows, function ( object $row ) use ( $sport_filter ): bool {
				$sports = json_decode( $row->sports ?? '[]', true );
				return is_array( $sports ) && in_array( $sport_filter, $sports, true );
			} ) );
		}

		return new WP_REST_Response(
			playard_rest_success( array_map( [ $this, 'format_field' ], $rows ) ),
			200
		);
	}

	public function get_field( WP_REST_Request $request ): WP_REST_Response {
		$id  = absint( $request->get_param( 'id' ) );
		$row = $this->field->get( $id );

		if ( ! $row || $row->status !== 'active' ) {
			return new WP_REST_Response(
				playard_rest_error( 'not_found', __( 'Field not found.', 'playard' ) ),
				404
			);
		}

		return new WP_REST_Response(
			playard_rest_success( $this->format_field( $row ) ),
			200
		);
	}

	/**
	 * @param object $row
	 * @return array<string,mixed>
	 */
	private function format_field( object $row ): array {
		return [
			'id'            => (int) $row->id,
			'name'          => $row->name,
			'description'   => (string) ( $row->description ?? '' ),
			'sports'        => json_decode( (string) ( $row->sports ?? '[]' ), true ) ?: [],
			'photos'        => json_decode( (string) ( $row->photos ?? '[]' ), true ) ?: [],
			'capacity'      => (int) ( $row->capacity ?? 0 ),
			'slot_duration' => (int) $row->slot_duration,
			'base_price'    => (float) $row->base_price,
			'payment_mode'  => (string) ( $row->payment_mode ?? 'both' ),
			'buffer_time'   => (int) ( $row->buffer_time ?? 0 ),
			'min_advance'   => (int) ( $row->min_advance ?? 0 ),
			'max_advance'   => (int) ( $row->max_advance ?? 30 ),
		];
	}
}
