<?php

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

class WNC_Connect_Settings {

    const OPTION_KEY = 'wnc_connect_field_map';
    const MIGRATION_OPTION_KEY = 'wnc_legacy_mapping_migrated';

    public static function init() {
        self::maybe_migrate_legacy_mapping();
        add_action('admin_menu', [__CLASS__, 'add_settings_page']);
    }

    /**
     * Copy mappings saved by Connector 1.0 into the consolidated option array.
     *
     * Existing non-empty values always win. The legacy option is deliberately
     * retained as a recovery copy, while the migration flag prevents a mapping
     * that is intentionally cleared later from being restored on every request.
     */
    public static function maybe_migrate_legacy_mapping() {
        if (get_option(self::MIGRATION_OPTION_KEY, false)) {
            return;
        }

        $legacy = get_option(self::OPTION_KEY, []);

        if (!is_array($legacy) || empty($legacy)) {
            return;
        }

        $options = get_option('wnc_options', []);
        $options = is_array($options) ? $options : [];

        $legacy_key_map = [
            'name'                    => 'name_key',
            'address'                 => 'address_key',
            'postcode'                => 'postcode_key',
            'website'                 => 'website_key',
            'booking-url'             => 'booking_url_key',
            'parking-url'             => 'parking_url_key',
            'category'                => 'category_key',
            'image'                   => 'cover_image_key',
            'price'                   => 'pricing_key',
            'price-type'              => 'price_type_key',
            'adult-price'             => 'adult_price_key',
            'child-price'             => 'child_price_key',
            'family-price'            => 'family_price_key',
            'carer-pricing-type'      => 'carer_pricing_type_key',
            'carer-price'             => 'carer_price_key',
            'parking-cost'            => 'parking_cost_key',
            'price-notes'             => 'price_notes_key',
            'pricing-source'          => 'pricing_source_key',
            'pricing-last-checked'    => 'pricing_last_checked_key',
            'pricing-confidence'      => 'pricing_confidence_key',
            'membership-provider'     => 'membership_provider_key',
            'opening-times'           => 'opening_times_key',
            'monday'                  => 'monday_key',
            'tuesday'                 => 'tuesday_key',
            'wednesday'               => 'wednesday_key',
            'thursday'                => 'thursday_key',
            'friday'                  => 'friday_key',
            'saturday'                => 'saturday_key',
            'sunday'                  => 'sunday_key',
            'indoor-outdoor'          => 'indoor_outdoor_key',
            'facilities'              => 'facilities_key',
            'parking-available'       => 'parking_key',
            'age-suitability'         => 'age_suitability_key',
            'notes'                   => 'notes_key',
            'what3words'              => 'what3words_key',
            'latitude'                => 'latitude_key',
            'longitude'               => 'longitude_key',
            'phone'                   => 'phone_key',
            'place-mode'              => 'place_mode_key',
            'event-start-date'        => 'event_start_date_key',
            'event-end-date'          => 'event_end_date_key',
        ];

        $changed = false;

        foreach ($legacy_key_map as $legacy_key => $option_key) {
            $legacy_value = isset($legacy[$legacy_key])
                ? sanitize_text_field((string) $legacy[$legacy_key])
                : '';

            if ($legacy_value === '' || !empty($options[$option_key])) {
                continue;
            }

            $options[$option_key] = $legacy_value;
            $changed = true;
        }

        if ($changed) {
            update_option('wnc_options', $options);
        }

        update_option(self::MIGRATION_OPTION_KEY, 1, false);
    }

