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

/**
 * IPP Developer API — Global PHP functions for theme/plugin developers.
 *
 * Provides a clean public API so developers never need to touch
 * post meta or internal classes directly.
 *
 * @package Integrate_Palace_Properties
 * @since   2.0.0
 */
class IPP_Developer_API {

    /**
     * Boot the API — registers all global functions.
     * Called once at the bottom of this file.
     */
    public static function init() {
        // Nothing to hook — functions are declared at file scope below.
    }

    /**
     * Add a posts_search filter that extends WP search to include property meta fields.
     * This makes search find properties by address, suburb, region, code, agent name, etc.
     *
     * @param string $search_term The search term.
     */
    public static function add_meta_search_filter( $search_term ) {
        add_filter( 'posts_search', function( $search_sql, $query ) use ( $search_term ) {
            if ( ! $query->get( 'ipp_meta_search' ) || empty( $search_sql ) ) {
                return $search_sql;
            }
            global $wpdb;
            $like = '%' . $wpdb->esc_like( $search_term ) . '%';
            $meta_keys = "'ipp_address1','ipp_address2','ipp_address3','ipp_suburb','ipp_region','ipp_postcode','ipp_property_code','ipp_agent_full_name','ipp_class','ipp_management_type','information_address','information_suburb','information_region','ipp_header','ipp_name','ipp_property_code_global'";
            $meta_condition = $wpdb->prepare(
                " OR ({$wpdb->posts}.ID IN (SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key IN ({$meta_keys}) AND meta_value LIKE %s))",
                $like
            );
            // Append our meta condition before the closing parenthesis of the search WHERE
            $search_sql = preg_replace( '/(\s*\)\s*)$/', $meta_condition . '$1', $search_sql );
            return $search_sql;
        }, 10, 2 );
    }

    /* ───────────────────────────────────────────────────────────────
     *  Internal helpers used by the global functions
     * ─────────────────────────────────────────────────────────────── */

