<?php
/**
 * Plugin Name: ThaiForTravel Mini App API
 * Description: Normalized REST API for ThaiForTravel tours, yachts, zoos and transfers.
 * Version: 0.4.7
 * Requires at least: 6.5
 * Requires PHP: 8.1
 * Author: ThaiForTravel
 * Text Domain: tft-miniapp-api
 */

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

define('TFT_MINIAPP_API_VERSION', '0.4.7');
define('TFT_MINIAPP_API_PATH', plugin_dir_path(__FILE__));
define('TFT_MINIAPP_TOURS_CACHE_KEY', 'tft_miniapp_tours_v12');
define('TFT_MINIAPP_TRANSFERS_CACHE_KEY', 'tft_miniapp_transfers_v7');

require_once TFT_MINIAPP_API_PATH . 'includes/class-tft-miniapp-normalizer.php';
require_once TFT_MINIAPP_API_PATH . 'includes/class-tft-miniapp-catalog-overrides.php';
require_once TFT_MINIAPP_API_PATH . 'includes/class-tft-miniapp-rest-controller.php';

function tft_miniapp_tour_post_types(): array
{
    return [
        'pattaya',
        'phuket',
        'yacht',
        'yacht_phuket',
        'zoo_pattaya',
        'zoo_phuket',
    ];
}

function tft_miniapp_register_content_model(): void
{
    register_taxonomy(
        'tft_miniapp_category',
        tft_miniapp_tour_post_types(),
        [
            'labels' => [
                'name' => 'Категории Mini App',
                'singular_name' => 'Категория Mini App',
                'search_items' => 'Найти категорию',
                'all_items' => 'Все категории',
                'edit_item' => 'Изменить категорию',
                'update_item' => 'Обновить категорию',
                'add_new_item' => 'Добавить категорию',
                'new_item_name' => 'Название категории',
                'menu_name' => 'Категории Mini App',
            ],
            'public' => false,
            'show_ui' => true,
            'show_admin_column' => true,
            'show_in_rest' => true,
            'hierarchical' => false,
            'rewrite' => false,
        ]
    );

    foreach (tft_miniapp_tour_post_types() as $post_type) {
        register_post_meta(
            $post_type,
            '_tft_miniapp_featured',
            [
                'type' => 'boolean',
                'single' => true,
                'default' => false,
                'show_in_rest' => true,
                'sanitize_callback' => 'rest_sanitize_boolean',
                'auth_callback' => static fn (): bool => current_user_can('edit_posts'),
            ]
        );
        register_post_meta(
            $post_type,
            '_tft_miniapp_duration_days',
            [
                'type' => 'integer',
                'single' => true,
                'default' => 1,
                'show_in_rest' => true,
                'sanitize_callback' => 'absint',
                'auth_callback' => static fn (): bool => current_user_can('edit_posts'),
            ]
        );
        register_post_meta(
            $post_type,
            '_tft_miniapp_adult_price',
            [
                'type' => 'number',
                'single' => true,
                'show_in_rest' => true,
                'sanitize_callback' => 'floatval',
                'auth_callback' => static fn (): bool => current_user_can('edit_posts'),
            ]
        );
        register_post_meta(
            $post_type,
            '_tft_miniapp_child_price',
            [
                'type' => 'number',
                'single' => true,
                'show_in_rest' => true,
                'sanitize_callback' => 'floatval',
                'auth_callback' => static fn (): bool => current_user_can('edit_posts'),
            ]
        );
    }
}
add_action('init', 'tft_miniapp_register_content_model');

function tft_miniapp_seed_terms(): void
{
    $terms = [
        'sea' => 'Морские',
        'kids' => 'Можно с детьми',
        'extreme' => 'Экстрим',
        'adult' => 'Для взрослых',
        'nature' => 'Природа и животные',
        'far' => 'Дальние туры',
        'bangkok' => 'Бангкок',
        'culture' => 'Культура и обзорные',
        'shopping' => 'Шопинг и мастер-классы',
        'evening' => 'Вечерние',
        'islands' => 'Острова и пляжи',
        'fishing' => 'Рыбалка/дайвинг',
        'overview' => 'Обзорные',
    ];

    foreach ($terms as $slug => $name) {
        if (!term_exists($slug, 'tft_miniapp_category')) {
            wp_insert_term($name, 'tft_miniapp_category', ['slug' => $slug]);
        }
    }
}
add_action('init', 'tft_miniapp_seed_terms', 20);

function tft_miniapp_add_meta_box(): void
{
    foreach (tft_miniapp_tour_post_types() as $post_type) {
        add_meta_box(
            'tft-miniapp-settings',
            'ThaiForTravel Mini App',
            'tft_miniapp_render_meta_box',
            $post_type,
            'side',
            'default'
        );
    }
}
add_action('add_meta_boxes', 'tft_miniapp_add_meta_box');

