<?php
declare(strict_types=1);

namespace Help4BuilderSuite\Modules\SEO;

use Help4BuilderSuite\Support\AdminRequest;
use Help4BuilderSuite\Support\Settings;
use WP_REST_Request;
use WP_REST_Response;

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

final class GoogleBusinessAddon
{
    private const OPTION_KEY = 'h4bs_google_business_profiles';

    public function boot(): void
    {
        add_action('admin_menu', [$this, 'registerAdminPage']);
        add_action('admin_init', [$this, 'handleAdminActions']);
        add_action('rest_api_init', [$this, 'registerRestRoutes']);
        add_shortcode('h4_google_business', [$this, 'renderBusinessShortcode']);
        add_shortcode('h4_google_reviews', [$this, 'renderReviewsShortcode']);
        add_shortcode('h4_google_map', [$this, 'renderMapShortcode']);
    }

    public function registerAdminPage(): void
    {
        add_submenu_page(
            'h4bs-settings',
            __('Google Business Profiles', 'help4-builder-suite'),
            __('Google Business', 'help4-builder-suite'),
            'manage_options',
            'h4bs-google-business',
            [$this, 'renderAdminPage']
        );
    }

    public function handleAdminActions(): void
    {
        if (! is_admin() || ! current_user_can('manage_options')) {
            return;
        }
        $post = wp_unslash($_POST);
        $action = isset($post['h4bs_google_business_action']) ? sanitize_key((string) $post['h4bs_google_business_action']) : '';
        if ($action !== 'save_profiles') {
            return;
        }

        check_admin_referer('h4bs_google_business_save', 'h4bs_google_business_nonce');
        $domains = isset($post['domain']) && is_array($post['domain']) ? $post['domain'] : [];
        $placeIds = isset($post['place_id']) && is_array($post['place_id']) ? $post['place_id'] : [];
        $labels = isset($post['location_label']) && is_array($post['location_label']) ? $post['location_label'] : [];
        $mapUrls = isset($post['map_embed_url']) && is_array($post['map_embed_url']) ? $post['map_embed_url'] : [];
        $serviceAreas = isset($post['service_areas']) && is_array($post['service_areas']) ? $post['service_areas'] : [];

        $max = max(count($domains), count($placeIds), count($labels), count($mapUrls), count($serviceAreas));
        $profiles = [];
        for ($i = 0; $i < $max; $i++) {
            $domain = $this->sanitizeDomain((string) ($domains[$i] ?? ''));
            $placeId = sanitize_text_field((string) ($placeIds[$i] ?? ''));
            $label = sanitize_text_field((string) ($labels[$i] ?? ''));
            $mapUrl = esc_url_raw((string) ($mapUrls[$i] ?? ''));
            $serviceAreaRaw = sanitize_textarea_field((string) ($serviceAreas[$i] ?? ''));
            $serviceArea = array_values(
                array_filter(
                    array_map(
                        static fn (string $item): string => sanitize_text_field(trim($item)),
                        preg_split('/[\r\n,]+/', $serviceAreaRaw) ?: []
                    ),
                    static fn (string $item): bool => $item !== ''
                )
            );

            if ($domain === '' || $placeId === '') {
                continue;
            }

            $profiles[] = [
                'domain' => $domain,
                'place_id' => $placeId,
                'location_label' => $label !== '' ? $label : ucfirst(str_replace(['-', '.'], ' ', $domain)),
                'map_embed_url' => $mapUrl,
                'service_areas' => $serviceArea,
            ];
        }

        update_option(self::OPTION_KEY, $profiles, false);

        $settings = Settings::all();
        $submittedApiKey = sanitize_text_field((string) ($post['maps_api_key'] ?? ''));
        if ($submittedApiKey !== '') {
            $settings['maps_api_key'] = $submittedApiKey;
            update_option(Settings::OPTION_KEY, $settings);
        }

        wp_safe_redirect(
            add_query_arg(
                [
                    'page' => 'h4bs-google-business',
                    'h4bs_notice' => 'saved',
                ],
                admin_url('admin.php')
            )
        );
        exit;
    }