    /**
     * Build WP_Query args from a developer-friendly $args array.
     *
     * @param array $args Supported keys: limit, offset, status, type, region,
     *                    bedrooms_min, bedrooms_max, bathrooms_min, bathrooms_max,
     *                    price_min, price_max, sort_by, order, exclude_hidden, search.
     * @return array WP_Query-compatible args.
     */
    public static function build_query_args( $args = [] ) {
        $defaults = [
            'limit'          => 10,
            'offset'         => 0,
            'status'         => '',
            'type'           => '',
            'region'         => '',
            'bedrooms_min'   => '',
            'bedrooms_max'   => '',
            'bathrooms_min'  => '',
            'bathrooms_max'  => '',
            'price_min'      => '',
            'price_max'      => '',
            'sort_by'        => 'date',
            'order'          => 'DESC',
            'exclude_hidden' => true,
            'search'         => '',
        ];
        $args = wp_parse_args( $args, $defaults );

        $query_args = [
            'post_type'      => 'palace-properties',
            'post_status'    => 'publish',
            'posts_per_page' => absint( $args['limit'] ) ?: 10,
            'offset'         => absint( $args['offset'] ),
        ];

        // Taxonomy filters
        $tax_query = [];
        if ( ! empty( $args['status'] ) ) {
            $tax_query[] = [
                'taxonomy' => 'palace-property-status',
                'field'    => 'slug',
                'terms'    => sanitize_text_field( $args['status'] ),
            ];
        }
        if ( ! empty( $args['type'] ) ) {
            $tax_query[] = [
                'taxonomy' => 'palace-property-type',
                'field'    => 'slug',
                'terms'    => sanitize_text_field( $args['type'] ),
            ];
        }
        if ( ! empty( $args['region'] ) ) {
            $tax_query[] = [
                'taxonomy' => 'palace-property-region',
                'field'    => 'slug',
                'terms'    => sanitize_text_field( $args['region'] ),
            ];
        }
        if ( ! empty( $tax_query ) ) {
            $tax_query['relation'] = 'AND';
            $query_args['tax_query'] = $tax_query;
        }

        // Meta query filters
        $meta_query = [];
        if ( $args['bedrooms_min'] !== '' ) {
            $meta_query[] = [
                'key'     => 'ipp_bedrooms',
                'value'   => absint( $args['bedrooms_min'] ),
                'compare' => '>=',
                'type'    => 'NUMERIC',
            ];
        }
        if ( $args['bedrooms_max'] !== '' ) {
            $meta_query[] = [
                'key'     => 'ipp_bedrooms',
                'value'   => absint( $args['bedrooms_max'] ),
                'compare' => '<=',
                'type'    => 'NUMERIC',
            ];
        }
        if ( $args['bathrooms_min'] !== '' ) {
            $meta_query[] = [
                'key'     => 'ipp_bathrooms',
                'value'   => absint( $args['bathrooms_min'] ),
                'compare' => '>=',
                'type'    => 'NUMERIC',
            ];
        }
        if ( $args['bathrooms_max'] !== '' ) {
            $meta_query[] = [
                'key'     => 'ipp_bathrooms',
                'value'   => absint( $args['bathrooms_max'] ),
                'compare' => '<=',
                'type'    => 'NUMERIC',
            ];
        }
        if ( $args['price_min'] !== '' ) {
            $meta_query[] = [
                'key'     => 'ipp_rent_amount',
                'value'   => floatval( $args['price_min'] ),
                'compare' => '>=',
                'type'    => 'NUMERIC',
            ];
        }
        if ( $args['price_max'] !== '' ) {
            $meta_query[] = [
                'key'     => 'ipp_rent_amount',
                'value'   => floatval( $args['price_max'] ),
                'compare' => '<=',
                'type'    => 'NUMERIC',
            ];
        }
        if ( $args['exclude_hidden'] ) {
            $meta_query[] = [
                'relation' => 'OR',
                [
                    'key'     => 'ipp_archived',
                    'compare' => 'NOT EXISTS',
                ],
                [
                    'key'     => 'ipp_archived',
                    'value'   => 'Yes',
                    'compare' => '!=',
                ],
            ];
        }
        if ( ! empty( $meta_query ) ) {
            $meta_query['relation'] = 'AND';
            $query_args['meta_query'] = $meta_query;
        }

        // Search — custom implementation that searches title + multiple meta fields
        if ( ! empty( $args['search'] ) ) {
            $search_term = sanitize_text_field( $args['search'] );
            // Use a custom posts_where filter for maximum flexibility
            add_filter( 'posts_where', function( $where, $query ) use ( $search_term ) {
                if ( ! $query->get( 'ipp_meta_search' ) ) return $where;
                global $wpdb;
                $like = '%' . $wpdb->esc_like( $search_term ) . '%';
                $where .= $wpdb->prepare(
                    " AND ({$wpdb->posts}.post_title LIKE %s OR {$wpdb->posts}.post_content LIKE %s OR {$wpdb->posts}.ID IN (SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key IN ('ipp_address1','ipp_address2','ipp_address3','ipp_suburb','ipp_region','ipp_postcode','ipp_property_code','ipp_property_code_global','ipp_agent_full_name','ipp_class','ipp_management_type','information_address','information_suburb','information_region','ipp_header','ipp_name') AND meta_value LIKE %s))",
                    $like, $like, $like
                );
                return $where;
            }, 10, 2 );
            $query_args['ipp_meta_search'] = true;
            // Don't use 's' — we handle search ourselves via posts_where
        }

        // Sorting
        switch ( $args['sort_by'] ) {
            case 'price_asc':
                $query_args['meta_key'] = 'ipp_rent_amount';
                $query_args['orderby']  = 'meta_value_num';
                $query_args['order']    = 'ASC';
                break;
            case 'price_desc':
                $query_args['meta_key'] = 'ipp_rent_amount';
                $query_args['orderby']  = 'meta_value_num';
                $query_args['order']    = 'DESC';
                break;
            case 'bedrooms':
                $query_args['meta_key'] = 'ipp_bedrooms';
                $query_args['orderby']  = 'meta_value_num';
                $query_args['order']    = $args['order'] ?: 'DESC';
                break;
            case 'title':
                $query_args['orderby'] = 'title';
                $query_args['order']   = $args['order'] ?: 'ASC';
                break;
            case 'date':
            default:
                $query_args['orderby'] = 'date';
                $query_args['order']   = $args['order'] ?: 'DESC';
                break;
        }

        return apply_filters( 'ipp_archive_query_args', $query_args );
    }

