<?php
declare(strict_types=1);

namespace Help4BuilderSuite\Support;

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

final class BusinessProfileDefaults
{
    public const PROFILE_OPTION = 'h4bs_business_profile';
    public const SEED_STATE_OPTION = 'h4bs_business_profile_seed_state';
    public const SCHEMA_VERSION = 1;

    private const FALLBACK_PROFILE = 'business';

    private static bool $applyingDefaults = false;

    public function boot(): void
    {
        add_action('admin_init', [$this, 'seedMissingSettings'], 5);
        add_action('update_option_' . Settings::OPTION_KEY, [$this, 'captureExternalSettingsUpdate'], 10, 3);
    }

    /**
     * @return array<string, mixed>
     */
    public function seedMissingSettings(): array
    {
        return self::applyRecommendedSettings(self::selectedSlug(), false);
    }

    /**
     * @param mixed $oldValue
     * @param mixed $newValue
     */
    public function captureExternalSettingsUpdate($oldValue, $newValue, string $optionName): void
    {
        if (self::$applyingDefaults || $optionName !== Settings::OPTION_KEY) {
            return;
        }

        $oldValue = is_array($oldValue) ? $oldValue : [];
        $newValue = is_array($newValue) ? $newValue : [];
        $changedKeys = [];
        foreach (array_unique(array_merge(array_keys($oldValue), array_keys($newValue))) as $key) {
            $key = sanitize_key((string) $key);
            if ($key === '') {
                continue;
            }
            if (! array_key_exists($key, $oldValue) || ! array_key_exists($key, $newValue) || $oldValue[$key] !== $newValue[$key]) {
                $changedKeys[] = $key;
            }
        }

        self::markUserOwnedSettings($changedKeys);
    }

