<?php
if ( ! defined( 'ABSPATH' ) ) exit;

/**
 * IPP REST API — Public endpoints for property data.
 *
 * Namespace: palace-properties/v1
 *
 * All endpoints are public (no authentication required) since
 * this is listing data meant for display.
 *
 * @package Integrate_Palace_Properties
 * @since   2.0.0
 */
class IPP_REST_API {

    const NAMESPACE = 'palace-properties/v1';

    /**
     * Boot the REST API — register routes on rest_api_init.
     */
    public static function init() {
        add_action( 'rest_api_init', [ __CLASS__, 'register_routes' ] );
    }

    /**
     * Register all REST routes.
     */
    public static function register_routes() {

        // GET /properties
        register_rest_route( self::NAMESPACE, '/properties', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'get_properties' ],
            'permission_callback' => '__return_true',
            'args'                => self::get_collection_params(),
        ] );

        // GET /properties/{id}
        register_rest_route( self::NAMESPACE, '/properties/(?P<id>\d+)', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'get_property' ],
            'permission_callback' => '__return_true',
            'args'                => [
                'id' => [
                    'validate_callback' => function( $param ) {
                        return is_numeric( $param );
                    },
                ],
            ],
        ] );

        // GET /properties/{id}/gallery
        register_rest_route( self::NAMESPACE, '/properties/(?P<id>\d+)/gallery', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'get_property_gallery' ],
            'permission_callback' => '__return_true',
            'args'                => [
                'id' => [
                    'validate_callback' => function( $param ) {
                        return is_numeric( $param );
                    },
                ],
            ],
        ] );

        // GET /search
        register_rest_route( self::NAMESPACE, '/search', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'search_properties' ],
            'permission_callback' => '__return_true',
            'args'                => self::get_collection_params(),
        ] );

        // GET /taxonomies
        register_rest_route( self::NAMESPACE, '/taxonomies', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'get_taxonomies' ],
            'permission_callback' => '__return_true',
        ] );

        // GET /stats
        register_rest_route( self::NAMESPACE, '/stats', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'get_stats' ],
            'permission_callback' => '__return_true',
        ] );
    }

    /**
     * Define accepted query parameters for collection endpoints.
     */
    private static function get_collection_params() {
        return [
            'page'          => [
                'default'           => 1,
                'sanitize_callback' => 'absint',
            ],
            'per_page'      => [
                'default'           => 10,
                'sanitize_callback' => 'absint',
            ],
            'search'        => [
                'default'           => '',
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'status'        => [
                'default'           => '',
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'type'          => [
                'default'           => '',
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'region'        => [
                'default'           => '',
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'bedrooms_min'  => [
                'default'           => '',
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'bedrooms_max'  => [
                'default'           => '',
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'bathrooms_min' => [
                'default'           => '',
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'bathrooms_max' => [
                'default'           => '',
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'price_min'     => [
                'default'           => '',
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'price_max'     => [
                'default'           => '',
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'sort'          => [
                'default'           => 'date',
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'exclude_hidden' => [
                'default'           => true,
                'sanitize_callback' => 'rest_sanitize_boolean',
            ],
        ];
    }

    /**
     * Build query args from a REST request.
     */
    private static function request_to_query_args( WP_REST_Request $request ) {
        $per_page = min( absint( $request->get_param( 'per_page' ) ) ?: 10, 100 );
        $page     = max( absint( $request->get_param( 'page' ) ) ?: 1, 1 );

        return [
            'limit'          => $per_page,
            'offset'         => ( $page - 1 ) * $per_page,
            'status'         => $request->get_param( 'status' ),
            'type'           => $request->get_param( 'type' ),
            'region'         => $request->get_param( 'region' ),
            'bedrooms_min'   => $request->get_param( 'bedrooms_min' ),
            'bedrooms_max'   => $request->get_param( 'bedrooms_max' ),
            'bathrooms_min'  => $request->get_param( 'bathrooms_min' ),
            'bathrooms_max'  => $request->get_param( 'bathrooms_max' ),
            'price_min'      => $request->get_param( 'price_min' ),
            'price_max'      => $request->get_param( 'price_max' ),
            'sort_by'        => $request->get_param( 'sort' ),
            'exclude_hidden' => $request->get_param( 'exclude_hidden' ),
            'search'         => $request->get_param( 'search' ),
        ];
    }

    /**
     * Format a single property for the REST response.
     *
     * @param int $post_id
     * @return array
     */
    private static function format_property( $post_id ) {
        $data = IPP_Developer_API::property_to_array( $post_id );
        if ( ! $data ) return null;

        // Restructure gallery for REST output
        $gallery = [];
        if ( ! empty( $data['gallery'] ) ) {
            foreach ( $data['gallery'] as $img ) {
                $gallery[] = [
                    'id'        => $img['id'],
                    'url'       => $img['url'],
                    'thumbnail' => $img['thumb'],
                    'full'      => $img['full'],
                    'alt'       => $img['alt'] ?? '',
                ];
            }
        }
        $data['gallery'] = $gallery;

        return $data;
    }

    /* ═══════════════════════════════════════════════════════════════
     *  ENDPOINT CALLBACKS
     * ═══════════════════════════════════════════════════════════════ */

    /**
     * GET /properties — List properties (paginated, filterable).
     */
    public static function get_properties( WP_REST_Request $request ) {
        $args       = self::request_to_query_args( $request );
        $query_args = IPP_Developer_API::build_query_args( $args );
        $query      = new WP_Query( $query_args );

        $properties = [];
        if ( $query->have_posts() ) {
            foreach ( $query->posts as $post ) {
                $formatted = self::format_property( $post->ID );
                if ( $formatted ) {
                    $properties[] = $formatted;
                }
            }
        }

        $per_page = min( absint( $request->get_param( 'per_page' ) ) ?: 10, 100 );

        $response = new WP_REST_Response( $properties, 200 );
        $response->header( 'X-WP-Total', $query->found_posts );
        $response->header( 'X-WP-TotalPages', ceil( $query->found_posts / $per_page ) );

        wp_reset_postdata();

        return $response;
    }

    /**
     * GET /properties/{id} — Single property with all data.
     */
    public static function get_property( WP_REST_Request $request ) {
        $post_id = absint( $request->get_param( 'id' ) );
        $data    = self::format_property( $post_id );

        if ( ! $data ) {
            return new WP_Error( 'not_found', 'Property not found', [ 'status' => 404 ] );
        }

        return new WP_REST_Response( $data, 200 );
    }

    /**
     * GET /properties/{id}/gallery — Property gallery images.
     */
    public static function get_property_gallery( WP_REST_Request $request ) {
        $post_id = absint( $request->get_param( 'id' ) );
        $post    = get_post( $post_id );

        if ( ! $post || $post->post_type !== 'palace-properties' ) {
            return new WP_Error( 'not_found', 'Property not found', [ 'status' => 404 ] );
        }

        $prop   = new IPP_Property_Helper( $post_id );
        $images = $prop->gallery_images( 'large' );
        $images = apply_filters( 'ipp_gallery_images', $images, $post_id );

        $gallery = [];
        foreach ( $images as $img ) {
            $gallery[] = [
                'id'        => $img['id'],
                'url'       => $img['url'],
                'thumbnail' => $img['thumb'],
                'full'      => $img['full'],
                'alt'       => $img['alt'] ?? '',
            ];
        }

        return new WP_REST_Response( $gallery, 200 );
    }

    /**
     * GET /search — Search properties (same params as /properties).
     */
    public static function search_properties( WP_REST_Request $request ) {
        // Identical to get_properties — both support search param
        return self::get_properties( $request );
    }

    /**
     * GET /taxonomies — Available taxonomy terms.
     */
    public static function get_taxonomies( WP_REST_Request $request ) {
        $result = [];

        $taxonomies = [
            'types'      => 'palace-property-type',
            'statuses'   => 'palace-property-status',
            'regions'    => 'palace-property-region',
            'management' => 'palace-property-management',
        ];

        foreach ( $taxonomies as $key => $taxonomy ) {
            $terms = get_terms( [
                'taxonomy'   => $taxonomy,
                'hide_empty' => true,
            ] );

            $result[ $key ] = [];
            if ( ! is_wp_error( $terms ) ) {
                foreach ( $terms as $term ) {
                    $result[ $key ][] = [
                        'id'    => $term->term_id,
                        'name'  => $term->name,
                        'slug'  => $term->slug,
                        'count' => $term->count,
                    ];
                }
            }
        }

        return new WP_REST_Response( $result, 200 );
    }

    /**
     * GET /stats — Public statistics.
     */
    public static function get_stats( WP_REST_Request $request ) {
        $total = wp_count_posts( 'palace-properties' );

        $stats = [
            'total_published' => isset( $total->publish ) ? (int) $total->publish : 0,
            'total_draft'     => isset( $total->draft ) ? (int) $total->draft : 0,
            'total_all'       => array_sum( (array) $total ),
        ];

        // Count by status taxonomy
        $statuses = get_terms( [
            'taxonomy'   => 'palace-property-status',
            'hide_empty' => false,
        ] );
        if ( ! is_wp_error( $statuses ) ) {
            $stats['by_status'] = [];
            foreach ( $statuses as $term ) {
                $stats['by_status'][ $term->slug ] = $term->count;
            }
        }

        // Count by type taxonomy
        $types = get_terms( [
            'taxonomy'   => 'palace-property-type',
            'hide_empty' => false,
        ] );
        if ( ! is_wp_error( $types ) ) {
            $stats['by_type'] = [];
            foreach ( $types as $term ) {
                $stats['by_type'][ $term->slug ] = $term->count;
            }
        }

        // Count by region taxonomy
        $regions = get_terms( [
            'taxonomy'   => 'palace-property-region',
            'hide_empty' => false,
        ] );
        if ( ! is_wp_error( $regions ) ) {
            $stats['by_region'] = [];
            foreach ( $regions as $term ) {
                $stats['by_region'][ $term->slug ] = $term->count;
            }
        }

        return new WP_REST_Response( $stats, 200 );
    }
}

// Self-initialize
IPP_REST_API::init();
