<?php
namespace Bookaro\Utils;

defined( 'ABSPATH' ) || exit;

final class GenericPresetProfiles
{
    public static function all(): array
    {
        return [
            'author_provider' => [
                'label' => __( 'Provider-Owned Directory', 'mybookaro' ),
                'recommended_for' => __( 'Use this when providers author and own their own listings.', 'mybookaro' ),
                'why_it_matters' => __( 'Why it matters: bookings go to the listing author, and each provider manages their own services.', 'mybookaro' ),
                'provider_mapping_detail' => __( 'Provider Mapping: Listing Author (listing post_author resolves provider ownership).', 'mybookaro' ),
                'services_source_detail' => __( 'Services Source: Provider Only (providers manage their own services).', 'mybookaro' ),
                'placement_detail' => __( 'Placement: keep UI Mode = Shortcodes, assign required pages, then place Booking Button or Services Cards where customers start bookings (Auto-Insert can stay as fallback).', 'mybookaro' ),
                'required_pages_detail' => __( 'Required pages: Booking page, plus Provider Dashboard and Customer Dashboard pages when UI Mode = Shortcodes.', 'mybookaro' ),
                'ready_definition_detail' => __( 'Ready means: provider mapping resolves on sample listings, provider services are available, required pages are assigned with dashboard embeds, Generic validation passes, and one full booking test succeeds.', 'mybookaro' ),
                'next_action' => __( 'Next action: assign Booking, Provider Dashboard, and Customer Dashboard pages, place Booking Button or Services Cards where customers start bookings, run System Status validation, then complete one full booking test.', 'mybookaro' ),
                'provider_mode' => 'author',
                'provider_mode_label' => __( 'Listing Author', 'mybookaro' ),
                'services_model' => 'provider_only',
                'services_model_label' => __( 'Provider Only', 'mybookaro' ),
            ],
            'meta_key_provider' => [
                'label' => __( 'Editorial + Meta Key Directory', 'mybookaro' ),
                'recommended_for' => __( 'Use this when editors publish listings and a provider user ID is stored in listing meta.', 'mybookaro' ),
                'why_it_matters' => __( 'Why it matters: bookings go to the provider stored in that meta field, while providers still manage their own services.', 'mybookaro' ),
                'provider_mapping_detail' => __( 'Provider Mapping: Listing Meta Key (for example provider_user_id).', 'mybookaro' ),
                'services_source_detail' => __( 'Services Source: Provider Only (providers still manage their own services after meta-key routing).', 'mybookaro' ),
                'placement_detail' => __( 'Placement: keep UI Mode = Shortcodes, assign required pages, then place Booking Button or Services Cards on the listing/page surfaces customers use.', 'mybookaro' ),
                'required_pages_detail' => __( 'Required pages: Booking page, plus Provider Dashboard and Customer Dashboard pages when UI Mode = Shortcodes.', 'mybookaro' ),
                'ready_definition_detail' => __( 'Ready means: the provider meta key is populated with valid user IDs, services source stays Provider Only, required pages are assigned with dashboard embeds, Generic validation passes, and one full booking test succeeds.', 'mybookaro' ),
                'next_action' => __( 'Next action: assign Booking, Provider Dashboard, and Customer Dashboard pages, place Booking Button or Services Cards on the listing/page customers use, run System Status validation, then complete one full booking test.', 'mybookaro' ),
                'provider_mode' => 'meta_key',
                'provider_mode_label' => __( 'Listing Meta Key', 'mybookaro' ),
                'services_model' => 'provider_only',
                'services_model_label' => __( 'Provider Only', 'mybookaro' ),
            ],
            'author_admin_catalog' => [
                'label' => __( 'Shared Catalog Directory', 'mybookaro' ),
                'recommended_for' => __( 'Use this when listing authors are the providers, but admins manage one shared service catalog.', 'mybookaro' ),
                'why_it_matters' => __( 'Why it matters: bookings still go to the listing author, but the available services come from the shared admin catalog.', 'mybookaro' ),
                'provider_mapping_detail' => __( 'Provider Mapping: Listing Author (listing post_author resolves provider ownership).', 'mybookaro' ),
                'services_source_detail' => __( 'Services Source: Admin Catalog Only (admins manage the shared catalog).', 'mybookaro' ),
                'placement_detail' => __( 'Placement: keep UI Mode = Shortcodes, assign required pages, then place Booking Button or Services Cards where customers discover the shared catalog.', 'mybookaro' ),
                'required_pages_detail' => __( 'Required pages: Booking page, plus Provider Dashboard and Customer Dashboard pages when UI Mode = Shortcodes.', 'mybookaro' ),
                'ready_definition_detail' => __( 'Ready means: listing-author provider mapping is intact, shared catalog services are published, required pages are assigned with dashboard embeds, Generic validation passes, and one full booking test succeeds.', 'mybookaro' ),
                'next_action' => __( 'Next action: assign Booking, Provider Dashboard, and Customer Dashboard pages, place Booking Button or Services Cards where customers discover the shared catalog, run System Status validation, then complete one full booking test.', 'mybookaro' ),
                'provider_mode' => 'author',
                'provider_mode_label' => __( 'Listing Author', 'mybookaro' ),
                'services_model' => 'admin_only',
                'services_model_label' => __( 'Admin Catalog Only', 'mybookaro' ),
            ],
        ];
    }

