<?php

/**
 * My Account Editor Hooks
 *
 * Integrates the custom menu configuration with WooCommerce My Account.
 *
 * @package ArraySubs\Features\MyAccountEditor\Services
 * @since 1.9.0
 */

namespace ArraySubs\Features\MyAccountEditor\Services;

defined('ABSPATH') || exit;

/**
 * My Account Editor hooks integration
 */
class Hooks
{
    /**
     * Enable auto-loading via AbstractLoader.
     *
     * @var bool
     */
    public static $loadable = true;

    /**
     * When true, applyMenuConfig() returns items unchanged.
     *
     * Used by helpers that need the raw WC menu items.
     *
     * @var bool
     */
    public static $bypass_menu_filter = false;

    /**
     * Initialize hooks.
     */
    public function __construct()
    {
        // Register custom rewrite endpoints.
        add_action('init', [$this, 'registerCustomEndpoints']);

        // Add custom endpoints to WC query vars.
        add_filter('woocommerce_get_query_vars', [$this, 'addQueryVars']);

        // Reorder + inject custom items into WC My Account menu - late priority.
        add_filter('woocommerce_account_menu_items', [$this, 'applyMenuConfig'], 99);

        // Render content for custom endpoints.
        add_action('template_redirect', [$this, 'hookCustomEndpointRenderers']);

        // Prevent direct access to linked content when toggle is on.
        add_action('template_redirect', [$this, 'guardDirectAccess']);

        // Flush rewrite rules once after config changes.
        add_action('update_option_arraysubs_myaccount_menu_config', [$this, 'scheduleFlush']);
    }

    /**
     * Register custom rewrite endpoints for any custom items.
     *
     * @return void
     */
    public function registerCustomEndpoints(): void
    {
        if (!$this->isMenuItemsFeatureEnabled()) {
            return;
        }

        $custom_items = arraysubs_get_custom_myaccount_endpoints();

        foreach ($custom_items as $item) {
            if (!empty($item['endpoint']) && !empty($item['enabled'])) {
                add_rewrite_endpoint($item['endpoint'], EP_ROOT | EP_PAGES);
            }
        }
    }

    /**
     * Add custom endpoint slugs to WC query vars.
     *
     * @param array $vars Existing query vars.
     * @return array
     */
    public function addQueryVars(array $vars): array
    {
        if (!$this->isMenuItemsFeatureEnabled()) {
            return $vars;
        }

        $custom_items = arraysubs_get_custom_myaccount_endpoints();

        foreach ($custom_items as $item) {
            if (!empty($item['endpoint']) && !empty($item['enabled'])) {
                $vars[$item['endpoint']] = $item['endpoint'];
            }
        }

        return $vars;
    }

    /**
     * Apply saved menu order and custom items to WC My Account menu.
     *
     * @param array $items Current WC menu items.
     * @return array Reordered/modified menu items.
     */
    public function applyMenuConfig(array $items): array
    {
        if (self::$bypass_menu_filter || !$this->isMenuItemsFeatureEnabled()) {
            return $items;
        }

        $config = arraysubs_get_myaccount_menu_config();

        if (empty($config)) {
            return $items;
        }

        $ordered = [];

        foreach ($config as $cfg_item) {
            $id      = $cfg_item['id'] ?? '';
            $enabled = $cfg_item['enabled'] ?? true;

            if (empty($id) || !$enabled) {
                continue;
            }

            if ('default' === ($cfg_item['type'] ?? 'default')) {
                // Default WC item — use saved label or fall back to WC label.
                if (isset($items[$id])) {
                    $ordered[$id] = !empty($cfg_item['label'])
                        ? $cfg_item['label']
                        : $items[$id];
                }
            } elseif ('custom' === ($cfg_item['type'] ?? '')) {
                // Custom linked content item.
                $endpoint = $cfg_item['endpoint'] ?? '';
                if (!empty($endpoint)) {
                    $ordered[$endpoint] = !empty($cfg_item['label'])
                        ? $cfg_item['label']
                        : esc_html__('Custom Page', 'arraysubs');
                }
            }
        }

        // Append any WC items not present in config (e.g. newly added by other plugins).
        $configured_ids = array_column($config, 'id');
        foreach ($items as $key => $label) {
            if (!in_array($key, $configured_ids, true) && !isset($ordered[$key])) {
                $ordered[$key] = $label;
            }
        }

        return $ordered;
    }