    /**
     * Convert a property post into an associative array with ALL data.
     *
     * @param int $post_id
     * @return array|null
     */
    public static function property_to_array( $post_id ) {
        $post = get_post( $post_id );
        if ( ! $post || $post->post_type !== 'palace-properties' ) {
            return null;
        }

        $prop = new IPP_Property_Helper( $post_id );

        $data = [
            'id'            => $post_id,
            'title'         => get_the_title( $post_id ),
            'slug'          => $post->post_name,
            'url'           => get_permalink( $post_id ),
            'content'       => $post->post_content,
            'status'        => $prop->status(),
            'property_code' => $prop->property_code(),
            'address'       => [
                'line1'    => $prop->address1(),
                'line2'    => $prop->address2(),
                'city'     => $prop->address3(),
                'region'   => $prop->region(),
                'suburb'   => $prop->suburb(),
                'postcode' => $prop->postcode(),
                'full'     => $prop->full_address(),
                'short'    => $prop->short_address(),
            ],
            'financial'     => [
                'rent'           => $prop->rent() ? floatval( $prop->rent() ) : null,
                'rental_period'  => $prop->rental_period(),
                'formatted_rent' => $prop->formatted_rent(),
                'market_value'   => $prop->market_value(),
            ],
            'features'      => [
                'bedrooms'         => $prop->bedrooms() ? intval( $prop->bedrooms() ) : null,
                'bathrooms'        => $prop->bathrooms() ? intval( $prop->bathrooms() ) : null,
                'ensuites'         => $prop->ensuites() ? intval( $prop->ensuites() ) : null,
                'cars'             => $prop->cars() ? intval( $prop->cars() ) : null,
                'parking'          => $prop->parking(),
                'class'            => $prop->property_class(),
                'year_built'       => $prop->year_built(),
                'stories'          => $prop->stories(),
                'furnishings'      => $prop->furnishings(),
                'new_construction' => $prop->new_construction(),
                'amenities'        => $prop->amenities(),
                'floor_area'       => $prop->floor_area(),
                'land_area_sqm'    => $prop->land_area_sqm(),
                'land_area_hectares' => $prop->land_area_hectares(),
                'pets_allowed'     => $prop->pets_allowed(),
                'smokers_allowed'  => $prop->smokers_allowed(),
            ],
            'agent'         => [
                'code'         => $prop->agent_code(),
                'name'         => $prop->agent_name(),
                'title'        => $prop->agent_title(),
                'email'        => $prop->agent_email(),
                'email2'       => $prop->agent_email2(),
                'phone_mobile' => $prop->agent_phone_mobile(),
                'phone_work'   => $prop->agent_phone_work(),
            ],
            'gallery'       => $prop->gallery_images( 'large' ),
            'featured_image' => $prop->featured_image( 'large' ),
            'map'           => [
                'lat'        => $prop->map_lat(),
                'lng'        => $prop->map_lng(),
                'has_coords' => $prop->has_map_coords(),
                'embed_url'  => $prop->map_embed_url(),
            ],
            'links'         => [
                'virtual_tour' => $prop->virtual_tour_url(),
                'web_link'     => $prop->web_link_url(),
            ],
            'taxonomies'    => [
                'type'       => wp_get_post_terms( $post_id, 'palace-property-type', [ 'fields' => 'names' ] ),
                'status'     => wp_get_post_terms( $post_id, 'palace-property-status', [ 'fields' => 'names' ] ),
                'region'     => wp_get_post_terms( $post_id, 'palace-property-region', [ 'fields' => 'names' ] ),
                'management' => wp_get_post_terms( $post_id, 'palace-property-management', [ 'fields' => 'names' ] ),
            ],
            'text'          => [
                'header'          => $prop->header(),
                'advert_text'     => $prop->advert_text(),
                'feature_details' => $prop->feature_details(),
            ],
            'custom_fields' => $prop->custom_fields(),
            'dates'         => [
                'available' => $prop->date_available(),
                'formatted_available' => $prop->formatted_date_available(),
                'start'     => $prop->start_date(),
                'created'   => $post->post_date,
                'modified'  => $post->post_modified,
            ],
            'meta'          => [
                'management_type' => $prop->management_type(),
                'archived'        => $prop->archived(),
                'name'            => $prop->name(),
            ],
        ];

        return apply_filters( 'ipp_property_data', $data, $post_id );
    }