    public static function get( string $preset ): array
    {
        $preset = sanitize_key( $preset );
        $profiles = self::all();

        return $profiles[ $preset ] ?? [];
    }

    public static function get_label( string $preset ): string
    {
        $profile = self::get( $preset );

        return (string) ( $profile['label'] ?? '' );
    }

    public static function has( string $preset ): bool
    {
        return ! empty( self::get( $preset ) );
    }

    public static function evaluate_alignment(
        string $preset,
        string $provider_mode,
        string $services_model,
        string $provider_meta_key = ''
    ): array {
        $profile = self::get( $preset );
        if ( empty( $profile ) ) {
            return [
                'has_preset' => false,
                'has_conflict' => false,
                'provider_mismatch' => false,
                'services_mismatch' => false,
                'preset' => sanitize_key( $preset ),
                'preset_label' => '',
                'provider_expected' => '',
                'provider_expected_label' => '',
                'provider_actual' => self::normalize_provider_mode( $provider_mode ),
                'provider_actual_label' => self::get_provider_mode_label( $provider_mode, $provider_meta_key ),
                'services_expected' => '',
                'services_expected_label' => '',
                'services_actual' => self::normalize_services_model( $services_model ),
                'services_actual_label' => self::get_services_model_label( $services_model ),
            ];
        }

        $preset = sanitize_key( $preset );
        $provider_actual = self::normalize_provider_mode( $provider_mode );
        $services_actual = self::normalize_services_model( $services_model );

        $provider_expected = self::normalize_provider_mode( (string) ( $profile['provider_mode'] ?? 'author' ) );
        $services_expected = self::normalize_services_model( (string) ( $profile['services_model'] ?? 'provider_only' ) );

        $provider_expected_label = (string) ( $profile['provider_mode_label'] ?? self::get_provider_mode_label( $provider_expected ) );
        $services_expected_label = (string) ( $profile['services_model_label'] ?? self::get_services_model_label( $services_expected ) );

        $provider_actual_label = self::get_provider_mode_label( $provider_actual, $provider_meta_key );
        $services_actual_label = self::get_services_model_label( $services_actual );

        $provider_mismatch = ( $provider_actual !== $provider_expected );
        $services_mismatch = ( $services_actual !== $services_expected );

        return [
            'has_preset' => true,
            'has_conflict' => $provider_mismatch || $services_mismatch,
            'provider_mismatch' => $provider_mismatch,
            'services_mismatch' => $services_mismatch,
            'preset' => $preset,
            'preset_label' => (string) ( $profile['label'] ?? '' ),
            'provider_expected' => $provider_expected,
            'provider_expected_label' => $provider_expected_label,
            'provider_actual' => $provider_actual,
            'provider_actual_label' => $provider_actual_label,
            'services_expected' => $services_expected,
            'services_expected_label' => $services_expected_label,
            'services_actual' => $services_actual,
            'services_actual_label' => $services_actual_label,
        ];
    }

