<?php
namespace Bookaro\Controller;

defined( 'ABSPATH' ) || exit;

/**
 * Registers Gutenberg blocks that map to Bookaro shortcodes.
 */
class BlocksController
{
    private const CATEGORY = 'bookaro';

    public function register_hooks(): void
    {
        add_action( 'init', [ $this, 'register_blocks' ] );
        add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_editor_assets' ] );
        add_filter( 'block_categories_all', [ $this, 'register_category' ], 10, 2 );
    }

    public function register_category( array $categories, $post ): array
    {
        foreach ( $categories as $category ) {
            if ( ( $category['slug'] ?? '' ) === self::CATEGORY ) {
                return $categories;
            }
        }

        $categories[] = [
            'slug'  => self::CATEGORY,
            'title' => __( 'MyBookaro', 'mybookaro' ),
        ];

        return $categories;
    }

    public function register_blocks(): void
    {
        if ( ! function_exists( 'register_block_type' ) ) {
            return;
        }

        register_block_type( 'bookaro/booking-button', [
            'api_version'     => 3,
            'category'        => self::CATEGORY,
            'title'           => __( 'MyBookaro Booking Button', 'mybookaro' ),
            'description'     => __( 'Render the MyBookaro booking button.', 'mybookaro' ),
            'render_callback' => [ $this, 'render_booking_button' ],
            'attributes'      => $this->get_booking_attributes(),
        ] );

        register_block_type( 'bookaro/booking-form', [
            'api_version'     => 3,
            'category'        => self::CATEGORY,
            'title'           => __( 'MyBookaro Booking Form', 'mybookaro' ),
            'description'     => __( 'Render the MyBookaro booking form.', 'mybookaro' ),
            'render_callback' => [ $this, 'render_booking_form' ],
            'attributes'      => $this->get_booking_attributes( true ),
        ] );

        register_block_type( 'bookaro/provider-dashboard', [
            'api_version'     => 3,
            'category'        => self::CATEGORY,
            'title'           => __( 'MyBookaro Provider Dashboard', 'mybookaro' ),
            'description'     => __( 'Render the provider dashboard.', 'mybookaro' ),
            'render_callback' => fn( $attrs ) => do_shortcode( '[bookaro_provider_dashboard]' ),
        ] );

        register_block_type( 'bookaro/customer-dashboard', [
            'api_version'     => 3,
            'category'        => self::CATEGORY,
            'title'           => __( 'MyBookaro Customer Dashboard', 'mybookaro' ),
            'description'     => __( 'Render the customer dashboard.', 'mybookaro' ),
            'render_callback' => fn( $attrs ) => do_shortcode( '[bookaro_customer_dashboard]' ),
        ] );

        register_block_type( 'bookaro/services-cards', [
            'api_version'     => 3,
            'category'        => self::CATEGORY,
            'title'           => __( 'MyBookaro Services Cards', 'mybookaro' ),
            'description'     => __( 'Render service cards for a listing.', 'mybookaro' ),
            'render_callback' => [ $this, 'render_services_cards' ],
            'attributes'      => $this->get_services_cards_attributes(),
        ] );
    }

    public function enqueue_editor_assets(): void
    {
        wp_enqueue_script(
            'bookaro-blocks',
            BOOKARO_PLUGIN_URL . 'assets/js/blocks.js',
            [ 'wp-blocks', 'wp-element', 'wp-components', 'wp-block-editor', 'wp-i18n' ],
            BOOKARO_VERSION,
            true
        );

        $rest_url = function_exists( 'rest_url' ) ? rest_url( 'bookaro/v1' ) : '';
        wp_localize_script(
            'bookaro-blocks',
            'BookaroBlocksData',
            [
                'restUrl' => esc_url_raw( $rest_url ),
                'restNonce' => wp_create_nonce( 'wp_rest' ),
            ]
        );
    }

    public function render_booking_button( array $attributes ): string
    {
        $attrs = $this->sanitize_booking_attributes( $attributes, false );
        return do_shortcode( $this->build_shortcode( 'bookaro_booking_button', $attrs ) );
    }

    public function render_booking_form( array $attributes ): string
    {
        $attrs = $this->sanitize_booking_attributes( $attributes, true );
        return do_shortcode( $this->build_shortcode( 'bookaro_booking_form', $attrs ) );
    }

    public function render_services_cards( array $attributes ): string
    {
        $attrs = $this->sanitize_services_cards_attributes( $attributes );
        return do_shortcode( $this->build_shortcode( 'bookaro_services_cards', $attrs ) );
    }

