<?php
/**
 * Lightweight bootstrap guards (avoid breaking core WP admin screens).
 *
 * @package Maca_MenuList
 */

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

/**
 * Admin menu icon ("ML" monogram SVG or dashicon fallback).
 *
 * @return string Dashicon class or data:image/svg+xml URL for add_menu_page().
 */
function maca_menulist_get_admin_menu_icon() {
    $svg_path = MACA_MENULIST_PLUGIN_DIR . 'assets/maca-menulist-adminikon.svg';

    if (is_readable($svg_path)) {
        $svg = file_get_contents($svg_path);
        if (is_string($svg) && $svg !== '') {
            return 'data:image/svg+xml;base64,' . base64_encode($svg);
        }
    }

    return 'dashicons-food';
}

/**
 * Writable log file for activation / bootstrap errors (works without WP_DEBUG_LOG).
 *
 * @return string
 */
function maca_menulist_debug_log_path() {
    if (defined('WP_CONTENT_DIR') && is_string(WP_CONTENT_DIR) && WP_CONTENT_DIR !== '') {
        return WP_CONTENT_DIR . '/maca-restu-debug.log';
    }

    return dirname(MACA_MENULIST_PLUGIN_DIR) . '/maca-restu-debug.log';
}

/**
 * Append a line to the plugin debug log.
 *
 * @param string $message Log message.
 * @return void
 */
function maca_menulist_debug_log($message) {
    $line = gmdate('Y-m-d H:i:s') . ' UTC ' . $message . PHP_EOL;
    // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
    @file_put_contents(maca_menulist_debug_log_path(), $line, FILE_APPEND | LOCK_EX);
}

/**
 * Whether a PHP error originated from this plugin.
 *
 * @param string $file File path from error_get_last().
 * @return bool
 */
function maca_menulist_error_is_from_plugin($file) {
    if ($file === '') {
        return false;
    }

    $dir = defined('MACA_MENULIST_PLUGIN_DIR') ? (string) MACA_MENULIST_PLUGIN_DIR : '';

    if ($dir !== '' && strpos($file, $dir) === 0) {
        return true;
    }

    return strpos($file, 'maca-restu-pro') !== false || strpos($file, 'maca_menulist') !== false;
}

/**
 * Persist activation / bootstrap failure for wp-admin and the debug log file.
 *
 * @param string               $context Short context label.
 * @param string               $message Error message.
 * @param array<string, mixed> $extra   Optional extra fields.
 * @return void
 */
function maca_menulist_store_bootstrap_error($context, $message, $extra = array()) {
    $payload = array_merge(
        array(
            'context' => (string) $context,
            'message' => (string) $message,
            'time'    => gmdate('c'),
        ),
        $extra
    );

    update_option('maca_menulist_activation_fatal', $payload, false);
    maca_menulist_debug_log($context . ': ' . $message);
}

/**
 * Log fatal errors (activation hook or first load after activate).
 *
 * @return void
 */
function maca_menulist_log_plugin_fatal() {
    $error = error_get_last();

    if (!$error || !in_array((int) $error['type'], array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR), true)) {
        return;
    }

    $file = isset($error['file']) ? (string) $error['file'] : '';

    if (!maca_menulist_error_is_from_plugin($file)) {
        return;
    }

    $message = isset($error['message']) ? (string) $error['message'] : '';
    $line = isset($error['line']) ? (int) $error['line'] : 0;

    maca_menulist_store_bootstrap_error(
        'fatal',
        $message,
        array(
            'file' => $file,
            'line' => $line,
        )
    );
}

/**
 * Load plugin translations and site locale (public overview, AJAX).
 *
 * @return void
 */
function maca_menulist_ensure_dashboard_locale() {
    if (function_exists('maca_menulist_load_textdomain')) {
        maca_menulist_load_textdomain();
    }

    if (function_exists('switch_to_locale') && function_exists('determine_locale')) {
        switch_to_locale(determine_locale());
    }
}

register_shutdown_function('maca_menulist_log_plugin_fatal');

add_action('admin_notices', 'maca_menulist_render_activation_fatal_notice');
add_action('init', 'maca_menulist_run_pending_activation_setup', 1);
add_action('init', 'maca_menulist_bootstrap_pending_rewrite_flush', 99);
add_action('init', 'maca_menulist_clear_stale_activation_fatal', 100);
add_action('admin_init', 'maca_menulist_maybe_dismiss_activation_fatal_notice');
add_action('admin_init', 'maca_menulist_run_deferred_upgrade_tasks', 0);