    public static function tags() {
        return [
            // Core
            'name' => 'Place Name',
            'address' => 'Address',
            'postcode' => 'Postcode',
            'website' => 'Website',
            'bookingUrl' => 'Booking URL',
            'parkingUrl' => 'Pre-book Parking URL',
            'category' => 'Category',
            'coverImageUri' => 'Cover Image',

            // Events
            'placeMode' => 'Place Mode',
            'eventStartDate' => 'Event Start Date',
            'eventEndDate' => 'Event End Date',

            // Pricing
            'pricing' => 'Pricing Table / Summary',
            'adultPrice' => 'Adult Price',
            'childPrice' => 'Child Price',
            'familyPrice' => 'Family Price',
            'carerPricingType' => 'Carer Pricing Type',
            'carerPrice' => 'Carer Price',
            'parkingCost' => 'Parking Cost',

            // Membership / opening / details
            'membershipProvider' => 'Membership Provider',
            'openingTimes' => 'Opening Times',
            'monday' => 'Monday Opening Times',
            'tuesday' => 'Tuesday Opening Times',
            'wednesday' => 'Wednesday Opening Times',
            'thursday' => 'Thursday Opening Times',
            'friday' => 'Friday Opening Times',
            'saturday' => 'Saturday Opening Times',
            'sunday' => 'Sunday Opening Times',
            'indoorOutdoor' => 'Indoor / Outdoor',
            'facilities' => 'Facilities',
            'parking' => 'Parking Information',
            'ageSuitability' => 'Age Suitability',

            // Location
            'what3words' => 'what3words',
            'latitude' => 'Latitude',
            'longitude' => 'Longitude',
            'phone' => 'Phone',
            
        ];
    }

    public static function add_settings_page() {
        add_options_page(
            'Where Next Connect',
            'Where Next Connect',
            'manage_options',
            'where-next-connect',
            [__CLASS__, 'render_settings_page']
        );
    }

    public static function register_settings() {
        register_setting(
            'wnc_settings',
            'wnc_options',
            [
                'sanitize_callback' => 'wnc_sanitize_options',
                'default' => [],
            ]
        );
    }

    public static function sanitize_options($input) {
        $existing = get_option('wnc_options', []);

        if (!is_array($existing)) {
            $existing = [];
        }

        if (!is_array($input)) {
            return $existing;
        }

        $output = $existing;

        /*
        |--------------------------------------------------------------------------
        | Enabled Post Types
        |--------------------------------------------------------------------------
        */

        $enabled_post_types = [];

        if (!empty($input['enabled_post_types']) && is_array($input['enabled_post_types'])) {
            $public_post_types = array_keys(self::get_public_post_types());

            foreach ($input['enabled_post_types'] as $post_type) {
                $post_type = sanitize_key(wp_unslash($post_type));

                if (in_array($post_type, $public_post_types, true)) {
                    $enabled_post_types[] = $post_type;
                }
            }
        }

        $output['enabled_post_types'] = array_values(array_unique($enabled_post_types));

        $event_post_types = [];

        if (!empty($input['event_post_types']) && is_array($input['event_post_types'])) {
            foreach ($input['event_post_types'] as $post_type) {
                $post_type = sanitize_key(wp_unslash($post_type));

                if (in_array($post_type, $enabled_post_types, true)) {
                    $event_post_types[] = $post_type;
                }
            }
        }

        $output['event_post_types'] = array_values(array_unique($event_post_types));

        /*
        |--------------------------------------------------------------------------
        | Field Mapping
        |--------------------------------------------------------------------------
        */

        $key_map = self::option_key_map();

        foreach (self::tags() as $tag => $label) {
            $option_key = $key_map[$tag] ?? '';

            if (!$option_key) {
                continue;
            }

            $value = '';

            if (isset($input[$option_key])) {
                $value = sanitize_text_field(wp_unslash($input[$option_key]));
            }

            $output[$option_key] = $value;
        }
        
  /*
|--------------------------------------------------------------------------
| Button / Badge / Archive Settings
|--------------------------------------------------------------------------
*/

$output['show_badge'] = !empty($input['show_badge']) ? 1 : 0;

$badge_variant = isset($input['badge_variant'])
    ? sanitize_key(wp_unslash($input['badge_variant']))
    : 'colour';

$output['badge_variant'] = in_array(
    $badge_variant,
    ['colour', 'light', 'icon'],
    true
) ? $badge_variant : 'colour';

$badge_position = isset($input['badge_position'])
    ? sanitize_key(wp_unslash($input['badge_position']))
    : 'manual';

$output['badge_position'] = in_array(
    $badge_position,
    ['manual', 'after_button', 'after_content', 'footer'],
    true
) ? $badge_position : 'manual';

$output['archive_button_enabled'] = !empty($input['archive_button_enabled']) ? 1 : 0;

$archive_button_position = isset($input['archive_button_position'])
    ? sanitize_key(wp_unslash($input['archive_button_position']))
    : 'after_excerpt';

$output['archive_button_position'] = in_array(
    $archive_button_position,
    ['after_excerpt', 'after_title', 'after_content'],
    true
) ? $archive_button_position : 'after_excerpt';

$archive_button_mode = isset($input['archive_button_mode'])
    ? sanitize_key(wp_unslash($input['archive_button_mode']))
    : 'url';

$output['archive_button_mode'] = in_array(
    $archive_button_mode,
    ['url', 'full'],
    true
) ? $archive_button_mode : 'url';

        return $output;
    }