    public function renderAdminPage(): void
    {
        if (! current_user_can('manage_options')) {
            return;
        }

        $profiles = $this->profiles();
        $settings = Settings::all();
        $mapsApiKey = sanitize_text_field((string) ($settings['maps_api_key'] ?? ''));
        $rowCount = max(6, count($profiles) + 1);
        ?>
        <div class="wrap h4bs-admin-wrap">
            <h1><?php esc_html_e('Google Business Profiles (Domain Based)', 'help4-builder-suite'); ?></h1>
            <p><?php esc_html_e('Map each website domain to one or more Google Place IDs. This setup supports shared hosting and does not rely on IP addresses.', 'help4-builder-suite'); ?></p>
            <p><?php esc_html_e('Locations created in Help4 Local SEO are included automatically when their optional Google Place ID is filled in. Use the domain table below only for additional domains or legacy mappings.', 'help4-builder-suite'); ?></p>
            <p><strong><?php esc_html_e('Use domains only (example.com), never server IPs.', 'help4-builder-suite'); ?></strong></p>
            <?php if (AdminRequest::queryKey('h4bs_notice') === 'saved') : ?>
                <div class="notice notice-success is-dismissible"><p><?php esc_html_e('Google Business profiles saved.', 'help4-builder-suite'); ?></p></div>
            <?php endif; ?>
            <form method="post">
                <?php wp_nonce_field('h4bs_google_business_save', 'h4bs_google_business_nonce'); ?>
                <input type="hidden" name="h4bs_google_business_action" value="save_profiles">
                <table class="form-table" role="presentation">
                    <tbody>
                        <tr>
                            <th scope="row"><label for="h4bs_maps_api_key"><?php esc_html_e('Google Maps / Places API Key', 'help4-builder-suite'); ?></label></th>
                            <td>
                                <input id="h4bs_maps_api_key" class="regular-text code" type="text" name="maps_api_key" value="<?php echo esc_attr($mapsApiKey); ?>">
                                <p class="description"><?php esc_html_e('Used for pulling rating + reviews from Places API by Place ID.', 'help4-builder-suite'); ?></p>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <h2><?php esc_html_e('Domain to Business Location Mapping', 'help4-builder-suite'); ?></h2>
                <div class="h4bs-admin-table-scroll" tabindex="0" role="region" aria-label="<?php esc_attr_e('Google Business profile mappings', 'help4-builder-suite'); ?>">
                <table class="widefat striped h4bs-google-business-table">
                    <thead>
                        <tr>
                            <th><?php esc_html_e('Domain', 'help4-builder-suite'); ?></th>
                            <th><?php esc_html_e('Google Place ID', 'help4-builder-suite'); ?></th>
                            <th><?php esc_html_e('Location Label', 'help4-builder-suite'); ?></th>
                            <th><?php esc_html_e('Map Embed URL (optional)', 'help4-builder-suite'); ?></th>
                            <th><?php esc_html_e('Service Areas (comma or new line)', 'help4-builder-suite'); ?></th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php for ($i = 0; $i < $rowCount; $i++) : ?>
                            <?php $profile = $profiles[$i] ?? []; ?>
                            <tr>
                                <td><input class="regular-text code" type="text" name="domain[]" value="<?php echo esc_attr((string) ($profile['domain'] ?? '')); ?>" placeholder="example.com"></td>
                                <td><input class="regular-text code" type="text" name="place_id[]" value="<?php echo esc_attr((string) ($profile['place_id'] ?? '')); ?>" placeholder="ChIJ..."></td>
                                <td><input class="regular-text" type="text" name="location_label[]" value="<?php echo esc_attr((string) ($profile['location_label'] ?? '')); ?>" placeholder="Main Office"></td>
                                <td><input class="widefat code" type="text" name="map_embed_url[]" value="<?php echo esc_attr((string) ($profile['map_embed_url'] ?? '')); ?>" placeholder="https://www.google.com/maps/embed?..."></td>
                                <td><textarea class="widefat" name="service_areas[]" rows="2" placeholder="City A, City B"><?php echo esc_textarea(implode(', ', is_array($profile['service_areas'] ?? null) ? $profile['service_areas'] : [])); ?></textarea></td>
                            </tr>
                        <?php endfor; ?>
                    </tbody>
                </table>
                </div>
                <p class="submit">
                    <button type="submit" class="button button-primary"><?php esc_html_e('Save Google Business Profiles', 'help4-builder-suite'); ?></button>
                </p>
            </form>
            <h2><?php esc_html_e('Shortcodes', 'help4-builder-suite'); ?></h2>
            <ul>
                <li><code>[h4_google_business domain="example.com" reviews="3"]</code></li>
                <li><code>[h4_google_reviews domain="example.com" limit="5"]</code></li>
                <li><code>[h4_google_map domain="example.com" location="1"]</code></li>
            </ul>
        </div>
        <?php
    }