    public static function build_selection_detail( string $preset ): string
    {
        $profile = self::get( $preset );
        if ( empty( $profile ) ) {
            return '';
        }

        $parts = [
            sprintf(
                /* translators: %s: preset label */
                __( '%s is selected.', 'mybookaro' ),
                (string) $profile['label']
            ),
            (string) ( $profile['recommended_for'] ?? '' ),
            (string) ( $profile['why_it_matters'] ?? '' ),
            (string) ( $profile['provider_mapping_detail'] ?? '' ),
            (string) ( $profile['services_source_detail'] ?? '' ),
            (string) ( $profile['placement_detail'] ?? '' ),
            (string) ( $profile['required_pages_detail'] ?? '' ),
            (string) ( $profile['ready_definition_detail'] ?? '' ),
            (string) ( $profile['next_action'] ?? '' ),
        ];

        $parts = array_map(
            static function ( $part ): string {
                return trim( (string) $part );
            },
            $parts
        );
        $parts = array_values(
            array_filter(
                $parts,
                static function ( string $part ): bool {
                    return '' !== $part;
                }
            )
        );

        return implode( ' ', $parts );
    }

    public static function build_launch_readiness_detail( string $preset ): string
    {
        $profile = self::get( $preset );
        if ( empty( $profile ) ) {
            return '';
        }

        $parts = [
            (string) ( $profile['provider_mapping_detail'] ?? '' ),
            (string) ( $profile['services_source_detail'] ?? '' ),
            (string) ( $profile['placement_detail'] ?? '' ),
            (string) ( $profile['required_pages_detail'] ?? '' ),
            (string) ( $profile['ready_definition_detail'] ?? '' ),
        ];

        $parts = array_map(
            static function ( $part ): string {
                return trim( (string) $part );
            },
            $parts
        );
        $parts = array_values(
            array_filter(
                $parts,
                static function ( string $part ): bool {
                    return '' !== $part;
                }
            )
        );

        return implode( ' ', $parts );
    }

    public static function build_custom_setup_label( string $provider_label, string $services_label, string $placement_label ): string
    {
        return sprintf(
            /* translators: 1: provider mapping label, 2: services source label, 3: placement label */
            __( 'Custom Generic setup: %1$s + %2$s + %3$s', 'mybookaro' ),
            $provider_label,
            $services_label,
            $placement_label
        );
    }

    public static function build_compact_lane_snapshot(
        string $preset,
        string $provider_mode,
        string $provider_meta_key,
        string $services_model,
        string $placement_strategy,
        bool $auto_insert_enabled = false,
        string $auto_insert_mode = '',
        string $auto_insert_selector = ''
    ): array {
        $provider_label = self::get_provider_mode_label( $provider_mode, $provider_meta_key );
        $services_label = self::get_services_model_label( $services_model );
        $placement_label = self::get_placement_strategy_label(
            $placement_strategy,
            $auto_insert_enabled,
            $auto_insert_mode,
            $auto_insert_selector
        );
        $pattern_label = self::get_label( $preset );
        if ( '' === $pattern_label ) {
            $pattern_label = self::build_custom_setup_label( $provider_label, $services_label, $placement_label );
        }

        return [
            'pattern' => $pattern_label,
            'provider' => $provider_label,
            'services' => $services_label,
            'placement' => $placement_label,
        ];
    }

    public static function normalize_provider_mode( string $provider_mode ): string
    {
        $provider_mode = sanitize_key( $provider_mode );
        if ( ! in_array( $provider_mode, [ 'author', 'meta_key' ], true ) ) {
            return 'author';
        }

        return $provider_mode;
    }