    /**
     * Render a property card using the active template.
     *
     * @param int $post_id
     * @return string HTML
     */
    public static function render_card( $post_id ) {
        $template_slug = sanitize_text_field( get_option( 'ipp_select_template', 'palace-property' ) );
        $card_path     = INTEGRATE_PALACE_P_PLUGIN_DIR . 'public/templates/' . sanitize_file_name( $template_slug ) . '/card.php';

        // Allow theme override
        $theme_path = get_stylesheet_directory() . '/palace-properties/card.php';
        if ( file_exists( $theme_path ) ) {
            $card_path = $theme_path;
        }

        $card_path = apply_filters( 'ipp_card_template', $card_path, $template_slug );

        if ( ! file_exists( $card_path ) ) {
            return '';
        }

        // Set up global post data
        global $post;
        $original_post = $post;
        $post = get_post( $post_id );
        setup_postdata( $post );

        $prop = new IPP_Property_Helper( $post_id );

        do_action( 'ipp_before_card', $post_id, $prop );

        ob_start();
        include $card_path;
        $html = ob_get_clean();

        do_action( 'ipp_after_card', $post_id, $prop );

        // Restore
        $post = $original_post;
        if ( $original_post ) {
            setup_postdata( $original_post );
        } else {
            wp_reset_postdata();
        }

        return $html;
    }

    /**
     * Render gallery HTML for a property.
     *
     * @param int    $post_id
     * @param string $size Image size.
     * @return string HTML
     */
    public static function render_gallery( $post_id, $size = 'large' ) {
        $prop   = new IPP_Property_Helper( $post_id );
        $images = $prop->gallery_images( $size );
        $images = apply_filters( 'ipp_gallery_images', $images, $post_id );

        if ( empty( $images ) ) {
            return '';
        }

        do_action( 'ipp_before_gallery', $post_id, $images );

        ob_start();
        ?>
        <div class="ipp-gallery" data-property-id="<?php echo esc_attr( $post_id ); ?>">
            <?php foreach ( $images as $img ) : ?>
                <div class="ipp-gallery__item">
                    <a href="<?php echo esc_url( $img['full'] ); ?>" data-lightbox="property-<?php echo esc_attr( $post_id ); ?>">
                        <img src="<?php echo esc_url( $img['url'] ); ?>"
                             alt="<?php echo esc_attr( $img['alt'] ); ?>"
                             loading="lazy" />
                    </a>
                </div>
            <?php endforeach; ?>
        </div>
        <?php
        $html = ob_get_clean();

        do_action( 'ipp_after_gallery', $post_id, $images );

        return $html;
    }
}

/* ═══════════════════════════════════════════════════════════════════
 *  GLOBAL FUNCTIONS
 *  These are the public developer-facing API.
 * ═══════════════════════════════════════════════════════════════════ */

if ( ! function_exists( 'ipp_get_property' ) ) {
    /**
     * Get a single property as an IPP_Property_Helper instance.
     *
     * @param int|null $post_id Defaults to current post.
     * @return IPP_Property_Helper|null
     */
    function ipp_get_property( $post_id = null ) {
        $post_id = $post_id ?: get_the_ID();
        if ( ! $post_id ) return null;
        $post = get_post( $post_id );
        if ( ! $post || $post->post_type !== 'palace-properties' ) return null;
        return new IPP_Property_Helper( $post_id );
    }
}

