<?php

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

if ( ! function_exists( 'bookaro_get_mylisting_services_repeater_class' ) ) {
    function bookaro_get_mylisting_services_repeater_class( array $settings = [] ): string {
        if ( empty( $settings ) ) {
            $settings = get_option( 'bookaro_settings', [] );
        }

        $target_class = 'mybookaro_services';
        if ( is_array( $settings ) ) {
            $target_class = sanitize_key( (string) ( $settings['mylisting_services_repeater_class'] ?? $target_class ) );
        }
        if ( '' === $target_class ) {
            $target_class = 'mybookaro_services';
        }

        return $target_class;
    }
}

if ( ! function_exists( 'bookaro_resolve_mylisting_services_payload' ) ) {
    /**
     * Resolve services and return diagnostics for MyListing repeater parsing.
     *
     * @return array{services:array,diagnostics:array}
     */
    function bookaro_resolve_mylisting_services_payload( array $services, int $listing_id, string $mode ): array {
        $target_class = bookaro_get_mylisting_services_repeater_class();
        $diagnostics = [
            'mode' => sanitize_key( $mode ),
            'listing_id' => absint( $listing_id ),
            'target_repeater_class' => $target_class,
            'reason_code' => '',
            'resolution_path' => 'none',
            'status' => 'info',
            'summary' => '',
            'detail' => '',
            'fix' => '',
            'row_count_total' => 0,
            'row_count_valid' => 0,
            'row_count_service_like' => 0,
            'row_count_class_match' => 0,
            'row_count_prefix_fallback' => 0,
            'row_count_class_mismatch' => 0,
            'row_count_missing_label' => 0,
            'resolved_services_count' => count( $services ),
            'detected_prefixes' => [],
            'detected_prefix_counts' => [],
            'detected_classes' => [],
            'detected_class_counts' => [],
            'primary_detected_prefix' => '',
            'primary_detected_class' => '',
            'prefix_mismatch' => false,
            'configured_prefix_detected' => false,
        ];

        $set_reason = static function ( array $diag, string $reason_code, string $status, string $summary, string $detail, string $fix = '' ): array {
            $diag['reason_code'] = sanitize_key( $reason_code );
            $diag['status'] = sanitize_key( $status );
            $diag['summary'] = trim( $summary );
            $diag['detail'] = trim( $detail );
            $diag['fix'] = trim( $fix );
            return $diag;
        };

        if ( 'mylisting' !== $mode ) {
            $diagnostics = $set_reason(
                $diagnostics,
                'mode_not_mylisting',
                'info',
                'MyListing repeater parsing is not active for this mode.',
                'Services are resolved through a non-MyListing mode, so repeater diagnostics are informational only.'
            );
            return [
                'services' => $services,
                'diagnostics' => $diagnostics,
            ];
        }

        if ( ! empty( $services ) ) {
            $diagnostics = $set_reason(
                $diagnostics,
                'pre_resolved_services',
                'ok',
                'Services were already provided before MyListing repeater parsing.',
                'Bookaro did not need to parse repeater rows because services were resolved earlier in the pipeline.'
            );
            return [
                'services' => $services,
                'diagnostics' => $diagnostics,
            ];
        }

        if ( $listing_id < 1 ) {
            $diagnostics = $set_reason(
                $diagnostics,
                'listing_not_selected',
                'warn',
                'Select a listing to run MyListing service diagnostics.',
                'Bookaro cannot read repeater rows without a valid listing ID.'
            );
            return [
                'services' => $services,
                'diagnostics' => $diagnostics,
            ];
        }

        if ( function_exists( 'bookaro_is_allowed_listing' ) && ! bookaro_is_allowed_listing( $listing_id ) ) {
            $diagnostics = $set_reason(
                $diagnostics,
                'listing_not_allowed',
                'warn',
                'This listing is not eligible for the current listing rules.',
                'Bookaro skipped MyListing repeater parsing because the listing is not allowed by current listing post type rules.'
            );
            return [
                'services' => $services,
                'diagnostics' => $diagnostics,
            ];
        }

        $rows = get_post_meta( $listing_id, '_repeater', true );
        if ( ! is_array( $rows ) || empty( $rows ) ) {
            $diagnostics['row_count_total'] = is_array( $rows ) ? count( $rows ) : 0;
            $diagnostics = $set_reason(
                $diagnostics,
                'no_repeater_rows',
                'warn',
                'No repeater rows were found on this listing.',
                'Bookaro could not locate `_repeater` rows to read service labels, prices, or durations.',
                'Open the MyListing listing type and add service repeater rows, then refresh diagnostics.'
            );
            return [
                'services' => $services,
                'diagnostics' => $diagnostics,
            ];
        }

        $prefix = $target_class;
        $candidate_prefixes = static function ( array $normalized ): array {
            $candidates = [];
            foreach ( array_keys( $normalized ) as $key ) {
                if ( preg_match( '/^(.+?)-(label|price|price-amount|duration|duration-minutes|description)$/', $key, $matches ) ) {
                    $candidate = sanitize_key( $matches[1] );
                    if ( '' !== $candidate ) {
                        $candidates[ $candidate ] = ( $candidates[ $candidate ] ?? 0 ) + 1;
                    }
                }
            }
            return $candidates;
        };

        $detect_prefix = static function ( array $row, string $default_prefix ) use ( $candidate_prefixes ): string {
            $normalized = [];
            foreach ( $row as $key => $value ) {
                $normalized[ sanitize_key( (string) $key ) ] = $value;
            }
            $candidates = $candidate_prefixes( $normalized );
            if ( '' !== $default_prefix && isset( $candidates[ $default_prefix ] ) ) {
                return $default_prefix;
            }
            if ( ! empty( $candidates ) ) {
                foreach ( array_keys( $candidates ) as $candidate ) {
                    if ( array_key_exists( $candidate . '-label', $normalized ) ) {
                        return $candidate;
                    }
                }
                foreach ( $candidates as $candidate => $count ) {
                    unset( $count );
                    return (string) $candidate;
                }
            }
            return $default_prefix;
        };

        $has_service_fields = static function ( array $row, string $row_prefix ): bool {
            if ( '' === $row_prefix ) {
                return false;
            }
            $normalized = [];
            foreach ( $row as $key => $value ) {
                $normalized[ sanitize_key( (string) $key ) ] = $value;
            }
            foreach ( [ $row_prefix . '-label', $row_prefix . '-price', $row_prefix . '-price-amount', $row_prefix . '-duration', $row_prefix . '-duration-minutes' ] as $key ) {
                if ( array_key_exists( $key, $normalized ) ) {
                    return true;
                }
            }
            return false;
        };

        $detected_prefix_counts = [];
        $detected_class_counts = [];
        $diagnostics['row_count_total'] = count( $rows );

        $filtered_rows = [];
        foreach ( $rows as $row ) {
            if ( ! is_array( $row ) ) {
                continue;
            }
            $diagnostics['row_count_valid']++;

            $normalized = [];
            foreach ( $row as $key => $value ) {
                $normalized[ sanitize_key( (string) $key ) ] = $value;
            }

            $row_candidates = $candidate_prefixes( $normalized );
            foreach ( $row_candidates as $candidate => $count ) {
                $detected_prefix_counts[ $candidate ] = ( $detected_prefix_counts[ $candidate ] ?? 0 ) + (int) $count;
            }

            $row_prefix = $detect_prefix( $row, $prefix );
            $row_has_prefix = $has_service_fields( $row, $row_prefix );
            if ( $row_has_prefix ) {
                $diagnostics['row_count_service_like']++;
            }

            $class_raw = '';
            foreach ( [ 'class', 'classes', 'css_class', 'cssClass', 'class_name' ] as $key ) {
                if ( ! empty( $row[ $key ] ) ) {
                    $class_raw = (string) $row[ $key ];
                    break;
                }
            }

            if ( '' !== $class_raw ) {
                $tokens = preg_split( '/\s+/', strtolower( trim( $class_raw ) ) );
                if ( ! is_array( $tokens ) ) {
                    continue;
                }
                $tokens = array_values( array_filter( array_map( 'sanitize_key', $tokens ) ) );
                foreach ( $tokens as $token ) {
                    $detected_class_counts[ $token ] = ( $detected_class_counts[ $token ] ?? 0 ) + 1;
                }
                if ( in_array( $target_class, $tokens, true ) ) {
                    $diagnostics['row_count_class_match']++;
                    $filtered_rows[] = $row;
                } elseif ( $row_has_prefix ) {
                    $diagnostics['row_count_class_mismatch']++;
                }
                continue;
            }

            if ( $row_has_prefix ) {
                $diagnostics['row_count_prefix_fallback']++;
                $filtered_rows[] = $row;
            }
        }

        if ( ! empty( $detected_prefix_counts ) ) {
            arsort( $detected_prefix_counts );
            $diagnostics['detected_prefix_counts'] = $detected_prefix_counts;
            $diagnostics['detected_prefixes'] = array_values( array_keys( $detected_prefix_counts ) );
            $primary = array_key_first( $detected_prefix_counts );
            if ( is_string( $primary ) ) {
                $diagnostics['primary_detected_prefix'] = $primary;
            }
        }

        if ( ! empty( $detected_class_counts ) ) {
            arsort( $detected_class_counts );
            $diagnostics['detected_class_counts'] = $detected_class_counts;
            $diagnostics['detected_classes'] = array_values( array_keys( $detected_class_counts ) );
            $primary_class = array_key_first( $detected_class_counts );
            if ( is_string( $primary_class ) ) {
                $diagnostics['primary_detected_class'] = $primary_class;
            }
        }

        $diagnostics['configured_prefix_detected'] = isset( $detected_prefix_counts[ $target_class ] );
        $diagnostics['prefix_mismatch'] = $diagnostics['row_count_service_like'] > 0
            && ! $diagnostics['configured_prefix_detected'];

        $resolved = [];
        $row_index = 0;
        foreach ( $filtered_rows as $row ) {
            if ( ! is_array( $row ) ) {
                $row_index++;
                continue;
            }
            $row_prefix = $detect_prefix( $row, $prefix );
            $normalized = [];
            foreach ( $row as $key => $value ) {
                $normalized[ sanitize_key( (string) $key ) ] = $value;
            }
            $token = '';
            foreach ( [ 'menu-id', 'menu_id', 'menuId', 'id', '_id', 'uid' ] as $key ) {
                $normalized_key = sanitize_key( $key );
                if ( ! empty( $normalized[ $normalized_key ] ) ) {
                    $token = sanitize_text_field( (string) $normalized[ $normalized_key ] );
                    break;
                }
            }
            if ( '' === $token ) {
                $token = (string) $row_index;
            }
            $label = sanitize_text_field( $normalized[ $row_prefix . '-label' ] ?? '' );
            if ( '' === $label ) {
                if ( $has_service_fields( $row, $row_prefix ) ) {
                    $diagnostics['row_count_missing_label']++;
                }
                $row_index++;
                continue;
            }
            $description = sanitize_textarea_field( $normalized[ $row_prefix . '-description' ] ?? '' );
            $duration = 0;
            foreach ( [ $row_prefix . '-duration', $row_prefix . '-duration-minutes' ] as $key ) {
                if ( ! empty( $normalized[ $key ] ) ) {
                    $duration = absint( $normalized[ $key ] );
                    break;
                }
            }

            $price = 0.0;
            foreach ( [ $row_prefix . '-price', $row_prefix . '-price-amount' ] as $key ) {
                if ( ! empty( $normalized[ $key ] ) ) {
                    $raw = (string) $normalized[ $key ];
                    $price = function_exists( 'bookaro_parse_price_string' )
                        ? bookaro_parse_price_string( $raw )
                        : (float) $raw;
                    break;
                }
            }

            $price_formatted = function_exists( 'bookaro_format_price' )
                ? bookaro_format_price( $price )
                : '';

            $resolved[] = [
                'id'          => 0,
                'token'       => $token,
                'title'       => $label,
                'description' => $description,
                'price'       => $price,
                'price_formatted' => $price_formatted,
                'duration'    => $duration,
                'listing_id'  => $listing_id,
            ];
            $row_index++;
        }

        $resolved_count = count( $resolved );
        $diagnostics['resolved_services_count'] = $resolved_count;
        if ( $diagnostics['row_count_class_match'] > 0 && $diagnostics['row_count_prefix_fallback'] > 0 ) {
            $diagnostics['resolution_path'] = 'class_and_prefix';
        } elseif ( $diagnostics['row_count_class_match'] > 0 ) {
            $diagnostics['resolution_path'] = 'class_match';
        } elseif ( $diagnostics['row_count_prefix_fallback'] > 0 ) {
            $diagnostics['resolution_path'] = 'prefix_fallback';
        }

        if ( $resolved_count > 0 ) {
            $reason_code = 'resolved_with_class_and_prefix';
            if ( 'class_match' === $diagnostics['resolution_path'] ) {
                $reason_code = 'resolved_with_class_match';
            } elseif ( 'prefix_fallback' === $diagnostics['resolution_path'] ) {
                $reason_code = 'resolved_with_prefix_fallback';
            }

            $detail = sprintf(
                'Resolved %1$d service row(s). Class match rows: %2$d, prefix fallback rows: %3$d.',
                $resolved_count,
                (int) $diagnostics['row_count_class_match'],
                (int) $diagnostics['row_count_prefix_fallback']
            );
            if ( $diagnostics['prefix_mismatch'] ) {
                $detail .= sprintf(
                    ' Detected prefix `%1$s` differs from configured class `%2$s`.',
                    (string) ( $diagnostics['primary_detected_prefix'] ?: 'none' ),
                    $target_class
                );
            }

            $diagnostics = $set_reason(
                $diagnostics,
                $reason_code,
                'ok',
                'MyListing services resolved successfully.',
                $detail
            );
        } elseif ( $diagnostics['row_count_service_like'] < 1 ) {
            $prefix_hint = (string) ( $diagnostics['primary_detected_prefix'] ?? '' );
            $detail = 'Repeater rows were found, but Bookaro did not detect service fields like `<prefix>-label`.';
            if ( '' !== $prefix_hint ) {
                $detail .= sprintf( ' Primary detected prefix: `%s`.', $prefix_hint );
            }
            $diagnostics = $set_reason(
                $diagnostics,
                'no_service_like_rows',
                'warn',
                'No service-like rows were detected.',
                $detail,
                'Ensure repeater fields use keys such as `<prefix>-label`, `<prefix>-price`, or `<prefix>-duration`.'
            );
        } elseif ( $diagnostics['row_count_class_mismatch'] > 0 && $diagnostics['row_count_class_match'] < 1 && $diagnostics['row_count_prefix_fallback'] < 1 ) {
            $classes = empty( $diagnostics['detected_classes'] ) ? 'none' : implode( ', ', (array) $diagnostics['detected_classes'] );
            $prefixes = empty( $diagnostics['detected_prefixes'] ) ? 'none' : implode( ', ', (array) $diagnostics['detected_prefixes'] );
            $diagnostics = $set_reason(
                $diagnostics,
                'class_mismatch',
                'error',
                'Service-like rows exist, but repeater class matching failed.',
                sprintf(
                    'Configured class `%1$s` was not found in row classes (%2$s). Detected prefixes: %3$s.',
                    $target_class,
                    $classes,
                    $prefixes
                ),
                'Set Services Repeater Class to the class used by service rows, or update listing-type row classes to include the configured value.'
            );
        } elseif ( $diagnostics['row_count_missing_label'] > 0 ) {
            $diagnostics = $set_reason(
                $diagnostics,
                'missing_service_labels',
                'warn',
                'Service rows matched, but labels were empty.',
                sprintf(
                    '%d matched row(s) were skipped because `<prefix>-label` is empty.',
                    (int) $diagnostics['row_count_missing_label']
                ),
                'Fill the service label field in each repeater row so Bookaro can expose services to booking.'
            );
        } else {
            $diagnostics = $set_reason(
                $diagnostics,
                'no_resolved_services',
                'warn',
                'Service rows were found but none resolved.',
                'Bookaro parsed repeater rows but could not build a usable service payload from the current row data.'
            );
        }

        return [
            'services' => $resolved,
            'diagnostics' => $diagnostics,
        ];
    }
}