/**
 * Remove stored activation error after a successful request (stale notice).
 *
 * @return void
 */
function maca_menulist_clear_stale_activation_fatal() {
    if (!did_action('init')) {
        return;
    }

    if (get_option('maca_menulist_pending_activation_setup') === MACA_MENULIST_VERSION) {
        return;
    }

    $fatal = get_option('maca_menulist_activation_fatal');

    if (!is_array($fatal) || empty($fatal['message'])) {
        return;
    }

    if (!function_exists('maca_menulist_rewrite_api_is_ready')) {
        require_once MACA_MENULIST_PLUGIN_DIR . 'includes/rewrites.php';
    }

    if (!maca_menulist_rewrite_api_is_ready()) {
        return;
    }

    delete_option('maca_menulist_activation_fatal');
}

/**
 * Dismiss the activation error admin notice (?maca_menulist_dismiss_fatal=1).
 *
 * @return void
 */
function maca_menulist_maybe_dismiss_activation_fatal_notice() {
    if (!current_user_can('activate_plugins')) {
        return;
    }

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Verified below.
    if (!isset($_GET['maca_menulist_dismiss_fatal'])) {
        return;
    }

    check_admin_referer('maca_menulist_dismiss_fatal');

    delete_option('maca_menulist_activation_fatal');

    wp_safe_redirect(remove_query_arg(array('maca_menulist_dismiss_fatal', '_wpnonce')));
    exit;
}

/**
 * Flush rewrite rules after activation (init only — not plugins_loaded).
 *
 * @return void
 */
function maca_menulist_bootstrap_pending_rewrite_flush() {
    if (get_option('maca_menulist_pending_rewrite_flush') !== MACA_MENULIST_VERSION) {
        return;
    }

    require_once MACA_MENULIST_PLUGIN_DIR . 'includes/rewrites.php';
    maca_menulist_run_pending_rewrite_flush();
}

/**
 * Core WP admin screens / AJAX where maca Restu should not load the full stack.
 *
 * Loading every include on plugin-install.php (and its AJAX) can break the
 * WordPress.org plugin API (timeouts, memory, or stray output).
 *
 * @return bool
 */
function maca_menulist_should_skip_heavy_bootstrap() {
    if (!is_admin()) {
        return false;
    }

    if (defined('WP_INSTALLING') && WP_INSTALLING) {
        return true;
    }

    global $pagenow;

    // Skip heavy bootstrap on plugin install/update AJAX only. Full admin pages still
    // need the admin menu (e.g. after uploading a new plugin version on update.php).
    if (is_string($pagenow) && in_array($pagenow, array('plugin-install.php', 'update.php'), true)) {
        if (defined('DOING_AJAX') && DOING_AJAX) {
            return true;
        }

        return false;
    }

    if (!defined('DOING_AJAX') || !DOING_AJAX) {
        return false;
    }

    $action = isset($_REQUEST['action']) ? sanitize_key((string) wp_unslash($_REQUEST['action'])) : '';

    if ($action === '') {
        return false;
    }

    if (strpos($action, 'maca_') === 0 || strpos($action, 'maca_menulist') === 0) {
        return false;
    }

    $core_actions = array(
        'search-install-plugins',
        'install-plugin',
        'activate-plugin',
        'update-plugin',
        'upload-plugin',
        'delete-plugin',
        'edit-plugin',
        'get-plugin-install-notices',
        'save-plugin-privacy',
        'heartbeat',
        'health-check',
    );

    if (in_array($action, $core_actions, true)) {
        return true;
    }

    if (strpos($action, 'install') !== false || strpos($action, 'plugin') !== false) {
        return true;
    }

    return false;
}

/**
 * Remove stale step-tracking options after a successful upgrade.
 *
 * @return void
 */
function maca_menulist_db_clear_migration_tracking_options() {
    delete_option('maca_menulist_db_migrate_target');
    delete_option('maca_menulist_db_migrate_completed');
    delete_transient('maca_menulist_db_migrating');
    delete_transient('maca_menulist_db_upgrade_lock');
}