    public static function option_key_map() {
        return [
            'name' => 'name_key',
            'address' => 'address_key',
            'postcode' => 'postcode_key',
            'website' => 'website_key',
            'bookingUrl' => 'booking_url_key',
            'parkingUrl' => 'parking_url_key',
            'category' => 'category_key',
            'coverImageUri' => 'cover_image_key',

            'placeMode' => 'place_mode_key',
            'eventStartDate' => 'event_start_date_key',
            'eventEndDate' => 'event_end_date_key',

            'pricing' => 'pricing_key',
            'adultPrice' => 'adult_price_key',
            'childPrice' => 'child_price_key',
            'familyPrice' => 'family_price_key',
            'carerPricingType' => 'carer_pricing_type_key',
            'carerPrice' => 'carer_price_key',
            'parkingCost' => 'parking_cost_key',

            'membershipProvider' => 'membership_provider_key',
            'openingTimes' => 'opening_times_key',
            'monday' => 'monday_key',
            'tuesday' => 'tuesday_key',
            'wednesday' => 'wednesday_key',
            'thursday' => 'thursday_key',
            'friday' => 'friday_key',
            'saturday' => 'saturday_key',
            'sunday' => 'sunday_key',
            'indoorOutdoor' => 'indoor_outdoor_key',
            'facilities' => 'facilities_key',
            'parking' => 'parking_key',
            'ageSuitability' => 'age_suitability_key',

            'what3words' => 'what3words_key',
            'latitude' => 'latitude_key',
            'longitude' => 'longitude_key',
            'phone' => 'phone_key',
        ];
    }

    public static function get_enabled_post_types() {
        $options = function_exists('wnc_get_options')
            ? wnc_get_options()
            : get_option('wnc_options', []);

        if (!is_array($options)) {
            $options = [];
        }

        if (!empty($options['enabled_post_types']) && is_array($options['enabled_post_types'])) {
            return array_values(array_unique(array_map('sanitize_key', $options['enabled_post_types'])));
        }

        return ['post', 'page'];
    }

    public static function is_enabled_post_type($post_type = null) {
        if (!$post_type) {
            $post_type = get_post_type();
        }

        if (!$post_type) {
            return false;
        }

        return in_array($post_type, self::get_enabled_post_types(), true);
    }