if ( ! function_exists( 'bookaro_resolve_mylisting_services' ) ) {
    /**
     * Resolve MyListing services from the listing repeater meta.
     */
    function bookaro_resolve_mylisting_services( array $services, int $listing_id, string $mode ): array {
        $payload = bookaro_resolve_mylisting_services_payload( $services, $listing_id, $mode );
        $resolved = $payload['services'] ?? [];
        return is_array( $resolved ) ? $resolved : [];
    }
}

if ( ! function_exists( 'bookaro_get_mylisting_service_resolution_diagnostics' ) ) {
    function bookaro_get_mylisting_service_resolution_diagnostics( int $listing_id ): array {
        $payload = bookaro_resolve_mylisting_services_payload( [], $listing_id, 'mylisting' );
        $diagnostics = $payload['diagnostics'] ?? [];
        return is_array( $diagnostics ) ? $diagnostics : [];
    }
}

add_filter( 'bookaro_listing_services', 'bookaro_resolve_mylisting_services', 10, 3 );
add_filter( 'bookaro_integration_modes', static function ( array $modes ): array {
    $modes['mylisting'] = __( 'MyListing', 'mybookaro' );
    return $modes;
} );

add_filter( 'bookaro_blocked_listing_post_types', static function ( array $blocked, string $mode ): array {
    if ( 'mylisting' === $mode ) {
        return [];
    }
    return $blocked;
}, 10, 2 );