if ( ! function_exists( 'ipp_get_properties' ) ) {
    /**
     * Get multiple properties with filtering.
     *
     * @param array $args See IPP_Developer_API::build_query_args() for supported keys.
     * @return IPP_Property_Helper[]
     */
    function ipp_get_properties( $args = [] ) {
        $query_args = IPP_Developer_API::build_query_args( $args );
        $query      = new WP_Query( $query_args );
        $results    = [];

        if ( $query->have_posts() ) {
            foreach ( $query->posts as $post ) {
                $results[] = new IPP_Property_Helper( $post->ID );
            }
        }
        wp_reset_postdata();

        return $results;
    }
}

if ( ! function_exists( 'ipp_get_field' ) ) {
    /**
     * Get a property meta field value directly.
     *
     * @param int    $post_id
     * @param string $field Meta key (without ipp_ prefix).
     * @return string
     */
    function ipp_get_field( $post_id, $field ) {
        $prop = new IPP_Property_Helper( $post_id );
        // Try calling the method if it exists
        if ( method_exists( $prop, $field ) ) {
            return $prop->$field();
        }
        // Fall back to meta lookup
        return $prop->meta( $field );
    }
}

if ( ! function_exists( 'ipp_is_field_visible' ) ) {
    /**
     * Check if a display field is enabled in plugin settings.
     *
     * @param string $field_key
     * @return bool
     */
    function ipp_is_field_visible( $field_key ) {
        $display_fields = get_option( 'ipp_display_fields', IntegratePalace_Properties_Settings::get_default_display_fields() );
        $visible = in_array( $field_key, $display_fields, true );
        return apply_filters( 'ipp_show_field', $visible, $field_key, 0 );
    }
}

if ( ! function_exists( 'ipp_get_display_fields' ) ) {
    /**
     * Get all display-enabled field keys.
     *
     * @return array
     */
    function ipp_get_display_fields() {
        $fields = get_option( 'ipp_display_fields', IntegratePalace_Properties_Settings::get_default_display_fields() );
        return apply_filters( 'ipp_display_fields', $fields );
    }
}

if ( ! function_exists( 'ipp_get_template' ) ) {
    /**
     * Get the active template slug.
     *
     * @return string
     */
    function ipp_get_template() {
        return sanitize_text_field( get_option( 'ipp_select_template', 'palace-property' ) );
    }
}

if ( ! function_exists( 'ipp_render_card' ) ) {
    /**
     * Render a property card (uses the active template's card.php).
     *
     * @param int $post_id
     * @return string HTML
     */
    function ipp_render_card( $post_id ) {
        return IPP_Developer_API::render_card( $post_id );
    }
}

if ( ! function_exists( 'ipp_render_gallery' ) ) {
    /**
     * Render a property's gallery HTML.
     *
     * @param int    $post_id
     * @param string $size WordPress image size.
     * @return string HTML
     */
    function ipp_render_gallery( $post_id, $size = 'large' ) {
        return IPP_Developer_API::render_gallery( $post_id, $size );
    }
}

if ( ! function_exists( 'ipp_property_to_array' ) ) {
    /**
     * Get property as an associative array (for JSON/API use).
     *
     * @param int $post_id
     * @return array|null
     */
    function ipp_property_to_array( $post_id ) {
        return IPP_Developer_API::property_to_array( $post_id );
    }
}

if ( ! function_exists( 'ipp_query_properties' ) ) {
    /**
     * Query properties — returns a WP_Query object.
     *
     * @param array $args See IPP_Developer_API::build_query_args().
     * @return WP_Query
     */
    function ipp_query_properties( $args = [] ) {
        $query_args = IPP_Developer_API::build_query_args( $args );
        return new WP_Query( $query_args );
    }
}

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