    public static function get_mapping() {
        $options = function_exists('wnc_get_options')
            ? wnc_get_options()
            : get_option('wnc_options', []);

        if (!is_array($options)) {
            return [];
        }

        return [
            'name' => $options['name_key'] ?? '',
            'address' => $options['address_key'] ?? '',
            'postcode' => $options['postcode_key'] ?? '',
            'website' => $options['website_key'] ?? '',
            'bookingUrl' => $options['booking_url_key'] ?? '',
            'parkingUrl' => $options['parking_url_key'] ?? '',
            'category' => $options['category_key'] ?? '',
            'coverImageUri' => $options['cover_image_key'] ?? '',

            'placeMode' => $options['place_mode_key'] ?? '',
            'eventStartDate' => $options['event_start_date_key'] ?? '',
            'eventEndDate' => $options['event_end_date_key'] ?? '',

            'pricing' => $options['pricing_key'] ?? '',
            'adultPrice' => $options['adult_price_key'] ?? '',
            'childPrice' => $options['child_price_key'] ?? '',
            'familyPrice' => $options['family_price_key'] ?? '',
            'carerPricingType' => $options['carer_pricing_type_key'] ?? '',
            'carerPrice' => $options['carer_price_key'] ?? '',
            'parkingCost' => $options['parking_cost_key'] ?? '',

            'membershipProvider' => $options['membership_provider_key'] ?? '',
            'openingTimes' => $options['opening_times_key'] ?? '',
            'monday' => $options['monday_key'] ?? '',
            'tuesday' => $options['tuesday_key'] ?? '',
            'wednesday' => $options['wednesday_key'] ?? '',
            'thursday' => $options['thursday_key'] ?? '',
            'friday' => $options['friday_key'] ?? '',
            'saturday' => $options['saturday_key'] ?? '',
            'sunday' => $options['sunday_key'] ?? '',
            'indoorOutdoor' => $options['indoor_outdoor_key'] ?? '',
            'facilities' => $options['facilities_key'] ?? '',
            'parking' => $options['parking_key'] ?? '',
            'ageSuitability' => $options['age_suitability_key'] ?? '',

            'what3words' => $options['what3words_key'] ?? '',
            'latitude' => $options['latitude_key'] ?? '',
            'longitude' => $options['longitude_key'] ?? '',
            'phone' => $options['phone_key'] ?? '',
        ];
    }

    public static function render_settings_page() {
        if (!current_user_can('manage_options')) {
            return;
        }

        $mapping = self::get_mapping();
        $sources = self::get_source_options();
        $enabled_post_types = self::get_enabled_post_types();
        $public_post_types = self::get_public_post_types();
        $key_map = self::option_key_map();

        ?>
        <div class="wrap">
            <h1>Where Next Connect</h1>

            <p>
                Choose which content types Where Next Connect should run on, then map each Where Next tag to a default source.
                Individual posts can still override these values in the Where Next Connect box.
            </p>

            <form method="post" action="options.php">
                <?php settings_fields('wnc_settings'); ?>
                <input type="hidden" name="wnc_options[_form_scope]" value="connect">

                <h2>Enabled Post Types</h2>

                <table class="widefat striped" style="max-width: 1000px; margin-bottom: 24px;">
                    <tbody>
                        <tr>
                            <td>
                                <?php foreach ($public_post_types as $post_type => $object) : ?>
                                    <label style="display:block; margin: 8px 0;">
                                        <input
                                            type="checkbox"
                                            name="wnc_options[enabled_post_types][]"
                                            value="<?php echo esc_attr($post_type); ?>"
                                            <?php checked(in_array($post_type, $enabled_post_types, true)); ?>
                                        >
                                        <?php echo esc_html($object->labels->name ?? $post_type); ?>
                                        <code><?php echo esc_html($post_type); ?></code>
                                    </label>
                                <?php endforeach; ?>

                                <p class="description">
                                    Select where Where Next buttons, meta tags and override boxes should be available.
                                </p>
                            </td>
                        </tr>
                    </tbody>
                </table>

                <h2>Event Post Types</h2>
                <table class="widefat striped" style="max-width:1000px;margin-bottom:24px;">
                    <tbody><tr><td>
                        <?php $event_post_types = function_exists('wnc_get_event_post_types') ? wnc_get_event_post_types() : []; ?>
                        <?php foreach ($public_post_types as $post_type => $object) : ?>
                            <label style="display:block;margin:8px 0;">
                                <input type="checkbox" name="wnc_options[event_post_types][]" value="<?php echo esc_attr($post_type); ?>" <?php checked(in_array($post_type, $event_post_types, true)); ?>>
                                <?php echo esc_html($object->labels->name ?? $post_type); ?> <code><?php echo esc_html($post_type); ?></code>
                            </label>
                        <?php endforeach; ?>
                        <p class="description">Event post types are checked for start and end dates instead of normal place-only fields.</p>
                    </td></tr></tbody>
                </table>

                <h2>Field Mapping</h2>

                <table class="widefat striped" style="max-width: 1000px;">
                    <thead>
                        <tr>
                            <th style="width: 260px;">Where Next Tag</th>
                            <th>Default Source</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach (self::tags() as $tag => $label) : ?>
                            <?php $option_key = $key_map[$tag] ?? ''; ?>

                            <?php if (!$option_key) : ?>
                                <?php continue; ?>
                            <?php endif; ?>

                            <tr>
                                <td>
                                    <strong><?php echo esc_html($label); ?></strong><br>
                                    <code>wherenext:<?php echo esc_html($tag); ?></code>
                                </td>
                                <td>
                                    <select name="wnc_options[<?php echo esc_attr($option_key); ?>]" style="width: 100%; max-width: 520px;">
                                        <?php foreach ($sources as $value => $source_label) : ?>
                                            <option value="<?php echo esc_attr($value); ?>" <?php selected($mapping[$tag] ?? '', $value); ?>>
                                                <?php echo esc_html($source_label); ?>
                                            </option>
                                        <?php endforeach; ?>
                                    </select>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>

                <?php submit_button('Save Where Next Settings'); ?>
            </form>
        </div>
        <?php
    }