add_filter( 'bookaro_listing_post_type', static function ( string $post_type, string $mode ): string {
    if ( 'mylisting' === $mode ) {
        $settings = get_option( 'bookaro_settings', [] );
        if ( is_array( $settings ) ) {
            $selected = '';
            if ( ! empty( $settings['listing_post_type'] ) ) {
                $selected = sanitize_key( (string) $settings['listing_post_type'] );
            } elseif ( ! empty( $settings['allowed_listing_post_types'] ) && is_array( $settings['allowed_listing_post_types'] ) ) {
                $selected = sanitize_key( (string) ( $settings['allowed_listing_post_types'][0] ?? '' ) );
            }
            if ( $selected !== '' ) {
                return $selected;
            }
        }
        return 'job_listing';
    }
    return $post_type;
}, 10, 2 );

add_filter( 'bookaro_allowed_listing_post_types', static function ( array $types, string $mode ): array {
    if ( 'mylisting' !== $mode ) {
        return $types;
    }
    return $types;
}, 10, 2 );

add_filter( 'bookaro_show_provider_ui', static function ( bool $show ): bool {
    return ( function_exists( 'bookaro_get_integration_mode' ) && 'mylisting' === bookaro_get_integration_mode() )
        ? false
        : $show;
} );

add_filter( 'bookaro_show_service_ui', static function ( bool $show ): bool {
    return ( function_exists( 'bookaro_get_integration_mode' ) && 'mylisting' === bookaro_get_integration_mode() )
        ? false
        : $show;
} );