function tft_miniapp_render_meta_box(WP_Post $post): void
{
    wp_nonce_field('tft_miniapp_save_meta', 'tft_miniapp_meta_nonce');
    $featured = (bool) get_post_meta($post->ID, '_tft_miniapp_featured', true);
    $duration_days = max(1, (int) get_post_meta($post->ID, '_tft_miniapp_duration_days', true));
    $adult_price = get_post_meta($post->ID, '_tft_miniapp_adult_price', true);
    $child_price = get_post_meta($post->ID, '_tft_miniapp_child_price', true);
    ?>
    <p>
        <label>
            <input type="checkbox" name="tft_miniapp_featured" value="1" <?php checked($featured); ?>>
            Показывать как популярную
        </label>
    </p>
    <p>
        <label for="tft_miniapp_duration_days"><strong>Длительность, дней</strong></label>
        <input class="widefat" id="tft_miniapp_duration_days" name="tft_miniapp_duration_days" type="number" min="1" max="30" value="<?php echo esc_attr((string) $duration_days); ?>">
    </p>
    <p>
        <label for="tft_miniapp_adult_price"><strong>Резервная взрослая цена</strong></label>
        <input class="widefat" id="tft_miniapp_adult_price" name="tft_miniapp_adult_price" type="number" min="0" step="1" value="<?php echo esc_attr((string) $adult_price); ?>">
    </p>
    <p>
        <label for="tft_miniapp_child_price"><strong>Резервная детская цена</strong></label>
        <input class="widefat" id="tft_miniapp_child_price" name="tft_miniapp_child_price" type="number" min="0" step="1" value="<?php echo esc_attr((string) $child_price); ?>">
    </p>
    <?php
}

function tft_miniapp_save_meta(int $post_id): void
{
    if (
        !isset($_POST['tft_miniapp_meta_nonce']) ||
        !wp_verify_nonce(
            sanitize_text_field(wp_unslash($_POST['tft_miniapp_meta_nonce'])),
            'tft_miniapp_save_meta'
        ) ||
        (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) ||
        !current_user_can('edit_post', $post_id)
    ) {
        return;
    }

    update_post_meta(
        $post_id,
        '_tft_miniapp_featured',
        isset($_POST['tft_miniapp_featured']) ? '1' : '0'
    );
    update_post_meta(
        $post_id,
        '_tft_miniapp_duration_days',
        max(1, min(30, absint($_POST['tft_miniapp_duration_days'] ?? 1)))
    );

    foreach (['adult', 'child'] as $price_type) {
        $field = 'tft_miniapp_' . $price_type . '_price';
        $meta_key = '_tft_miniapp_' . $price_type . '_price';
        $raw_value = isset($_POST[$field]) ? wp_unslash($_POST[$field]) : '';
        if ($raw_value === '') {
            delete_post_meta($post_id, $meta_key);
        } else {
            update_post_meta($post_id, $meta_key, max(0, (float) $raw_value));
        }
    }
}
add_action('save_post', 'tft_miniapp_save_meta');

function tft_miniapp_purge_catalog_cache(): void
{
    delete_transient(TFT_MINIAPP_TOURS_CACHE_KEY);
    delete_transient(TFT_MINIAPP_TRANSFERS_CACHE_KEY);

    if (
        defined('TFT_MINIAPP_BACKEND_PURGE_URL') &&
        defined('TFT_MINIAPP_SYNC_SECRET') &&
        TFT_MINIAPP_BACKEND_PURGE_URL &&
        TFT_MINIAPP_SYNC_SECRET
    ) {
        wp_remote_post(
            TFT_MINIAPP_BACKEND_PURGE_URL,
            [
                'timeout' => 1,
                'blocking' => false,
                'headers' => [
                    'x-tft-sync-secret' => TFT_MINIAPP_SYNC_SECRET,
                ],
            ]
        );
    }
}

function tft_miniapp_maybe_purge_for_post(int $post_id): void
{
    $post_type = get_post_type($post_id);
    if (
        in_array($post_type, tft_miniapp_tour_post_types(), true) ||
        $post_type === 'page'
    ) {
        tft_miniapp_purge_catalog_cache();
    }
}
add_action('save_post', 'tft_miniapp_maybe_purge_for_post', 30);
add_action('deleted_post', 'tft_miniapp_maybe_purge_for_post');
add_action('set_object_terms', 'tft_miniapp_purge_catalog_cache');

function tft_miniapp_maybe_purge_on_version_change(): void
{
    $option = 'tft_miniapp_api_version';
    if ((string) get_option($option, '') === TFT_MINIAPP_API_VERSION) {
        return;
    }

    update_option($option, TFT_MINIAPP_API_VERSION, false);
    tft_miniapp_purge_catalog_cache();
}
add_action('init', 'tft_miniapp_maybe_purge_on_version_change', 40);

function tft_miniapp_register_rest_routes(): void
{
    (new TFT_Miniapp_REST_Controller())->register_routes();
}
add_action('rest_api_init', 'tft_miniapp_register_rest_routes');

register_activation_hook(
    __FILE__,
    static function (): void {
        tft_miniapp_register_content_model();
        tft_miniapp_seed_terms();
        tft_miniapp_purge_catalog_cache();
        flush_rewrite_rules();
    }
);