    /**
     * @return array<string, array<string, mixed>>
     */
    public static function catalog(): array
    {
        $baseWizard = self::baseWizardAnswers();
        $profiles = [
            'business' => [
                'label' => __('General business', 'help4-builder-suite'),
                'description' => __('A balanced lead-generation, SEO, security, performance, forms, and page-building setup.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-foundation',
                'wizard' => $baseWizard,
                'settings' => [],
            ],
            'agency' => [
                'label' => __('Agency or professional service', 'help4-builder-suite'),
                'description' => __('Reusable templates, proposals, intake forms, proof sections, reporting, and client-focused conversion tools.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-enterprise-dark',
                'wizard' => $baseWizard,
                'settings' => [],
            ],
            'local_service' => [
                'label' => __('Local service business', 'help4-builder-suite'),
                'description' => __('Local discovery, service-area content, quote and callback forms, reviews, maps, and fast mobile contact journeys.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-foundation',
                'wizard' => $baseWizard,
                'settings' => ['seo_default_intent_profile' => 'local'],
            ],
            'contractor' => [
                'label' => __('Contractor or skilled trade', 'help4-builder-suite'),
                'description' => __('Quote-first service pages, project proof, structured fields, local search, and field-service conversion defaults.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-contractor-pro',
                'wizard' => array_replace($baseWizard, ['needs_contractor' => true]),
                'settings' => ['seo_default_intent_profile' => 'local'],
            ],
            'healthcare' => [
                'label' => __('Healthcare or wellness practice', 'help4-builder-suite'),
                'description' => __('Service, practitioner, location, intake, accessibility, privacy, and educational-content recommendations.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-foundation',
                'wizard' => $baseWizard,
                'settings' => ['seo_default_intent_profile' => 'local'],
            ],
            'realtor' => [
                'label' => __('Real estate or property', 'help4-builder-suite'),
                'description' => __('Listing search, maps, property fields, lead capture, social images, real-estate schema, and IndexNow-ready tools.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-realtor-luxe',
                'wizard' => array_replace($baseWizard, ['needs_realtor' => true]),
                'settings' => [
                    'seo_default_intent_profile' => 'local',
                    'commerce_product_card_style' => 'showcase',
                    'commerce_product_columns_desktop' => '3',
                ],
            ],
            'store' => [
                'label' => __('Store or product catalog', 'help4-builder-suite'),
                'description' => __('Products, variations, customer fields, inventory, promotions, tax, shipping, checkout, and payment routing.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-commerce-neo',
                'wizard' => array_replace($baseWizard, [
                    'needs_commerce' => true,
                    'needs_standalone_payments' => true,
                    'needs_invoice_tracking' => true,
                ]),
                'settings' => [
                    'seo_default_intent_profile' => 'ecommerce',
                    'commerce_seo_feed_enabled' => '1',
                    'commerce_product_card_style' => 'overlay',
                    'commerce_product_hover' => 'quick_actions',
                    'commerce_product_columns_desktop' => '4',
                    'commerce_product_columns_tablet' => '2',
                    'commerce_product_columns_mobile' => '1',
                    'commerce_filter_style' => 'toolbar',
                    'security_require_ssl_for_commerce' => '1',
                ],
            ],
            'restaurant' => [
                'label' => __('Restaurant or hospitality', 'help4-builder-suite'),
                'description' => __('Menu or offering pages, locations, opening hours, reservations, events, local search, and optional payments.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-foundation',
                'wizard' => array_replace($baseWizard, ['needs_standalone_payments' => true]),
                'settings' => [
                    'seo_default_intent_profile' => 'local',
                    'commerce_product_card_style' => 'clean',
                    'commerce_product_columns_desktop' => '3',
                    'commerce_show_compare_action' => '0',
                ],
            ],
            'education' => [
                'label' => __('Education, courses, or training', 'help4-builder-suite'),
                'description' => __('Courses, protected video and documents, progress, certificates, student forms, and reusable learning layouts.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-foundation',
                'wizard' => array_replace($baseWizard, ['needs_lms' => true]),
                'settings' => [],
            ],
            'membership' => [
                'label' => __('Membership or community', 'help4-builder-suite'),
                'description' => __('Recurring access, member dashboards, protected resources, subscriptions, customer fields, and lifecycle forms.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-foundation',
                'wizard' => array_replace($baseWizard, [
                    'needs_commerce' => true,
                    'needs_standalone_payments' => true,
                    'needs_subscriptions' => true,
                    'needs_lms' => true,
                ]),
                'settings' => [
                    'seo_default_intent_profile' => 'ecommerce',
                    'commerce_product_card_style' => 'clean',
                    'commerce_product_columns_desktop' => '3',
                    'security_require_ssl_for_commerce' => '1',
                ],
            ],
            'content' => [
                'label' => __('Publisher, blog, or knowledge hub', 'help4-builder-suite'),
                'description' => __('Search-first editorial templates, readability guidance, connected schema, media optimization, and content discovery.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-speed-lite',
                'wizard' => $baseWizard,
                'settings' => ['seo_default_intent_profile' => 'publisher'],
            ],
            'nonprofit' => [
                'label' => __('Nonprofit or community organization', 'help4-builder-suite'),
                'description' => __('Mission storytelling, events, volunteers, newsletters, donation collection, accessibility, and local visibility.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-foundation',
                'wizard' => array_replace($baseWizard, ['needs_standalone_payments' => true]),
                'settings' => [],
            ],
            'portfolio' => [
                'label' => __('Portfolio or creative studio', 'help4-builder-suite'),
                'description' => __('Media-forward project templates, galleries, lead forms, case studies, social presentation, and lightweight delivery.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-speed-lite',
                'wizard' => $baseWizard,
                'settings' => ['image_opt_enhance_uploaded' => '1'],
            ],
            'saas' => [
                'label' => __('Software or subscription service', 'help4-builder-suite'),
                'description' => __('Feature, pricing, documentation, onboarding, account, subscription, support, and conversion-focused templates.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-enterprise-dark',
                'wizard' => array_replace($baseWizard, [
                    'needs_standalone_payments' => true,
                    'needs_subscriptions' => true,
                ]),
                'settings' => ['security_require_ssl_for_commerce' => '1'],
            ],
        ];

        $profiles = apply_filters('h4bs_business_profile_catalog', $profiles);
        if (! is_array($profiles)) {
            return [];
        }

        $clean = [];
        foreach ($profiles as $profileSlug => $profile) {
            if (! is_array($profile)) {
                continue;
            }
            $slug = sanitize_key((string) ($profile['slug'] ?? $profileSlug));
            if ($slug === '') {
                continue;
            }
            $wizard = array_replace($baseWizard, is_array($profile['wizard'] ?? null) ? $profile['wizard'] : []);
            foreach (array_keys($baseWizard) as $key) {
                $wizard[$key] = ! empty($wizard[$key]);
            }
            $settings = [];
            foreach ((array) ($profile['settings'] ?? []) as $key => $value) {
                $key = sanitize_key((string) $key);
                if ($key !== '') {
                    $settings[$key] = $value;
                }
            }
            $clean[$slug] = [
                'slug' => $slug,
                'label' => sanitize_text_field((string) ($profile['label'] ?? ucfirst(str_replace('_', ' ', $slug)))),
                'description' => sanitize_text_field((string) ($profile['description'] ?? '')),
                'theme_pack_slug' => sanitize_key((string) ($profile['theme_pack_slug'] ?? 'help4-foundation')),
                'wizard' => $wizard,
                'settings' => $settings,
            ];
        }

        return $clean;
    }

    public static function selectedSlug(): string
    {
        $catalog = self::catalog();
        $saved = sanitize_key((string) get_option(self::PROFILE_OPTION, ''));
        if ($saved !== '' && isset($catalog[$saved])) {
            return $saved;
        }

        $wizard = get_option('h4bs_setup_wizard_answers', []);
        $wizard = is_array($wizard) ? $wizard : [];
        $legacy = sanitize_key((string) ($wizard['business_type'] ?? ''));
        if ($legacy !== '' && isset($catalog[$legacy])) {
            return $legacy;
        }

        return isset($catalog[self::FALLBACK_PROFILE]) ? self::FALLBACK_PROFILE : (string) array_key_first($catalog);
    }

    /**
     * @return array<string, mixed>|null
     */
    public static function profile(string $slug): ?array
    {
        $slug = sanitize_key($slug);
        $catalog = self::catalog();
        return isset($catalog[$slug]) ? $catalog[$slug] : null;
    }

    /**
     * @return array<string, bool>
     */
    public static function wizardDefaults(string $slug): array
    {
        $profile = self::profile($slug) ?? self::profile(self::FALLBACK_PROFILE);
        return array_replace(self::baseWizardAnswers(), is_array($profile['wizard'] ?? null) ? $profile['wizard'] : []);
    }

    public static function themePackSlug(string $slug): string
    {
        $profile = self::profile($slug) ?? self::profile(self::FALLBACK_PROFILE);
        return sanitize_key((string) ($profile['theme_pack_slug'] ?? 'help4-foundation'));
    }

    /**
     * @param array<string, mixed> $baseDefaults
     * @return array<string, mixed>
     */
    public static function settingsDefaults(array $baseDefaults, ?string $slug = null): array
    {
        $slug = $slug === null ? self::selectedSlug() : sanitize_key($slug);
        $profile = self::profile($slug) ?? self::profile(self::FALLBACK_PROFILE);
        $patch = is_array($profile['settings'] ?? null) ? $profile['settings'] : [];
        $patch = array_intersect_key($patch, $baseDefaults);
        $recommended = array_replace($baseDefaults, $patch);
        $filtered = apply_filters('h4bs_business_profile_defaults', $recommended, $slug, $profile, $baseDefaults);

        return is_array($filtered)
            ? array_replace($recommended, array_intersect_key($filtered, $baseDefaults))
            : $recommended;
    }

    /**
     * @return array<string, mixed>
     */
    public static function selectProfile(string $slug, bool $refreshManaged = true): array
    {
        $slug = self::rememberProfile($slug);

        return self::applyRecommendedSettings($slug, $refreshManaged);
    }

    public static function rememberProfile(string $slug): string
    {
        $slug = sanitize_key($slug);
        if (! self::profile($slug)) {
            $slug = self::FALLBACK_PROFILE;
        }
        update_option(self::PROFILE_OPTION, $slug, false);

        $state = self::seedState();
        $state['profile_slug'] = $slug;
        $state['profile_selected_at'] = gmdate('c');
        update_option(self::SEED_STATE_OPTION, $state, false);

        return $slug;
    }

    /**
     * @return array<string, mixed>
     */
    public static function applyRecommendedSettings(string $slug, bool $refreshManaged): array
    {
        $slug = sanitize_key($slug);
        if (! self::profile($slug)) {
            $slug = self::FALLBACK_PROFILE;
        }

        $sentinel = '__h4bs_missing_' . wp_generate_uuid4();
        $rawSettings = get_option(Settings::OPTION_KEY, $sentinel);
        $rawSettings = is_array($rawSettings) ? $rawSettings : [];
        $recommended = self::settingsDefaults(Settings::defaults(), $slug);
        $recommended = array_diff_key($recommended, Settings::lockedEndpointDefaults());
        $state = self::seedState();
        $managed = is_array($state['managed'] ?? null) ? $state['managed'] : [];
        $seeded = [];
        $refreshed = [];
        $preserved = [];
        $changed = false;

        foreach ($recommended as $key => $value) {
            $key = sanitize_key((string) $key);
            if ($key === '') {
                continue;
            }
            if (! array_key_exists($key, $rawSettings)) {
                $rawSettings[$key] = $value;
                $managed[$key] = self::valueHash($value);
                $seeded[] = $key;
                $changed = true;
                continue;
            }

            if ($refreshManaged && isset($managed[$key])) {
                if (hash_equals((string) $managed[$key], self::valueHash($rawSettings[$key]))) {
                    if ($rawSettings[$key] !== $value) {
                        $rawSettings[$key] = $value;
                        $refreshed[] = $key;
                        $changed = true;
                    }
                    $managed[$key] = self::valueHash($value);
                    continue;
                }
                unset($managed[$key]);
            }
            $preserved[] = $key;
        }

        if ($changed || $rawSettings === []) {
            self::$applyingDefaults = true;
            update_option(Settings::OPTION_KEY, $rawSettings, false);
            self::$applyingDefaults = false;
        }

        $newState = [
            'schema' => 'h4bs/business-profile-seed-state',
            'schema_version' => self::SCHEMA_VERSION,
            'profile_slug' => $slug,
            'catalog_hash' => self::valueHash($recommended),
            'managed' => $managed,
            'user_owned_keys' => array_values(array_diff(array_keys($rawSettings), array_keys($managed))),
        ];
        foreach (['profile_selected_at', 'last_seeded_at', 'last_user_change_at'] as $stateKey) {
            if (isset($state[$stateKey])) {
                $newState[$stateKey] = $state[$stateKey];
            }
        }
        if ($changed) {
            $newState['last_seeded_at'] = gmdate('c');
        }
        if (maybe_serialize($newState) !== maybe_serialize($state)) {
            update_option(self::SEED_STATE_OPTION, $newState, false);
        }

        return [
            'profile_slug' => $slug,
            'seeded' => $seeded,
            'refreshed' => $refreshed,
            'preserved' => $preserved,
            'changed' => $changed,
        ];
    }

    /**
     * @param array<int|string, mixed> $keys
     */
    public static function markUserOwnedSettings(array $keys): void
    {
        $state = self::seedState();
        $managed = is_array($state['managed'] ?? null) ? $state['managed'] : [];
        $changed = false;
        foreach ($keys as $key) {
            $key = sanitize_key((string) $key);
            if ($key !== '' && isset($managed[$key])) {
                unset($managed[$key]);
                $changed = true;
            }
        }
        if (! $changed) {
            return;
        }
        $state['managed'] = $managed;
        $rawSettings = get_option(Settings::OPTION_KEY, []);
        $rawSettings = is_array($rawSettings) ? $rawSettings : [];
        $state['user_owned_keys'] = array_values(array_diff(array_keys($rawSettings), array_keys($managed)));
        $state['last_user_change_at'] = gmdate('c');
        update_option(self::SEED_STATE_OPTION, $state, false);
    }

    /**
     * @return array<string, bool>
     */
    private static function baseWizardAnswers(): array
    {
        return [
            'needs_commerce' => false,
            'needs_standalone_payments' => false,
            'needs_invoice_tracking' => false,
            'needs_subscriptions' => false,
            'needs_lms' => false,
            'needs_realtor' => false,
            'needs_contractor' => false,
            'needs_templates' => true,
            'needs_seo' => true,
            'needs_security' => true,
            'needs_performance' => true,
            'needs_demo_showcase' => false,
        ];
    }

    /**
     * @return array<string, mixed>
     */
    private static function seedState(): array
    {
        $state = get_option(self::SEED_STATE_OPTION, []);
        return is_array($state) ? $state : [];
    }

    private static function valueHash(mixed $value): string
    {
        $encoded = wp_json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        return hash('sha256', is_string($encoded) ? $encoded : serialize($value));
    }
}