add_filter( 'bookaro_integration_service_duration', static function ( int $duration, int $listing_id, string $service_label, int $service_id = 0 ): int {
    if ( $duration > 0 ) {
        return $duration;
    }
    if ( ! function_exists( 'bookaro_get_integration_mode' ) || 'mylisting' !== bookaro_get_integration_mode() ) {
        return $duration;
    }
    if ( $listing_id < 1 || $service_label === '' ) {
        return $duration;
    }

    $services = function_exists( 'bookaro_resolve_listing_services' )
        ? bookaro_resolve_listing_services( $listing_id, 'mylisting' )
        : bookaro_resolve_mylisting_services( [], $listing_id, 'mylisting' );
    if ( ! is_array( $services ) ) {
        return $duration;
    }

    $needle = strtolower( trim( $service_label ) );
    foreach ( $services as $service ) {
        $title = strtolower( trim( (string) ( $service['title'] ?? '' ) ) );
        if ( $title === $needle && ! empty( $service['duration'] ) ) {
            return absint( $service['duration'] );
        }
    }

    return $duration;
}, 10, 4 );

add_filter( 'bookaro_booking_data', static function ( array $data, array $context, string $mode ): array {
    if ( 'mylisting' !== $mode ) {
        return $data;
    }
    $listing_id = (int) ( $context['listing_id'] ?? 0 );
    if ( $listing_id < 1 ) {
        return $data;
    }

    $services = function_exists( 'bookaro_resolve_listing_services' )
        ? bookaro_resolve_listing_services( $listing_id, 'mylisting' )
        : bookaro_resolve_mylisting_services( [], $listing_id, 'mylisting' );
    if ( ! is_array( $services ) ) {
        return $data;
    }

    $durations = [];
    foreach ( $services as $service ) {
        $title = strtolower( trim( (string) ( $service['title'] ?? '' ) ) );
        $duration = absint( $service['duration'] ?? 0 );
        if ( $title && $duration > 0 ) {
            $durations[ $title ] = $duration;
        }
    }
    $data['service_durations'] = $durations;

    $target_class = bookaro_get_mylisting_services_repeater_class();
    $data['mylisting_services_repeater_class'] = $target_class;

    return $data;
}, 10, 3 );