    private function get_booking_attributes( bool $include_auto_open = false ): array
    {
        $attrs = [
            'listingId'    => [ 'type' => 'number', 'default' => 0 ],
            'providerId'   => [ 'type' => 'number', 'default' => 0 ],
            'serviceId'    => [ 'type' => 'number', 'default' => 0 ],
            'serviceLabel' => [ 'type' => 'string', 'default' => '' ],
            'price'        => [ 'type' => 'string', 'default' => '' ],
            'serviceDuration' => [ 'type' => 'number', 'default' => 0 ],
            'buttonLabel'  => [ 'type' => 'string', 'default' => '' ],
            'className'    => [ 'type' => 'string', 'default' => '' ],
        ];

        if ( $include_auto_open ) {
            $attrs['autoOpen'] = [ 'type' => 'boolean', 'default' => true ];
        }

        return $attrs;
    }

    private function get_services_cards_attributes(): array
    {
        return [
            'listingId'    => [ 'type' => 'number', 'default' => 0 ],
            'providerId'   => [ 'type' => 'number', 'default' => 0 ],
            'listingSource'=> [ 'type' => 'string', 'default' => 'current' ],
            'mode'         => [ 'type' => 'string', 'default' => 'auto' ],
            'layout'       => [ 'type' => 'string', 'default' => 'grid' ],
            'columns'      => [ 'type' => 'number', 'default' => 3 ],
            'showPrice'    => [ 'type' => 'boolean', 'default' => true ],
            'showDuration' => [ 'type' => 'boolean', 'default' => true ],
            'source'       => [ 'type' => 'string', 'default' => 'auto' ],
        ];
    }

    private function sanitize_booking_attributes( array $attributes, bool $include_auto_open ): array
    {
        $attrs = [
            'listing_id'   => absint( $attributes['listingId'] ?? 0 ),
            'provider_id'  => absint( $attributes['providerId'] ?? 0 ),
            'service_id'   => absint( $attributes['serviceId'] ?? 0 ),
            'service_label'=> sanitize_text_field( $attributes['serviceLabel'] ?? '' ),
            'price'        => sanitize_text_field( $attributes['price'] ?? '' ),
            'duration'     => absint( $attributes['serviceDuration'] ?? 0 ),
            'button_label' => sanitize_text_field( $attributes['buttonLabel'] ?? '' ),
            'class'        => sanitize_text_field( $attributes['className'] ?? '' ),
        ];

        if ( $include_auto_open ) {
            $attrs['auto_open'] = ! empty( $attributes['autoOpen'] ) ? 'true' : 'false';
        }

        return $attrs;
    }

    private function sanitize_services_cards_attributes( array $attributes ): array
    {
        $columns = absint( $attributes['columns'] ?? 3 );
        if ( $columns < 1 ) {
            $columns = 3;
        }
        $mode = sanitize_key( (string) ( $attributes['mode'] ?? '' ) );
        $source = sanitize_key( (string) ( $attributes['source'] ?? '' ) );
        if ( ( '' === $mode || 'auto' === $mode ) && '' !== $source && 'auto' !== $source ) {
            $mode = ( 'bookaro' === $source ) ? 'generic' : $source;
        }
        if ( ! in_array( $mode, [ 'auto', 'mylisting', 'generic' ], true ) ) {
            $mode = 'auto';
        }
        if ( ! in_array( $source, [ 'auto', 'provider', 'mylisting', 'generic', 'bookaro', '' ], true ) ) {
            $source = '';
        }

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

        $listing_id = absint( $attributes['listingId'] ?? 0 );
        $listing_source = sanitize_key( (string) ( $attributes['listingSource'] ?? '' ) );
        if ( '' === $listing_source ) {
            $listing_source = $listing_id > 0 ? 'manual' : 'current';
        }
        if ( 'manual' !== $listing_source ) {
            $listing_id = 0;
        }

        return [
            'listing_id'   => $listing_id,
            'provider_id'  => absint( $attributes['providerId'] ?? 0 ),
            'mode'         => $mode,
            'layout'       => $layout,
            'columns'      => $columns,
            'show_price'   => ! empty( $attributes['showPrice'] ) ? '1' : '0',
            'show_duration'=> ! empty( $attributes['showDuration'] ) ? '1' : '0',
            'source'       => $source,
        ];
    }

    private function build_shortcode( string $tag, array $attrs ): string
    {
        $pairs = [];
        foreach ( $attrs as $key => $value ) {
            if ( '' === $value || 0 === $value ) {
                if ( in_array( $key, [ 'listing_id', 'provider_id', 'service_id' ], true ) ) {
                    continue;
                }
                if ( in_array( $key, [ 'service_label', 'price', 'button_label', 'class' ], true ) ) {
                    if ( $value === '' ) {
                        continue;
                    }
                }
            }
            $pairs[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) );
        }

        $attr_string = implode( ' ', $pairs );
        if ( '' === $attr_string ) {
            return sprintf( '[%s]', $tag );
        }
        return sprintf( '[%s %s]', $tag, $attr_string );
    }
}
