<?php
namespace BLR\Backline\Modules\Events;

use BLR\Backline\Core\Access;
use BLR\Backline\Core\AdminMenu;
use BLR\Backline\Core\Sanitizer;

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

final class Module {
    private const CALENDAR_CACHE_VERSION_OPTION = 'blr_ba_calendar_cache_version';


    /**
     * Register CPT/meta only. Front-end routes are hard-coded in the core Router.
     */
    public static function register_feature_only(): void {
        add_action('init', [self::class, 'register_cpt']);
        add_action('init', [self::class, 'register_meta'], 11);
        add_action('save_post_blr_event', [self::class, 'handle_event_save'], 20, 3);
        add_action('before_delete_post', [self::class, 'handle_post_deletion']);
        add_action('trashed_post', [self::class, 'handle_post_deletion']);
        add_action('untrashed_post', [self::class, 'handle_post_deletion']);
    }


    public static function register_cpt(): void {
        $common = [
            'public'              => false,
            'publicly_queryable'  => false,
            'exclude_from_search' => true,
            'show_ui'             => false,
            'show_in_menu'        => false,
            'show_in_rest'        => false,
            'show_in_nav_menus'   => false,
            'has_archive'         => false,
            'rewrite'             => false,
            'query_var'           => false,
            'supports'            => ['title', 'editor', 'thumbnail', 'excerpt', 'custom-fields', 'revisions', 'author'],
        ];

        register_post_type(
            'blr_event',
            array_replace_recursive(
                $common,
                Access::post_type_registration_args('blr_event'),
                [
                    'labels' => [
                        'name'          => __('Events', 'blr-backline'),
                        'singular_name' => __('Event', 'blr-backline'),
                    ],
                    'menu_icon' => 'dashicons-calendar-alt',
                ]
            )
        );
    }

    public static function register_meta(): void {
        // Dates/time
        self::reg_meta('blr_event', 'blr_event_start', 'string'); // "YYYY-MM-DD HH:MM"
        self::reg_meta('blr_event', 'blr_event_end', 'string');
        self::reg_meta('blr_event', 'blr_timezone', 'string');

        // Venue/location
        self::reg_meta('blr_event', 'blr_venue_name', 'string');
        self::reg_meta('blr_event', 'blr_venue_website', 'string');
        self::reg_meta('blr_event', 'blr_venue_address', 'string');
        self::reg_meta('blr_event', 'blr_venue_city', 'string');
        self::reg_meta('blr_event', 'blr_venue_state', 'string');
        self::reg_meta('blr_event', 'blr_venue_postal', 'string');
        self::reg_meta('blr_event', 'blr_venue_country', 'string');
        self::reg_meta('blr_event', 'blr_venue_phone', 'string'); // kept for future venue CPT

        // Links
        self::reg_meta('blr_event', 'blr_ticket_url', 'string');
        self::reg_meta('blr_event', 'blr_event_url', 'string');

        // Operational details
        self::reg_meta('blr_event', 'blr_event_status', 'string'); // confirmed/hold/cancelled
        self::reg_meta('blr_event', 'blr_age_restriction', 'string');
        self::reg_meta('blr_event', 'blr_doors', 'string');
        self::reg_meta('blr_event', 'blr_set_time', 'string');
        self::reg_meta('blr_event', 'blr_load_in', 'string');
        self::reg_meta('blr_event', 'blr_soundcheck', 'string');
        self::reg_meta('blr_event', 'blr_payout', 'string');
        self::reg_meta('blr_event', 'blr_notes', 'string');

        // Public display controls
        self::reg_meta('blr_event', 'blr_show_frontend', 'boolean');
    }


    public static function handle_event_save(int $post_id, \WP_Post $post, bool $update): void {
        unset($post, $update);

        if ($post_id <= 0 || wp_is_post_revision($post_id)) {
            return;
        }

        self::bump_calendar_cache_version();
    }

    public static function handle_post_deletion(int $post_id): void {
        $post = get_post($post_id);
        if (!$post instanceof \WP_Post || $post->post_type !== 'blr_event') {
            return;
        }

        self::bump_calendar_cache_version();
    }

    public static function calendar_cache_version(): int {
        $version = (int) get_option(self::CALENDAR_CACHE_VERSION_OPTION, 1);
        return $version > 0 ? $version : 1;
    }

    public static function bump_calendar_cache_version(): void {
        update_option(self::CALENDAR_CACHE_VERSION_OPTION, self::calendar_cache_version() + 1, false);
    }

    public static function status_options(): array {
        return [
            'confirmed' => __('Confirmed', 'blr-backline'),
            'hold' => __('Hold', 'blr-backline'),
            'cancelled' => __('Cancelled', 'blr-backline'),
        ];
    }

    public static function normalize_status(string $value): string {
        $value = strtolower(trim(sanitize_text_field($value)));
        if ($value === '') {
            return '';
        }

        $aliases = [
            'confirmed' => 'confirmed',
            'confirm' => 'confirmed',
            'booked' => 'confirmed',
            'locked' => 'confirmed',
            'hold' => 'hold',
            'on hold' => 'hold',
            'onhold' => 'hold',
            'tentative' => 'hold',
            'pending' => 'hold',
            'cancelled' => 'cancelled',
            'canceled' => 'cancelled',
            'cancel' => 'cancelled',
        ];

        if (isset($aliases[$value])) {
            return $aliases[$value];
        }

        $compact = preg_replace('/[^a-z0-9]+/', '', $value);
        if (is_string($compact) && isset($aliases[$compact])) {
            return $aliases[$compact];
        }

        return array_key_exists($value, self::status_options()) ? $value : '';
    }


    public static function normalize_show_frontend($value): string {
        if (is_bool($value)) {
            return $value ? '1' : '0';
        }

        $value = strtolower(trim(sanitize_text_field((string) $value)));
        return in_array($value, ['1', 'true', 'on', 'yes'], true) ? '1' : '0';
    }

    public static function status_label(string $value): string {
        $normalized = self::normalize_status($value);
        if ($normalized === '') {
            return __('Unspecified', 'blr-backline');
        }

        $options = self::status_options();
        return (string) ($options[$normalized] ?? ucfirst($normalized));
    }

    private static function reg_meta(string $post_type, string $key, string $type): void {
        register_post_meta($post_type, $key, [
            'type' => $type,
            'single' => true,
            'show_in_rest' => false,
            'sanitize_callback' => static function ($value) use ($key, $type) {
                if ($key === 'blr_event_status') {
                    return self::normalize_status((string) $value);
                }

                if ($key === 'blr_show_frontend') {
                    return self::normalize_show_frontend($value);
                }

                if (in_array($key, ['blr_event_start', 'blr_event_end'], true)) {
                    return Sanitizer::datetime_ymd_hi($value);
                }

                if (in_array($key, ['blr_doors', 'blr_set_time', 'blr_load_in', 'blr_soundcheck'], true)) {
                    return Sanitizer::time_hi($value);
                }

                return Sanitizer::meta_value($key, $value, $type);
            },
            'auth_callback' => Access::rest_meta_auth_callback($post_type),
        ]);
    }
}