/**
 * Run DB schema upgrades once after a plugin update, then stop checking.
 *
 * @return void
 */
function maca_menulist_run_db_migration_if_needed() {
    if (get_option('maca_menulist_db_version') === MACA_MENULIST_VERSION) {
        maca_menulist_db_clear_migration_tracking_options();
        return;
    }

    if (get_transient('maca_menulist_db_upgrade_lock')) {
        return;
    }

    set_transient('maca_menulist_db_upgrade_lock', '1', 90);

    if (!function_exists('maca_menulist_db_apply_pending_schema_upgrades')) {
        require_once MACA_MENULIST_PLUGIN_DIR . 'includes/db.php';
    }

    if (function_exists('set_time_limit')) {
        @set_time_limit(180);
    }

    maca_menulist_debug_log('db_migration: start → ' . MACA_MENULIST_VERSION);

    maca_menulist_db_apply_pending_schema_upgrades();
    update_option('maca_menulist_db_version', MACA_MENULIST_VERSION);
    maca_menulist_db_clear_migration_tracking_options();

    if (function_exists('maca_menulist_flush_rewrite_rules')) {
        maca_menulist_flush_rewrite_rules();
    }

    maca_menulist_debug_log('db_migration: done');
}

/**
 * Run DB / rewrite upgrade tasks on a normal admin request (not plugin-install).
 *
 * @return void
 */
function maca_menulist_run_deferred_upgrade_tasks() {
    if (maca_menulist_should_skip_heavy_bootstrap()) {
        return;
    }

    if (!function_exists('maca_menulist_flush_rewrite_rules')) {
        require_once MACA_MENULIST_PLUGIN_DIR . 'includes/rewrites.php';
    }

    $db_needs_upgrade = (get_option('maca_menulist_db_version') !== MACA_MENULIST_VERSION);

    if ($db_needs_upgrade) {
        maca_menulist_run_db_migration_if_needed();
    } else {
        maca_menulist_db_clear_migration_tracking_options();
    }

    if (get_option('maca_menulist_qr_slug') === 'meny') {
        update_option('maca_menulist_qr_slug', 'qrmeny');
        maca_menulist_flush_rewrite_rules();
    }

    if (get_option('maca_menulist_rewrite_version') !== MACA_MENULIST_VERSION) {
        update_option('maca_menulist_rewrite_version', MACA_MENULIST_VERSION);
        maca_menulist_flush_rewrite_rules();
    }

    if (!get_option('maca_menulist_https_migrated')) {
        if (function_exists('maca_menulist_migrate_http_urls')) {
            maca_menulist_migrate_http_urls();
        }
        update_option('maca_menulist_https_migrated', true);
    }

    if (!get_option('maca_menulist_credit_option_removed')) {
        delete_option('maca_menulist_qr_show_credit');
        update_option('maca_menulist_credit_option_removed', true);
    }

    if (get_option('maca_menulist_db_migrated_schedule_datetime_format_v2') !== '1') {
        require_once MACA_MENULIST_PLUGIN_DIR . 'includes/schedule.php';
        if (function_exists('maca_menulist_db_migrate_schedule_datetime_format_v2')) {
            maca_menulist_db_migrate_schedule_datetime_format_v2();
        }
    }
}

/**
 * Finish activation tasks on the first admin request (keeps activate hook lightweight).
 *
 * @return void
 */