    public function registerRestRoutes(): void
    {
        register_rest_route(
            'h4bs/v1',
            '/google-business',
            [
                'methods' => 'GET',
                'callback' => [$this, 'getBusinessDataRest'],
                'permission_callback' => '__return_true',
            ]
        );
    }

    public function getBusinessDataRest(WP_REST_Request $request): WP_REST_Response
    {
        $domain = $this->resolveDomain((string) $request->get_param('domain'));
        $limit = max(1, min(10, (int) $request->get_param('limit')));
        $payload = $this->buildDomainPayload($domain, $limit);
        return new WP_REST_Response($payload, 200);
    }

    /**
     * @param array<string, string> $atts
     */
    public function renderBusinessShortcode(array $atts): string
    {
        $atts = shortcode_atts(
            [
                'domain' => '',
                'reviews' => '3',
                'location' => '1',
                'show_header' => '1',
                'show_aggregate' => '1',
                'show_map' => '1',
                'show_reviews' => '1',
                'map_height' => '360',
                'show_service_areas' => '1',
                'empty_text' => '',
            ],
            $atts,
            'h4_google_business'
        );
        $domain = $this->resolveDomain((string) ($atts['domain'] ?? ''));
        $reviewLimit = max(1, min(10, (int) ($atts['reviews'] ?? 3)));
        $showHeader = rest_sanitize_boolean($atts['show_header'] ?? '1');
        $showAggregate = rest_sanitize_boolean($atts['show_aggregate'] ?? '1');
        $showMap = rest_sanitize_boolean($atts['show_map'] ?? '1');
        $showReviews = rest_sanitize_boolean($atts['show_reviews'] ?? '1');
        $mapHeight = max(220, min(900, (int) ($atts['map_height'] ?? 360)));
        $showServiceAreas = rest_sanitize_boolean($atts['show_service_areas'] ?? '1');
        $emptyText = sanitize_text_field((string) ($atts['empty_text'] ?? ''));
        if ($emptyText === '') {
            $emptyText = __('Google Business profile not configured for this domain yet.', 'help4-builder-suite');
        }
        $payload = $this->buildDomainPayload($domain, $reviewLimit);
        if (empty($payload['locations'])) {
            return '<div class="h4-gmb-empty">' . esc_html($emptyText) . '</div>';
        }
        if (! $showMap && ! $showReviews) {
            return '<div class="h4-gmb-empty">' . esc_html__('Enable map and/or reviews to show this widget.', 'help4-builder-suite') . '</div>';
        }

        ob_start();
        ?>
        <section class="h4-gmb-block">
            <?php if ($showHeader) : ?>
                <header style="margin-bottom:1rem;">
                    <h3 style="margin:0;"><?php echo esc_html((string) ($payload['domain'] ?? $domain)); ?></h3>
                    <?php if ($showAggregate && isset($payload['aggregate']['rating'])) : ?>
                        <p style="margin:.35rem 0 0;">
                            <strong><?php echo esc_html(number_format_i18n((float) ($payload['aggregate']['rating'] ?? 0), 1)); ?>/5</strong>
                            (<?php echo esc_html((string) ($payload['aggregate']['total_reviews'] ?? 0)); ?> <?php esc_html_e('reviews', 'help4-builder-suite'); ?>)
                        </p>
                    <?php endif; ?>
                </header>
            <?php endif; ?>
            <?php if ($showMap) : ?>
                <?php
                $mapHtml = $this->renderMapShortcode(
                    [
                        'domain' => $domain,
                        'location' => (string) ($atts['location'] ?? '1'),
                        'height' => (string) $mapHeight,
                        'show_service_areas' => $showServiceAreas ? '1' : '0',
                        'empty_text' => $emptyText,
                    ]
                );
                // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- renderMapShortcode returns sanitized shortcode markup.
                echo $mapHtml;
                ?>
            <?php endif; ?>
            <?php if ($showReviews) : ?>
                <?php
                $reviewsHtml = $this->renderReviewsShortcode(
                    [
                        'domain' => $domain,
                        'limit' => (string) $reviewLimit,
                        'empty_text' => $emptyText,
                    ]
                );
                // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- renderReviewsShortcode returns sanitized shortcode markup.
                echo $reviewsHtml;
                ?>
            <?php endif; ?>
        </section>
        <?php
        return (string) ob_get_clean();
    }