    private static function get_source_options() {
        $options = [
            '' => 'None',
            'post:title' => 'Post Title',
            'post:permalink' => 'Permalink',
            'post:featured_image' => 'Featured Image',
            'post:excerpt' => 'Excerpt',
            'post:content' => 'Content',
        ];

        foreach (self::get_meta_keys() as $meta_key) {
            $options['meta:' . $meta_key] = 'Custom field: ' . $meta_key;
        }

        foreach (self::get_taxonomies() as $taxonomy_name => $taxonomy_label) {
            $options['tax:' . $taxonomy_name] = 'Taxonomy: ' . $taxonomy_label;
        }

        return $options;
    }

    private static function get_meta_keys() {
        global $wpdb;

        $keys = $wpdb->get_col(
            "SELECT DISTINCT meta_key
             FROM {$wpdb->postmeta}
             WHERE meta_key NOT LIKE '\_%'
             ORDER BY meta_key ASC
             LIMIT 300"
        );

        return array_filter(array_map('sanitize_text_field', (array) $keys));
    }

    private static function get_taxonomies() {
        $taxonomies = get_taxonomies(['public' => true], 'objects');
        $out = [];

        foreach ($taxonomies as $taxonomy) {
            $out[$taxonomy->name] = $taxonomy->label . ' (' . $taxonomy->name . ')';
        }

        asort($out);

        return $out;
    }

    private static function get_public_post_types() {
        $post_types = get_post_types(['public' => true], 'objects');

        unset($post_types['attachment']);

        uasort($post_types, function ($a, $b) {
            return strcasecmp($a->labels->name ?? $a->name, $b->labels->name ?? $b->name);
        });

        return $post_types;
    }
}

if (!function_exists('wnc_get_enabled_post_types')) {
    function wnc_get_enabled_post_types() {
        return WNC_Connect_Settings::get_enabled_post_types();
    }
}

if (!function_exists('wnc_is_enabled_post_type')) {
    function wnc_is_enabled_post_type($post_type = null) {
        return WNC_Connect_Settings::is_enabled_post_type($post_type);
    }
}