function maca_menulist_run_pending_activation_setup() {
    if (maca_menulist_should_skip_heavy_bootstrap()) {
        return;
    }

    $pending = get_option('maca_menulist_pending_activation_setup');

    if ($pending !== MACA_MENULIST_VERSION) {
        return;
    }

    delete_option('maca_menulist_pending_activation_setup');

    maca_menulist_debug_log('pending_activation_setup: start');

    try {
        if (!function_exists('dbDelta')) {
            require_once ABSPATH . 'wp-admin/includes/upgrade.php';
        }

        require_once MACA_MENULIST_PLUGIN_DIR . 'includes/db.php';
        maca_menulist_db_create_tables();
        maca_menulist_db_apply_pending_schema_upgrades();
        update_option('maca_menulist_db_version', MACA_MENULIST_VERSION);
        maca_menulist_db_clear_migration_tracking_options();

        require_once MACA_MENULIST_PLUGIN_DIR . 'includes/db-dishes.php';
        if (function_exists('maca_menulist_db_ensure_dish_takeaway_columns')) {
            maca_menulist_db_ensure_dish_takeaway_columns();
        }
        maca_menulist_db_seed_default_allergens();

        if (!get_option('maca_menulist_qr_slug')) {
            update_option('maca_menulist_qr_slug', 'qrmeny');
        }

        update_option('maca_menulist_pending_rewrite_flush', MACA_MENULIST_VERSION);
        delete_option('maca_menulist_flush_rewrite');

        require_once MACA_MENULIST_PLUGIN_DIR . 'includes/menulist-user-access.php';
        require_once MACA_MENULIST_PLUGIN_DIR . 'includes/booking-staff-access.php';
        require_once MACA_MENULIST_PLUGIN_DIR . 'includes/booking-log.php';
        maca_menulist_register_menulist_user_access();
        maca_menulist_register_booking_host_role();
        maca_menulist_db_create_booking_log_table();

        delete_option('maca_menulist_activation_fatal');
        maca_menulist_debug_log('pending_activation_setup: done');

        $trial_banner_file = MACA_MENULIST_PLUGIN_DIR . 'includes/pro/trial-promo-banner.php';
        if (file_exists($trial_banner_file)) {
            require_once MACA_MENULIST_PLUGIN_DIR . 'includes/pro/license.php';
            require_once $trial_banner_file;
            Maca_MenuList_Pro_Trial_Promo_Banner::refresh_from_server(true);
            Maca_MenuList_Pro_Trial_Promo_Banner::bootstrap();
        }
    } catch (Throwable $e) {
        maca_menulist_store_bootstrap_error(
            'pending_activation_setup',
            $e->getMessage(),
            array(
                'file' => $e->getFile(),
                'line' => $e->getLine(),
            )
        );
    }
}

/**
 * Show stored activation fatal on the plugins screen.
 *
 * @return void
 */
function maca_menulist_render_activation_fatal_notice() {
    if (!current_user_can('activate_plugins')) {
        return;
    }

    $fatal = get_option('maca_menulist_activation_fatal');

    if (!is_array($fatal) || empty($fatal['message'])) {
        return;
    }

    $log_path = maca_menulist_debug_log_path();

    echo '<div class="notice notice-error"><p><strong>maca Restu Pro</strong> ';
    echo esc_html__('Activation or startup error:', 'maca-restu-pro');
    echo ' <code>';
    echo esc_html((string) $fatal['message']);
    if (!empty($fatal['file'])) {
        echo ' — ' . esc_html(basename((string) $fatal['file']));
        if (!empty($fatal['line'])) {
            echo ':' . esc_html((string) $fatal['line']);
        }
    }
    echo '</code></p>';
    echo '<p>';
    printf(
        /* translators: %s: absolute path to debug log file */
        esc_html__('Details are also written to %s (even when wp-content/debug.log is missing). For WordPress debug.log you need WP_DEBUG and WP_DEBUG_LOG in wp-config.php.', 'maca-restu-pro'),
        '<code>' . esc_html($log_path) . '</code>'
    );
    echo '</p><p>';
    $dismiss_url = wp_nonce_url(
        add_query_arg('maca_menulist_dismiss_fatal', '1'),
        'maca_menulist_dismiss_fatal'
    );
    echo '<a href="' . esc_url($dismiss_url) . '" class="button button-secondary">';
    esc_html_e('Dismiss this notice', 'maca-restu-pro');
    echo '</a></p></div>';
}

/**
 * Request path relative to the site home (no leading slash).
 *
 * @return string
 */
function maca_menulist_early_request_path() {
    $uri = isset($_SERVER['REQUEST_URI']) ? (string) wp_unslash($_SERVER['REQUEST_URI']) : '';
    $path = wp_parse_url($uri, PHP_URL_PATH);

    if (!is_string($path) || $path === '') {
        return '';
    }

    $path = strtolower(trim($path, '/'));
    $home_path = trim((string) wp_parse_url(home_url('/'), PHP_URL_PATH), '/');

    if ($home_path !== '' && strpos($path, $home_path) === 0) {
        $path = trim(substr($path, strlen($home_path)), '/');
    }

    if (strpos($path, 'index.php/') === 0) {
        $path = trim(substr($path, strlen('index.php/')), '/');
    }

    return $path;
}