    /**
     * @param array<string, string> $atts
     */
    public function renderReviewsShortcode(array $atts): string
    {
        $atts = shortcode_atts(
            [
                'domain' => '',
                'limit' => '5',
                'empty_text' => '',
            ],
            $atts,
            'h4_google_reviews'
        );
        $domain = $this->resolveDomain((string) ($atts['domain'] ?? ''));
        $limit = max(1, min(10, (int) ($atts['limit'] ?? 5)));
        $emptyText = sanitize_text_field((string) ($atts['empty_text'] ?? ''));
        if ($emptyText === '') {
            $emptyText = __('No Google reviews available for this domain yet.', 'help4-builder-suite');
        }
        $payload = $this->buildDomainPayload($domain, $limit);
        if (empty($payload['reviews'])) {
            return '<div class="h4-gmb-empty">' . esc_html($emptyText) . '</div>';
        }

        ob_start();
        ?>
        <div class="h4-gmb-reviews" style="display:grid;gap:1rem;">
            <?php foreach ((array) $payload['reviews'] as $review) : ?>
                <?php
                $author = sanitize_text_field((string) ($review['author'] ?? ''));
                $text = sanitize_textarea_field((string) ($review['text'] ?? ''));
                $rating = max(1, min(5, (int) ($review['rating'] ?? 5)));
                $relativeTime = sanitize_text_field((string) ($review['relative_time'] ?? ''));
                ?>
                <article style="border:1px solid #dbe7e6;border-radius:12px;padding:1rem;">
                    <header style="display:flex;justify-content:space-between;gap:.5rem;align-items:center;">
                        <strong><?php echo esc_html($author !== '' ? $author : __('Google User', 'help4-builder-suite')); ?></strong>
                        <span><?php echo esc_html(str_repeat('★', $rating)); ?></span>
                    </header>
                    <p style="margin:.6rem 0;"><?php echo esc_html($text); ?></p>
                    <?php if ($relativeTime !== '') : ?>
                        <small style="opacity:.75;"><?php echo esc_html($relativeTime); ?></small>
                    <?php endif; ?>
                </article>
            <?php endforeach; ?>
        </div>
        <?php
        return (string) ob_get_clean();
    }