if ( ! function_exists( 'bookaro_render_mylisting_booking_button' ) ) {
    if ( ! function_exists( 'bookaro_render_mylisting_booking_container' ) ) {
        function bookaro_render_mylisting_booking_container(): void {
            if ( function_exists( 'bookaro_is_frontend_enabled' ) && ! bookaro_is_frontend_enabled() ) {
                return;
            }
            // Shared render-once guard across Lite + Pro: emit the
            // #bookaro-booking-app mount point at most once per request so a
            // single Vue instance mounts cleanly. Pro's BookingPopupController
            // checks the same flag, preventing duplicate element IDs that
            // otherwise collapse the widget on MyListing listing pages.
            if ( ! empty( $GLOBALS['bookaro_booking_app_rendered'] ) ) {
                return;
            }
            $GLOBALS['bookaro_booking_app_rendered'] = true;
            echo '<div id="bookaro-booking-app" class="bookaro-scope"></div>';
        }
    }

    function bookaro_render_mylisting_booking_button( $listing = null ): void {
        if ( function_exists( 'bookaro_is_frontend_enabled' ) && ! bookaro_is_frontend_enabled() ) {
            return;
        }
        if ( ! function_exists( 'bookaro_get_integration_mode' ) || 'mylisting' !== bookaro_get_integration_mode() ) {
            return;
        }
        if ( function_exists( 'bookaro_feature_enabled' ) && ! bookaro_feature_enabled( 'mylisting' ) ) {
            return;
        }

        $listing_id = 0;
        if ( is_object( $listing ) && isset( $listing->ID ) ) {
            $listing_id = (int) $listing->ID;
        }
        if ( $listing_id < 1 ) {
            $listing_id = (int) get_the_ID();
        }
        if ( $listing_id < 1 ) {
            return;
        }
        if ( function_exists( 'bookaro_is_allowed_listing' ) && ! bookaro_is_allowed_listing( $listing_id ) ) {
            return;
        }

        $provider_id = function_exists( 'bookaro_get_listing_owner_id' )
            ? (int) bookaro_get_listing_owner_id( $listing_id )
            : 0;
        if ( $provider_id < 1 ) {
            return;
        }

        $listing_price_meta_key = apply_filters(
            'bookaro_listing_price_meta_key',
            'bookaro_listing_price',
            $listing_id,
            'mylisting'
        );
        $listing_price = 0.0;
        if ( is_string( $listing_price_meta_key ) && '' !== $listing_price_meta_key ) {
            $listing_price_raw = get_post_meta( $listing_id, $listing_price_meta_key, true );
            if ( is_scalar( $listing_price_raw ) ) {
                $listing_price = function_exists( 'bookaro_parse_price_string' )
                    ? bookaro_parse_price_string( $listing_price_raw )
                    : (float) $listing_price_raw;
            }
        }

        $button_label = apply_filters(
            'bookaro_booking_button_label',
            __( 'Book Now', 'mybookaro' ),
            $listing_id,
            'mylisting'
        );

        printf(
            '<button type="button" class="bookaro-booking-btn bookaro-booking-launch bookaro-scope" data-listing-id="%1$d" data-provider-id="%2$d" data-service-label="" data-listing-price="%3$s" data-service-id="0">%4$s</button>',
            (int) $listing_id,
            (int) $provider_id,
            esc_attr( (string) $listing_price ),
            esc_html( $button_label )
        );
    }
}