    /**
     * Hook renderers for each custom endpoint.
     *
     * @return void
     */
    public function hookCustomEndpointRenderers(): void
    {
        if (!$this->isMenuItemsFeatureEnabled()) {
            return;
        }

        $custom_items = arraysubs_get_custom_myaccount_endpoints();

        foreach ($custom_items as $item) {
            if (empty($item['endpoint']) || empty($item['enabled'])) {
                continue;
            }

            $endpoint   = $item['endpoint'];
            $content_id = absint($item['content_id'] ?? 0);

            if ($content_id <= 0) {
                continue;
            }

            // Use a closure to bind the content ID.
            add_action(
                'woocommerce_account_' . $endpoint . '_endpoint',
                function () use ($content_id) {
                    $this->renderLinkedContent($content_id);
                }
            );
        }
    }

    /**
     * Render linked page/CPT content inside My Account.
     *
     * Uses a standard WP_Query loop so builder content renders correctly
     * without manually overriding WordPress globals.
     *
     * @param int $content_id Post ID of the linked content.
     * @return void
     */
    public function renderLinkedContent(int $content_id): void
    {
        $target_post = get_post($content_id);

        if (!$target_post || 'publish' !== $target_post->post_status) {
            echo '<div class="woocommerce-info">';
            echo esc_html__('This content is currently unavailable.', 'arraysubs');
            echo '</div>';
            return;
        }

        $content_query = new \WP_Query([
            'post_type'              => $target_post->post_type,
            'p'                      => $content_id,
            'post_status'            => 'publish',
            'posts_per_page'         => 1,
            'ignore_sticky_posts'    => true,
            'no_found_rows'          => true,
            'update_post_meta_cache' => false,
            'update_post_term_cache' => false,
        ]);

        if (!$content_query->have_posts()) {
            echo '<div class="woocommerce-info">';
            echo esc_html__('This content is currently unavailable.', 'arraysubs');
            echo '</div>';
            return;
        }

        $content_query->the_post();

        echo '<div class="arraysubs-myaccount-custom-content">';
        the_content();
        echo '</div>';

        wp_reset_postdata();
    }

    /**
     * Guard direct access to pages/CPTs that have prevent_direct_access enabled.
     *
     * Redirects to the My Account endpoint instead.
     *
     * @return void
     */
    public function guardDirectAccess(): void
    {
        if (!$this->isMenuItemsFeatureEnabled()) {
            return;
        }

        if (is_admin() || wp_doing_ajax() || wp_doing_cron()) {
            return;
        }

        if (!is_singular()) {
            return;
        }

        $current_post_id = get_queried_object_id();

        if ($current_post_id <= 0) {
            return;
        }

        $custom_items = arraysubs_get_custom_myaccount_endpoints();

        foreach ($custom_items as $item) {
            $content_id = absint($item['content_id'] ?? 0);

            if ($content_id !== $current_post_id) {
                continue;
            }

            if (empty($item['prevent_direct_access'])) {
                continue;
            }

            if (empty($item['enabled'])) {
                continue;
            }

            $endpoint = $item['endpoint'] ?? '';

            if (empty($endpoint)) {
                continue;
            }

            // Redirect to the My Account endpoint.
            $myaccount_url = wc_get_account_endpoint_url($endpoint);

            if (!empty($myaccount_url)) {
                wp_safe_redirect($myaccount_url);
                exit;
            }
        }
    }

    /**
     * Schedule a rewrite rules flush when the config is updated.
     *
     * @return void
     */
    public function scheduleFlush(): void
    {
        arraysubs_schedule_myaccount_editor_flush();
    }

    /**
     * Check whether My Account menu item customization is enabled.
     *
     * @return bool
     */
    private function isMenuItemsFeatureEnabled(): bool
    {
        return function_exists('arraysubs_is_myaccount_menu_items_enabled')
            ? arraysubs_is_myaccount_menu_items_enabled()
            : true;
    }
}