/**
 * Whether a path ends with a staff page slug (supports language prefixes).
 *
 * @param string $path Request path.
 * @param string $slug Staff slug.
 * @return bool
 */
function maca_menulist_early_path_matches_staff_slug($path, $slug) {
    $path = strtolower(trim((string) $path, '/'));
    $slug = strtolower(trim((string) $slug, '/'));

    if ($path === '' || $slug === '') {
        return false;
    }

    if ($path === $slug) {
        return true;
    }

    if (strlen($path) <= strlen($slug) || substr($path, -strlen($slug)) !== $slug) {
        return false;
    }

    $prefix = substr($path, 0, -strlen($slug));

    return $prefix !== '' && substr($prefix, -1) === '/';
}

/**
 * Whether the current HTTP request targets a staff order page URL.
 *
 * @return bool
 */
function maca_menulist_early_is_staff_page_request() {
    $path = maca_menulist_early_request_path();
    if ($path === '') {
        return false;
    }

    $waiter_slug = (string) get_option('maca_menulist_waiter_order_slug', 'meny-servitris');
    $kitchen_slug = (string) get_option('maca_menulist_kitchen_order_slug', 'meny-kok');

    return maca_menulist_early_path_matches_staff_slug($path, $waiter_slug)
        || maca_menulist_early_path_matches_staff_slug($path, $kitchen_slug);
}

/**
 * Staff board POST action from the request body.
 *
 * @return string
 */
function maca_menulist_early_staff_post_action() {
    // phpcs:ignore WordPress.Security.NonceVerification.Missing -- PIN-protected staff API.
    if (isset($_POST['maca_staff_action'])) {
        return sanitize_key(wp_unslash($_POST['maca_staff_action']));
    }

    if (isset($_POST['action'])) {
        return sanitize_key(wp_unslash($_POST['action']));
    }

    return '';
}

/**
 * Mark staff page/API requests before guest gettext filters load.
 *
 * @return void
 */
function maca_menulist_early_detect_staff_request() {
    if (maca_menulist_early_is_staff_page_request()
        && !defined('MACA_MENULIST_STAFF_PAGE_REQUEST')) {
        define('MACA_MENULIST_STAFF_PAGE_REQUEST', true);
    }

    $action = maca_menulist_early_staff_post_action();
    $staff_actions = array(
        'maca_verify_staff_pin',
        'maca_get_staff_table_summary',
        'maca_get_staff_orders',
        'maca_handle_staff_order',
        'maca_update_staff_order_table',
        'maca_update_staff_order_status',
    );

    if ($action !== '' && in_array($action, $staff_actions, true)
        && !defined('MACA_MENULIST_STAFF_API_REQUEST')) {
        define('MACA_MENULIST_STAFF_API_REQUEST', true);
    }

    // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Session token checked later in staff API.
    if (!defined('MACA_MENULIST_STAFF_API_REQUEST')
        && isset($_POST['staff_session'])
        && sanitize_text_field(wp_unslash($_POST['staff_session'])) !== '') {
        define('MACA_MENULIST_STAFF_API_REQUEST', true);
    }
}

maca_menulist_early_detect_staff_request();

add_action('plugins_loaded', 'maca_menulist_ensure_staff_ajax_bootstrap', 1);

/**
 * Ensure staff AJAX actions always load the full plugin stack.
 *
 * @return void
 */
function maca_menulist_ensure_staff_ajax_bootstrap() {
    if (!defined('DOING_AJAX') || !DOING_AJAX) {
        return;
    }

    $action = '';
    if (isset($_REQUEST['action'])) {
        $action = sanitize_key((string) wp_unslash($_REQUEST['action']));
    } elseif (isset($_REQUEST['maca_staff_action'])) {
        $action = sanitize_key((string) wp_unslash($_REQUEST['maca_staff_action']));
    }

    $staff_actions = array(
        'maca_verify_staff_pin',
        'maca_get_staff_table_summary',
        'maca_get_staff_orders',
        'maca_handle_staff_order',
        'maca_update_staff_order_table',
        'maca_update_staff_order_status',
    );

    if ($action === '' || !in_array($action, $staff_actions, true)) {
        return;
    }

    if (class_exists('Maca_Menu_List', false)) {
        Maca_Menu_List::boot();
    }
}