add_action( 'mylisting/single/sidebar/actions', 'bookaro_render_mylisting_booking_button', 20, 1 );
add_action( 'wp_enqueue_scripts', 'bookaro_enqueue_mylisting_assets', 20 );

function bookaro_enqueue_mylisting_assets(): void {
    if ( function_exists( 'bookaro_is_frontend_enabled' ) && ! bookaro_is_frontend_enabled() ) {
        return;
    }
    $is_listing = function_exists( 'bookaro_is_listing_singular' )
        ? bookaro_is_listing_singular()
        : is_singular( 'job_listing' );
    if ( ! $is_listing ) {
        return;
    }
    if ( ! function_exists( 'bookaro_get_integration_mode' ) || 'mylisting' !== bookaro_get_integration_mode() ) {
        return;
    }

    global $post;
    if ( ! $post ) {
        return;
    }

    $listing_id = (int) $post->ID;
    if ( $listing_id < 1 ) {
        return;
    }

    $user = wp_get_current_user();
    $provider_id = function_exists( 'bookaro_get_listing_owner_id' )
        ? (int) bookaro_get_listing_owner_id( $listing_id )
        : 0;
    if ( $provider_id < 1 ) {
        return;
    }

    $integration_mode = 'mylisting';
    $listing_price_meta_key = apply_filters(
        'bookaro_listing_price_meta_key',
        'bookaro_listing_price',
        $listing_id,
        $integration_mode
    );
    $listing_price = 0.0;
    if ( is_string( $listing_price_meta_key ) && '' !== $listing_price_meta_key ) {
        $listing_price_raw = get_post_meta( $listing_id, $listing_price_meta_key, true );
        if ( is_scalar( $listing_price_raw ) ) {
            $listing_price = function_exists( 'bookaro_parse_price_string' )
                ? bookaro_parse_price_string( $listing_price_raw )
                : (float) $listing_price_raw;
        }
    }
    $listing_price_formatted = function_exists( 'bookaro_format_price' )
        ? bookaro_format_price( $listing_price )
        : '';

    $schedule = new \Bookaro\Service\ScheduleService( new \Bookaro\Repository\BookingRepository() );
    $has_timeslots = ! empty( $schedule->get_timeslots( $provider_id ) );

    $theme_services = function_exists( 'bookaro_resolve_listing_services' )
        ? bookaro_resolve_listing_services( $listing_id, $integration_mode )
        : [];
    $has_services = ! empty( $theme_services );

    $bookaro_services = function_exists( 'bookaro_get_bookaro_services_for_listing' )
        ? bookaro_get_bookaro_services_for_listing( $listing_id )
        : [];
    $services_source = '';
    $services_payload = [];
    if ( ! $has_services && ! empty( $bookaro_services ) ) {
        $services_source = 'bookaro';
        $services_payload = $bookaro_services;
    } elseif ( $has_services ) {
        $services_source = 'theme';
    }

    wp_enqueue_script( 'jquery' );
    bookaro_enqueue_dayjs_locale();
    wp_enqueue_style( 'flatpickr-css', BOOKARO_PLUGIN_URL . 'assets/vendor/flatpickr/flatpickr.min.css', [], '4.6.13' );
    wp_enqueue_script( 'flatpickr-js', BOOKARO_PLUGIN_URL . 'assets/vendor/flatpickr/flatpickr.min.js', [ 'jquery' ], '4.6.13', true );
    wp_enqueue_style( 'bookaro-booking-tailwind', BOOKARO_PLUGIN_URL . 'assets/vendor/tailwind/tailwind.min.css', [], '2.2.19' );
    wp_enqueue_style( 'bookaro-booking-style', BOOKARO_PLUGIN_URL . 'assets/css/booking-base.css', [], BOOKARO_VERSION );
    wp_enqueue_style( 'bookaro-booking-calendar', BOOKARO_PLUGIN_URL . 'assets/css/calendar-picker.css', [], BOOKARO_VERSION );
    $booking_script_src  = BOOKARO_PLUGIN_URL . 'dist/booking.js';
    $lite_booking_path   = BOOKARO_PLUGIN_DIR . 'dist/booking.js';
    // Bug 47: use filemtime() rather than the static BOOKARO_VERSION so that a
    // rebuilt bundle cache-busts even if the plugin version constant didn't
    // change (same pattern as resolve_pro_dashboard_script).
    $booking_script_ver  = file_exists( $lite_booking_path ) ? (string) filemtime( $lite_booking_path ) : BOOKARO_VERSION;
    if (
        function_exists( 'bookaro_is_pro_active' ) &&
        bookaro_is_pro_active() &&
        defined( 'BOOKARO_PRO_PLUGIN_DIR' ) &&
        defined( 'BOOKARO_PRO_PLUGIN_URL' )
    ) {
        $pro_booking_path = BOOKARO_PRO_PLUGIN_DIR . 'dist/booking.js';
        if ( file_exists( $pro_booking_path ) ) {
            $booking_script_src = BOOKARO_PRO_PLUGIN_URL . 'dist/booking.js';
            $booking_script_ver = (string) filemtime( $pro_booking_path );
        }
    }
    wp_enqueue_script( 'bookaro-booking-script', $booking_script_src, [ 'jquery', 'flatpickr-js', 'dayjs' ], $booking_script_ver, true );
    add_action( 'wp_footer', 'bookaro_render_mylisting_booking_container', 20 );

    $dashboard_url = '';
    if ( function_exists( 'bookaro_user_has_dashboard_access' ) && bookaro_user_has_dashboard_access( $user->ID ) ) {
        $dashboard_url = function_exists( 'bookaro_get_dashboard_url' )
            ? bookaro_get_dashboard_url( [ 'listing_id' => $listing_id ] )
            : site_url( '/my-account/bookings-and-management/' );
    }

    $is_pro = function_exists( 'bookaro_is_pro_active' ) && bookaro_is_pro_active();

    $features = [
        'mylisting' => true,
    ];
    $features = apply_filters( 'bookaro_frontend_features', $features, $is_pro );


    $context = [
        'listing_id'   => $listing_id,
        'provider_id'  => $provider_id,
        'service_id'   => 0,
        'service_label'=> '',
    ];

    $data = [
        'ajax_url'     => admin_url( 'admin-ajax.php' ),
        'ajax_nonce'   => wp_create_nonce( 'bookaro_nonce' ),
        'rest_url'     => esc_url_raw( rest_url() ),
        'rest_nonce'   => wp_create_nonce( 'wp_rest' ),
        'listing_id'   => $listing_id,
        'provider_id'  => $provider_id,
        'current_user_id' => get_current_user_id(),
        'is_logged_in' => is_user_logged_in(),
        'login_url'    => function_exists( 'bookaro_get_login_url' )
            ? bookaro_get_login_url( get_permalink() )
            : site_url( '/my-account/?redirect_to=' . urlencode( get_permalink() ) ),
        'user'         => is_user_logged_in()
            ? [
                'name'  => trim( $user->first_name . ' ' . $user->last_name ) ?: $user->display_name,
                'email' => $user->user_email,
                'phone' => get_user_meta( $user->ID, 'billing_phone', true ),
            ]
            : null,
        'listing_title' => get_the_title( $listing_id ),
        'listing_url'   => get_permalink( $listing_id ),
        'listing_location' => (function_exists( 'get_post_meta' ) ? (string) apply_filters( 'bookaro_booking_location', (function () use ( $listing_id ) {
            $location = '';
            foreach ( [ 'job_location', 'geolocation_formatted_address', 'listing_location', 'location', 'address' ] as $meta_key ) {
                $value = get_post_meta( $listing_id, $meta_key, true );
                if ( is_string( $value ) && trim( $value ) !== '' ) {
                    $location = trim( $value );
                    break;
                }
            }
            return $location;
        })(), $listing_id, 0, null ) : ''),
        'provider' => (function () use ( $listing_id ) {
            $provider_id = function_exists( 'bookaro_get_listing_owner_id' )
                ? (int) bookaro_get_listing_owner_id( $listing_id )
                : 0;
            $provider = $provider_id > 0 ? get_user_by( 'ID', $provider_id ) : null;
            return [
                'id' => $provider_id,
                'name' => $provider ? $provider->display_name : '',
                'email' => $provider ? $provider->user_email : '',
                'phone' => $provider_id > 0 ? (string) get_user_meta( $provider_id, 'billing_phone', true ) : '',
            ];
        })(),
        'listing_price' => (float) $listing_price,
        'listing_price_formatted' => $listing_price_formatted,
        'dashboard_url' => $dashboard_url,
        'edit_listing_url' => get_edit_post_link( $listing_id, '' ),
        'policies' => function_exists( 'bookaro_get_option' )
            ? [
                'cancel_window_hours' => absint( bookaro_get_option( 'booking_cancel_window_hours', 0 ) ),
                'reschedule_window_hours' => absint( bookaro_get_option( 'booking_reschedule_window_hours', 0 ) ),
                'cancel_text' => sanitize_text_field( (string) bookaro_get_option( 'booking_cancel_policy_text', '' ) ),
                'reschedule_text' => sanitize_text_field( (string) bookaro_get_option( 'booking_reschedule_policy_text', '' ) ),
            ]
            : [],
        // Bug 75: the MyListing widget must localize require_login like the
        // shortcode/single-business lane (AssetsController) does, otherwise the
        // Vue computed defaults to gating and anonymous guest bookings are
        // blocked on the directory lane even when require_login=0. Pass a real
        // bool (not an int) — wp_localize_script stringifies scalars, so an int
        // 0 becomes the string "0", and !!"0" is true in JS (would re-gate). A
        // bool false serializes to "" which is correctly falsy, matching
        // AssetsController.
        'require_login' => function_exists( 'bookaro_get_option' )
            ? (bool) ! empty( bookaro_get_option( 'require_login', 1 ) )
            : true,
        'has_timeslots' => $has_timeslots,
        'has_services' => $has_services,
        'services' => $services_payload,
        'services_source' => $services_source,
        'service_durations' => [],
        'currency'    => function_exists( 'bookaro_get_currency_settings' )
            ? bookaro_get_currency_settings()
            : [],
        'is_pro'      => $is_pro,
        'features' => $features,
        'i18n'        => \Bookaro\Frontend\I18n::all(),
    ];

    $data = apply_filters( 'bookaro_booking_frontend_data', $data, $context );
    $data = apply_filters( 'bookaro_booking_data', $data, $context, $integration_mode );

    wp_localize_script(
        'bookaro-booking-script',
        'BookaroData',
        $data
    );
}

function bookaro_enqueue_dayjs_locale(): void {
    $locale = strtolower( determine_locale() );
    $locale = str_replace( '_', '-', $locale );

    wp_enqueue_script( 'dayjs', BOOKARO_PLUGIN_URL . 'assets/vendor/dayjs/dayjs.min.js', [], '1.11.10', true );

    if ( substr( $locale, 0, 2 ) !== 'en' ) {
        $locale_file = BOOKARO_PLUGIN_DIR . 'assets/vendor/dayjs/locale/' . $locale . '.js';
        if ( file_exists( $locale_file ) ) {
            wp_enqueue_script(
                'dayjs-locale',
                BOOKARO_PLUGIN_URL . 'assets/vendor/dayjs/locale/' . $locale . '.js',
                [ 'dayjs' ],
                '1.11.10',
                true
            );
            wp_add_inline_script( 'dayjs-locale', 'dayjs.locale(' . wp_json_encode( $locale ) . ');' );
        } else {
            wp_add_inline_script( 'dayjs', "dayjs.locale('en');" );
        }
    } else {
        wp_add_inline_script( 'dayjs', "dayjs.locale('en');" );
    }
}
