<?php
namespace Bookaro\Controller\Frontend;

defined( 'ABSPATH' ) || exit;

// phpcs:disable WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- meta_query is required to resolve services for the cards block and is bounded by the queried listing/provider.

final class ServicesCardsController
{
    /**
     * Render services cards HTML.
     *
     * @param array    $atts Shortcode attributes.
     * @param callable $render_booking_button Callback to render a booking button.
     */
    public function render( array $atts, callable $render_booking_button ): string
    {
        $atts = shortcode_atts(
            [
                'listing_id'    => '',
                'provider_id'   => '',
                'mode'          => '',
                'layout'        => '',
                'show_price'    => '1',
                'show_duration' => '1',
                'columns'       => '3', // Back-compat: legacy grid columns.
                'source'        => '',  // Back-compat: legacy source attribute.
            ],
            $atts,
            'bookaro_services_cards'
        );

        $explicit_listing_id = absint( $atts['listing_id'] );
        $explicit_provider_id = absint( $atts['provider_id'] );
        $has_explicit_context = ( $explicit_listing_id > 0 || $explicit_provider_id > 0 );
        $single_business = $this->is_single_business_site();

        $current_id = 0;
        if ( function_exists( 'get_the_ID' ) ) {
            $current_id = (int) get_the_ID();
        }
        if ( $current_id < 1 && function_exists( 'get_queried_object_id' ) ) {
            $current_id = (int) get_queried_object_id();
        }
        if (
            $current_id > 0
            && function_exists( 'bookaro_is_allowed_listing' )
            && ! $has_explicit_context
            && ! bookaro_is_allowed_listing( $current_id )
            && ! $single_business
        ) {
            return '<!-- Bookaro: shortcode disabled for this content type. Use an allowed listing type/page or pass listing_id/provider_id explicitly. -->';
        }

        $source = sanitize_key( (string) $atts['source'] );
        $mode = sanitize_key( (string) $atts['mode'] );
        if ( '' === $mode && '' !== $source ) {
            $mode = ( 'bookaro' === $source ) ? 'generic' : $source;
        }
        if ( ! in_array( $mode, [ 'auto', 'mylisting', 'generic' ], true ) ) {
            $mode = 'auto';
        }
        if ( 'auto' === $mode ) {
            $mode = function_exists( 'bookaro_get_integration_mode' )
                ? bookaro_get_integration_mode()
                : 'auto';
        }

        $default_provider_id = $this->get_default_provider_id();
        $provider_id = $explicit_provider_id;
        if ( ! $provider_id && $single_business && $default_provider_id > 0 ) {
            $provider_id = $default_provider_id;
        }

        $listing_id = $explicit_listing_id;
        if (
            ! $listing_id
            && $current_id > 0
            && ( ! function_exists( 'bookaro_is_allowed_listing' ) || bookaro_is_allowed_listing( $current_id ) )
            && ( ! $single_business || $provider_id < 1 )
        ) {
            $listing_id = $current_id;
        }

        if ( ! $provider_id && $listing_id ) {
            $provider_id = function_exists( 'bookaro_get_listing_owner_id' )
                ? (int) bookaro_get_listing_owner_id( $listing_id )
                : 0;
        }
        if ( ! $provider_id && $default_provider_id > 0 ) {
            $provider_id = $default_provider_id;
        }

        if ( $listing_id && function_exists( 'bookaro_is_allowed_listing' ) && ! bookaro_is_allowed_listing( $listing_id ) ) {
            return '<!-- Bookaro: invalid listing type. Open Setup Wizard > Listings and confirm allowed listing post types/pages. -->';
        }
        if ( ! $listing_id && $provider_id > 0 && 'provider' !== $source && 'mylisting' === $mode ) {
            $listing_id = $this->resolve_listing_for_provider( $provider_id );
        }
        if ( $listing_id && function_exists( 'bookaro_is_allowed_listing' ) && ! bookaro_is_allowed_listing( $listing_id ) ) {
            $listing_id = 0;
        }
        if (
            $single_business
            && 'generic' === $mode
            && $provider_id > 0
            && ! $has_explicit_context
            && ! $this->single_business_booking_page_assigned()
        ) {
            return ShortcodesController::render_single_business_setup_notice( 'missing_booking_page' );
        }
        if ( ! $listing_id && $provider_id < 1 ) {
            return $single_business
                ? ShortcodesController::render_single_business_setup_notice( 'missing_default_provider' )
                : '<!-- Bookaro: listing_id or provider_id is required. Pass listing_id/provider_id or place shortcode on an allowed listing, then verify provider mapping in Setup Wizard > Listings. -->';
        }

        $layout = sanitize_key( (string) $atts['layout'] );
        if ( ! in_array( $layout, [ 'grid', 'list' ], true ) ) {
            $layout = 'grid';
        }

        $columns = absint( $atts['columns'] );
        if ( $columns < 1 ) {
            $columns = 3;
        }
        $columns = min( 6, $columns );

        $show_price = filter_var( $atts['show_price'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
        if ( null === $show_price ) {
            $show_price = (string) $atts['show_price'] !== '0';
        }
        $show_duration = filter_var( $atts['show_duration'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
        if ( null === $show_duration ) {
            $show_duration = (string) $atts['show_duration'] !== '0';
        }

        $services = $this->resolve_services_cards_source( $listing_id, $mode, $provider_id, $source );
        if ( empty( $services ) || ! is_array( $services ) ) {
            if ( 'generic' === $mode ) {
                return $single_business
                    ? ShortcodesController::render_single_business_setup_notice( 'missing_services' )
                    : '<!-- Bookaro: no services found for this context. Check Setup Wizard > Services (Services Source) and Setup Wizard > Listings (provider mapping), then confirm services exist for this listing/provider. -->';
            }
            return '<!-- Bookaro: no services found for this context. Check Setup Wizard > Services (Services Source) and confirm services exist for this listing/provider. -->';
        }

        $cards = '';
        foreach ( $services as $service ) {
            if ( ! is_array( $service ) ) {
                continue;
            }
            $service = is_array( $service )
                ? apply_filters( 'bookaro_services_cards_service_payload', $service, $listing_id, $provider_id, $mode )
                : $service;
            if ( ! is_array( $service ) ) {
                continue;
            }

            $title = trim( (string) ( $service['title'] ?? '' ) );
            if ( '' === $title ) {
                continue;
            }
            $description = (string) ( $service['description'] ?? '' );
            $price = (float) ( $service['price'] ?? 0 );
            $price_formatted = (string) ( $service['price_formatted'] ?? '' );
            if ( '' === $price_formatted && function_exists( 'bookaro_format_price' ) ) {
                $price_formatted = bookaro_format_price( $price );
            }
            $duration = absint( $service['duration'] ?? 0 );
            $service_id = absint( $service['id'] ?? 0 );
            $service_listing_id = absint( $service['listing_id'] ?? 0 );
            if ( $listing_id < 1 && $service_listing_id > 0 ) {
                if ( function_exists( 'bookaro_is_allowed_listing' ) && ! bookaro_is_allowed_listing( $service_listing_id ) ) {
                    continue;
                }
                if ( function_exists( 'bookaro_is_lite_listing_allowed' ) && ! bookaro_is_lite_listing_allowed( $service_listing_id ) ) {
                    continue;
                }
            }
            $button_listing_id = $listing_id > 0 ? $listing_id : $service_listing_id;
            if ( $button_listing_id < 1 && $provider_id > 0 ) {
                $button_listing_id = 0;
            }
            if ( $button_listing_id < 1 && $provider_id < 1 ) {
                continue;
            }

            $button_atts = [
                'listing_id'    => $button_listing_id,
                'provider_id'   => $provider_id,
                'service_id'    => $service_id,
                'service_label' => $title,
                'price'         => (string) $price,
            ];
            $button = call_user_func( $render_booking_button, $button_atts );

            $meta_parts = [];
            if ( $show_price && $price_formatted !== '' ) {
                $meta_parts[] = '<span class="bookaro-service-card-price">' . esc_html( $price_formatted ) . '</span>';
            }
            if ( $show_duration && $duration > 0 ) {
                /* translators: %d: numeric value */
                $meta_parts[] = '<span class="bookaro-service-card-duration">' . esc_html( sprintf( __( '%d min', 'mybookaro' ), $duration ) ) . '</span>';
            }
            $meta = '';
            if ( ! empty( $meta_parts ) ) {
                $meta = '<div class="bookaro-service-card-meta">' . implode( ' ', $meta_parts ) . '</div>';
            }

            $card_class = apply_filters( 'bookaro_services_cards_card_class', 'bookaro-service-card', $service, $listing_id, $provider_id, $mode );
            $card_class = trim( (string) $card_class );
            if ( $card_class === '' ) {
                $card_class = 'bookaro-service-card';
            }

            $cards .= '<div class="' . esc_attr( $card_class ) . '">';
            $cards .= '<div class="bookaro-service-card-title">' . esc_html( $title ) . '</div>';
            if ( $description !== '' ) {
                $cards .= '<div class="bookaro-service-card-description">' . esc_html( $description ) . '</div>';
            }
            $cards .= $meta;
            $cards .= '<div class="bookaro-service-card-action">' . $button . '</div>';
            $cards .= '</div>';
        }

        if ( '' === $cards ) {
            return '<!-- Bookaro: no renderable services found. Check service assignments and Services Source configuration in Setup Wizard > Services. -->';
        }

        $wrapper_class = 'bookaro-services-cards bookaro-scope bookaro-services-cards--' . $layout;
        if ( 'grid' === $layout ) {
            $wrapper_class .= ' bookaro-services-cards--cols-' . $columns;
        }
        $wrapper_class = apply_filters( 'bookaro_services_cards_wrapper_class', $wrapper_class, $layout, $columns, $listing_id, $provider_id, $mode );
        $wrapper_class = trim( (string) $wrapper_class );
        if ( $wrapper_class === '' ) {
            $wrapper_class = 'bookaro-services-cards bookaro-scope bookaro-services-cards--' . $layout;
            if ( 'grid' === $layout ) {
                $wrapper_class .= ' bookaro-services-cards--cols-' . $columns;
            }
        }
        return '<div class="' . esc_attr( $wrapper_class ) . '">' . $cards . '</div>';
    }

    private function resolve_services_cards_source( int $listing_id, string $mode, int $provider_id, string $source ): array
    {
        if ( 'provider' === $source ) {
            if ( 'mylisting' === $mode ) {
                return [];
            }
            if ( function_exists( 'bookaro_provider_services_allowed' ) && ! bookaro_provider_services_allowed() ) {
                return [];
            }
            return $this->get_provider_services_for_context( $provider_id );
        }

        if ( $listing_id < 1 ) {
            if ( 'mylisting' === $mode ) {
                return [];
            }
            if ( function_exists( 'bookaro_get_generic_provider_context_services' ) ) {
                $services = bookaro_get_generic_provider_context_services( $provider_id );
                return is_array( $services ) ? $services : [];
            }

            return [];
        }

        if ( 'mylisting' === $mode ) {
            return function_exists( 'bookaro_resolve_listing_services' )
                ? bookaro_resolve_listing_services( $listing_id, 'mylisting' )
                : [];
        }

        return $this->resolve_generic_services( $listing_id );
    }

    private function resolve_generic_services( int $listing_id ): array
    {
        if ( $listing_id < 1 ) {
            return [];
        }

        if ( function_exists( 'bookaro_get_services_catalog_for_listing' ) ) {
            return bookaro_get_services_catalog_for_listing( $listing_id );
        }

        return function_exists( 'bookaro_get_bookaro_services_for_listing' )
            ? bookaro_get_bookaro_services_for_listing( $listing_id )
            : [];
    }

    private function resolve_listing_for_provider( int $provider_id ): int
    {
        if ( function_exists( 'bookaro_get_listing_id_for_provider' ) ) {
            return bookaro_get_listing_id_for_provider( $provider_id );
        }
        if ( $provider_id < 1 || ! function_exists( 'bookaro_get_allowed_listing_post_types' ) ) {
            return 0;
        }
        $types = bookaro_get_allowed_listing_post_types();
        if ( empty( $types ) ) {
            return 0;
        }

        $resolution_mode = function_exists( 'bookaro_get_option' )
            ? (string) bookaro_get_option( 'provider_resolution_mode', '' )
            : '';
        $resolution_mode = sanitize_key( $resolution_mode );
        $provider_meta_key = function_exists( 'bookaro_get_option' )
            ? (string) bookaro_get_option( 'provider_meta_key', '' )
            : '';
        $provider_meta_key = sanitize_key( $provider_meta_key );
        if ( $provider_meta_key === '' ) {
            $legacy_meta_key = function_exists( 'bookaro_get_option' )
                ? (string) bookaro_get_option( 'listing_provider_meta_key', '' )
                : '';
            $legacy_meta_key = sanitize_key( $legacy_meta_key );
            if ( $legacy_meta_key !== '' ) {
                $provider_meta_key = $legacy_meta_key;
            }
        }
        if ( ! in_array( $resolution_mode, [ 'author', 'meta_key' ], true ) ) {
            $resolution_mode = $provider_meta_key !== '' ? 'meta_key' : 'author';
        }

        $args = [
            'post_type'      => $types,
            'post_status'    => 'publish',
            'posts_per_page' => 5,
            'orderby'        => 'menu_order title',
            'order'          => 'ASC',
            'fields'         => 'ids',
        ];
        if ( 'meta_key' === $resolution_mode && $provider_meta_key !== '' ) {
            $args['meta_query'] = [
                [
                    'key'     => $provider_meta_key,
                    'value'   => $provider_id,
                    'compare' => '=',
                    'type'    => 'NUMERIC',
                ],
            ];
        } else {
            $args['author'] = $provider_id;
        }

        $args = apply_filters( 'bookaro_provider_listings_query_args', $args, $provider_id );
        $ids = get_posts( $args );
        foreach ( $ids as $listing_id ) {
            $listing_id = (int) $listing_id;
            if ( $listing_id > 0 && function_exists( 'bookaro_is_allowed_listing' ) && bookaro_is_allowed_listing( $listing_id ) ) {
                return $listing_id;
            }
        }

        return 0;
    }

    private function get_default_provider_id(): int
    {
        if ( ! function_exists( 'bookaro_get_option' ) ) {
            return 0;
        }

        $default_provider_id = absint( bookaro_get_option( 'default_provider_id', 0 ) );
        if ( $default_provider_id < 1 ) {
            return 0;
        }

        return get_user_by( 'ID', $default_provider_id ) ? $default_provider_id : 0;
    }

    private function single_business_booking_page_assigned(): bool
    {
        if ( ! function_exists( 'bookaro_get_option' ) ) {
            return false;
        }

        return (
            absint( bookaro_get_option( 'generic_setup_booking_page_id', 0 ) ) > 0
            || absint( bookaro_get_option( 'booking_page_id', 0 ) ) > 0
            || absint( bookaro_get_option( 'generic_setup_services_page_id', 0 ) ) > 0
        );
    }

    private function is_single_business_site(): bool
    {
        return function_exists( 'bookaro_is_single_business_site' ) && bookaro_is_single_business_site();
    }

    private function get_provider_services_for_context( int $provider_id ): array
    {
        if ( function_exists( 'bookaro_get_provider_services_for_context' ) ) {
            $services = bookaro_get_provider_services_for_context( $provider_id );
            return is_array( $services ) ? $services : [];
        }

        return [];
    }
}