    /**
     * @param array<string, string> $atts
     */
    public function renderMapShortcode(array $atts): string
    {
        $atts = shortcode_atts(
            [
                'domain' => '',
                'location' => '1',
                'height' => '360',
                'show_service_areas' => '1',
                'empty_text' => '',
            ],
            $atts,
            'h4_google_map'
        );
        $domain = $this->resolveDomain((string) ($atts['domain'] ?? ''));
        $showServiceAreas = rest_sanitize_boolean($atts['show_service_areas'] ?? '1');
        $emptyText = sanitize_text_field((string) ($atts['empty_text'] ?? ''));
        if ($emptyText === '') {
            $emptyText = __('No map location configured for this domain.', 'help4-builder-suite');
        }
        $payload = $this->buildDomainPayload($domain, 1);
        $locations = is_array($payload['locations'] ?? null) ? $payload['locations'] : [];
        if (! $locations) {
            return '<div class="h4-gmb-empty">' . esc_html($emptyText) . '</div>';
        }

        $index = max(1, (int) ($atts['location'] ?? 1)) - 1;
        if (! isset($locations[$index])) {
            $index = 0;
        }
        $location = is_array($locations[$index] ?? null) ? $locations[$index] : [];
        $mapUrl = (string) ($location['map_embed_url'] ?? '');
        if ($mapUrl === '') {
            $mapUrl = (string) ($location['map_fallback_url'] ?? '');
        }
        if ($mapUrl === '') {
            return '<div class="h4-gmb-empty">' . esc_html($emptyText) . '</div>';
        }

        $height = max(220, min(900, (int) ($atts['height'] ?? 360)));
        ob_start();
        ?>
        <div class="h4-gmb-map">
            <iframe title="<?php esc_attr_e('Google Business Map', 'help4-builder-suite'); ?>" src="<?php echo esc_url($mapUrl); ?>" loading="lazy" referrerpolicy="no-referrer-when-downgrade" style="width:100%;height:<?php echo esc_attr((string) $height); ?>px;border:0;border-radius:12px;"></iframe>
            <?php $serviceAreas = is_array($location['service_areas'] ?? null) ? $location['service_areas'] : []; ?>
            <?php if ($showServiceAreas && $serviceAreas) : ?>
                <p style="margin:.65rem 0 0;"><strong><?php esc_html_e('Service Areas:', 'help4-builder-suite'); ?></strong> <?php echo esc_html(implode(', ', array_map('strval', $serviceAreas))); ?></p>
            <?php endif; ?>
        </div>
        <?php
        return (string) ob_get_clean();
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    private function profiles(): array
    {
        $profiles = get_option(self::OPTION_KEY, []);
        if (! is_array($profiles)) {
            $profiles = [];
        }
        $clean = [];
        foreach ($profiles as $profile) {
            if (! is_array($profile)) {
                continue;
            }
            $domain = $this->sanitizeDomain((string) ($profile['domain'] ?? ''));
            $placeId = sanitize_text_field((string) ($profile['place_id'] ?? ''));
            if ($domain === '' || $placeId === '') {
                continue;
            }
            $clean[] = [
                'domain' => $domain,
                'place_id' => $placeId,
                'location_label' => sanitize_text_field((string) ($profile['location_label'] ?? '')),
                'map_embed_url' => esc_url_raw((string) ($profile['map_embed_url'] ?? '')),
                'service_areas' => array_values(
                    array_filter(
                        array_map('sanitize_text_field', is_array($profile['service_areas'] ?? null) ? $profile['service_areas'] : []),
                        static fn (string $value): bool => $value !== ''
                    )
                ),
            ];
        }

        $homeHost = wp_parse_url(home_url('/'), PHP_URL_HOST);
        $homeDomain = $this->sanitizeDomain(is_string($homeHost) ? $homeHost : '');
        if ($homeDomain !== '' && post_type_exists('h4_location')) {
            $locations = get_posts([
                'post_type' => 'h4_location',
                'post_status' => 'publish',
                'posts_per_page' => 500,
                'orderby' => 'title',
                'order' => 'ASC',
                'no_found_rows' => true,
            ]);
            foreach ($locations as $location) {
                if (! $location instanceof \WP_Post) {
                    continue;
                }
                $data = get_post_meta($location->ID, '_h4_local_data', true);
                $data = is_array($data) ? $data : [];
                $placeId = sanitize_text_field((string) ($data['place_id'] ?? ''));
                if ($placeId === '') {
                    continue;
                }
                $clean[] = [
                    'domain' => $homeDomain,
                    'place_id' => $placeId,
                    'location_label' => get_the_title($location),
                    'map_embed_url' => esc_url_raw((string) ($data['map_embed_url'] ?? '')),
                    'service_areas' => array_values(
                        array_filter(
                            array_map('sanitize_text_field', is_array($data['service_areas'] ?? null) ? $data['service_areas'] : []),
                            static fn (string $value): bool => $value !== ''
                        )
                    ),
                ];
            }
        }

        $deduplicated = [];
        foreach ($clean as $profile) {
            $key = (string) $profile['domain'] . '|' . (string) $profile['place_id'];
            $deduplicated[$key] = $profile;
        }
        return array_values($deduplicated);
    }

    /**
     * @return array<string, mixed>
     */
    private function buildDomainPayload(string $domain, int $reviewLimit): array
    {
        $domain = $this->resolveDomain($domain);
        $profiles = array_values(
            array_filter(
                $this->profiles(),
                static fn (array $profile): bool => (string) ($profile['domain'] ?? '') === $domain
            )
        );

        if (! $profiles) {
            return [
                'domain' => $domain,
                'locations' => [],
                'reviews' => [],
                'aggregate' => [
                    'rating' => 0,
                    'total_reviews' => 0,
                ],
            ];
        }

        $settings = Settings::all();
        $apiKey = sanitize_text_field((string) ($settings['maps_api_key'] ?? ''));
        $locations = [];
        $reviews = [];
        $ratingTotal = 0.0;
        $ratingCount = 0;
        $totalReviews = 0;

        foreach ($profiles as $profile) {
            $details = $this->fetchGooglePlaceDetails((string) ($profile['place_id'] ?? ''), $apiKey);
            $rating = (float) ($details['rating'] ?? 0);
            $ratingsTotal = (int) ($details['user_ratings_total'] ?? 0);
            if ($rating > 0) {
                $ratingTotal += $rating;
                $ratingCount++;
            }
            $totalReviews += max(0, $ratingsTotal);

            $location = $profile;
            $location['google_rating'] = $rating;
            $location['google_user_ratings_total'] = $ratingsTotal;
            $location['formatted_address'] = sanitize_text_field((string) ($details['formatted_address'] ?? ''));
            $location['place_name'] = sanitize_text_field((string) ($details['name'] ?? ''));
            $location['place_url'] = esc_url_raw((string) ($details['url'] ?? ''));
            if ((string) ($location['map_embed_url'] ?? '') === '') {
                $location['map_embed_url'] = $this->buildFallbackMapUrl($details);
            }
            $location['map_fallback_url'] = $this->buildFallbackMapUrl($details);
            $locations[] = $location;

            $placeReviews = is_array($details['reviews'] ?? null) ? $details['reviews'] : [];
            foreach ($placeReviews as $review) {
                if (! is_array($review)) {
                    continue;
                }
                $reviews[] = [
                    'author' => sanitize_text_field((string) ($review['author_name'] ?? '')),
                    'rating' => max(1, min(5, (int) ($review['rating'] ?? 5))),
                    'text' => sanitize_textarea_field((string) ($review['text'] ?? '')),
                    'relative_time' => sanitize_text_field((string) ($review['relative_time_description'] ?? '')),
                    'profile_photo_url' => esc_url_raw((string) ($review['profile_photo_url'] ?? '')),
                ];
            }
        }

        $reviews = array_slice($reviews, 0, $reviewLimit);
        $aggregateRating = $ratingCount > 0 ? $ratingTotal / $ratingCount : 0.0;

        return [
            'domain' => $domain,
            'locations' => $locations,
            'reviews' => $reviews,
            'aggregate' => [
                'rating' => $aggregateRating,
                'total_reviews' => $totalReviews,
            ],
        ];
    }

    /**
     * @return array<string, mixed>
     */
    private function fetchGooglePlaceDetails(string $placeId, string $apiKey): array
    {
        $placeId = sanitize_text_field($placeId);
        if ($placeId === '' || $apiKey === '') {
            return [];
        }

        $cacheKey = 'h4bs_gmb_' . md5($placeId . '|' . $apiKey);
        $cached = get_transient($cacheKey);
        if (is_array($cached)) {
            return $cached;
        }

        $url = add_query_arg(
            [
                'place_id' => $placeId,
                'fields' => 'name,rating,user_ratings_total,reviews,url,formatted_address,geometry',
                'reviews_sort' => 'newest',
                'key' => $apiKey,
            ],
            'https://maps.googleapis.com/maps/api/place/details/json'
        );

        $response = wp_remote_get(
            $url,
            [
                'timeout' => 15,
                'redirection' => 3,
                'user-agent' => 'Help4BuilderSuite/' . (defined('H4BS_VERSION') ? H4BS_VERSION : 'dev'),
            ]
        );
        if (is_wp_error($response)) {
            return [];
        }

        $statusCode = (int) wp_remote_retrieve_response_code($response);
        if ($statusCode < 200 || $statusCode >= 300) {
            return [];
        }

        $decoded = json_decode((string) wp_remote_retrieve_body($response), true);
        if (! is_array($decoded) || ! is_array($decoded['result'] ?? null)) {
            return [];
        }

        $result = $decoded['result'];
        set_transient($cacheKey, $result, 10 * MINUTE_IN_SECONDS);
        return $result;
    }

    /**
     * @param array<string, mixed> $details
     */
    private function buildFallbackMapUrl(array $details): string
    {
        $lat = (float) ($details['geometry']['location']['lat'] ?? 0);
        $lng = (float) ($details['geometry']['location']['lng'] ?? 0);
        if ($lat !== 0.0 && $lng !== 0.0) {
            return 'https://www.google.com/maps?q=' . rawurlencode((string) $lat . ',' . (string) $lng) . '&z=14&output=embed';
        }

        $address = sanitize_text_field((string) ($details['formatted_address'] ?? ''));
        if ($address !== '') {
            return 'https://www.google.com/maps?q=' . rawurlencode($address) . '&output=embed';
        }
        return '';
    }

    private function resolveDomain(string $domain): string
    {
        $domain = $this->sanitizeDomain($domain);
        if ($domain !== '') {
            return $domain;
        }

        $homeHost = wp_parse_url(home_url('/'), PHP_URL_HOST);
        return $this->sanitizeDomain(is_string($homeHost) ? $homeHost : '');
    }

    private function sanitizeDomain(string $domain): string
    {
        $domain = trim(strtolower($domain));
        if ($domain === '') {
            return '';
        }
        $domain = preg_replace('#^https?://#', '', $domain) ?? $domain;
        $domain = explode('/', $domain)[0] ?? $domain;
        $domain = explode(':', $domain)[0] ?? $domain;
        $domain = preg_replace('/^www\./', '', $domain) ?? $domain;
        $domain = trim($domain);
        if ($domain === '' || filter_var($domain, FILTER_VALIDATE_IP)) {
            return '';
        }
        if (! preg_match('/^[a-z0-9.-]+\.[a-z]{2,}$/i', $domain)) {
            return '';
        }
        return $domain;
    }
}