    public static function normalize_services_model( string $services_model ): string
    {
        $services_model = sanitize_key( $services_model );
        if ( 'admin_catalog' === $services_model ) {
            $services_model = 'admin_only';
        }
        if ( ! in_array( $services_model, [ 'provider_only', 'admin_only', 'hybrid' ], true ) ) {
            return 'provider_only';
        }

        return $services_model;
    }

    public static function normalize_placement_strategy( string $placement_strategy ): string
    {
        $placement_strategy = sanitize_key( $placement_strategy );
        if ( ! in_array( $placement_strategy, [ 'directory_template', 'normal_page', 'shortcode_only', 'css_selector' ], true ) ) {
            return 'shortcode_only';
        }

        return $placement_strategy;
    }

    public static function get_provider_mode_label( string $provider_mode, string $provider_meta_key = '' ): string
    {
        $provider_mode = self::normalize_provider_mode( $provider_mode );
        if ( 'meta_key' === $provider_mode ) {
            $provider_meta_key = sanitize_key( $provider_meta_key );
            if ( '' !== $provider_meta_key ) {
                return sprintf(
                    /* translators: %s: listing meta key used for provider mapping */
                    __( 'Listing Meta Key (%s)', 'mybookaro' ),
                    $provider_meta_key
                );
            }

            return __( 'Listing Meta Key', 'mybookaro' );
        }

        return __( 'Listing Author', 'mybookaro' );
    }

    public static function get_services_model_label( string $services_model ): string
    {
        $services_model = self::normalize_services_model( $services_model );
        $labels = [
            'provider_only' => __( 'Provider Only', 'mybookaro' ),
            'admin_only' => __( 'Admin Catalog Only', 'mybookaro' ),
            'hybrid' => __( 'Hybrid', 'mybookaro' ),
        ];

        return (string) ( $labels[ $services_model ] ?? $labels['provider_only'] );
    }

    public static function get_placement_strategy_label(
        string $placement_strategy,
        bool $auto_insert_enabled = false,
        string $auto_insert_mode = '',
        string $auto_insert_selector = ''
    ): string {
        $placement_strategy = self::normalize_placement_strategy( $placement_strategy );
        $labels = [
            'directory_template' => __( 'Directory template placement', 'mybookaro' ),
            'normal_page' => __( 'Normal page placement', 'mybookaro' ),
            'shortcode_only' => __( 'Shortcode/block-only placement', 'mybookaro' ),
            'css_selector' => __( 'CSS selector placement', 'mybookaro' ),
        ];
        $label = (string) ( $labels[ $placement_strategy ] ?? $labels['shortcode_only'] );

        if ( ! $auto_insert_enabled || 'shortcode_only' !== $placement_strategy ) {
            return $label;
        }

        $auto_insert_mode = sanitize_key( $auto_insert_mode );
        if ( 'selector' === $auto_insert_mode ) {
            $auto_insert_selector = sanitize_text_field( $auto_insert_selector );
            if ( '' !== $auto_insert_selector ) {
                return sprintf(
                    /* translators: 1: placement label, 2: css selector */
                    __( '%1$s + Auto-Insert fallback (selector: %2$s)', 'mybookaro' ),
                    $label,
                    $auto_insert_selector
                );
            }

            return sprintf(
                /* translators: %s: placement label */
                __( '%s + Auto-Insert fallback (selector)', 'mybookaro' ),
                $label
            );
        }

        if ( 'before_content' === $auto_insert_mode ) {
            return sprintf(
                /* translators: %s: placement label */
                __( '%s + Auto-Insert fallback (before content)', 'mybookaro' ),
                $label
            );
        }

        return sprintf(
            /* translators: %s: placement label */
            __( '%s + Auto-Insert fallback (after content)', 'mybookaro' ),
            $label
        );
    }
}
