<?php

declare(strict_types=1);

namespace FleekDash\Frontend;

use FleekDash\Traits\Base;
use FleekDash\Traits\RemoveAdminBar;

/**
 * FleekPages - Pseudo-pages system based on query string
 *
 * Allows accessing templates via ?fleekpage={template-slug}
 * Example: ?fleekpage=login, ?fleekpage=frontend
 */
class FleekPages
{
    use Base;
    use RemoveAdminBar;

    const QUERY_PARAM = 'fleekpage';
    const TEMPLATE_DIR = 'views/';
    const TEMPLATES_DIR = 'views/templates/';

    /**
     * Template mapping: slug => template file
     *
     * @var array<string, string>
     */
    private array $templateMap = [
        'login' => 'login-template.php',
        'frontend' => 'templates/frontend-template.php',
    ];

    /**
     * Bootstrap the FleekPages system
     */
    public function bootstrap(): void
    {
        // Hook into template_include to load the template (primary method)
        // Priority 100 (higher than Login.php and Template.php which use 99)
        // This ensures FleekPages executes first when ?fleekpage=login is present
        \add_filter('template_include', [$this, 'loadFleekpageTemplate'], 100);

        // Enqueue assets when fleekpage is detected
        \add_action('wp_enqueue_scripts', [$this, 'maybeEnqueueFleekpageAssets'], 1);

        // Remove admin bar when fleekpage is detected (especially for login)
        \add_action('template_redirect', [$this, 'maybeRemoveAdminBar'], 1);
    }

    /**
     * Remove admin bar if fleekpage is detected
     *
     * Note: Only FleekPages (custom templates like login) remove admin bar.
     * Regular frontend pages show admin bar normally for logged-in users.
     */
    public function maybeRemoveAdminBar(): void
    {
        if (isset($_GET[self::QUERY_PARAM])) {
            $template_slug = \sanitize_text_field((string) $_GET[self::QUERY_PARAM]);
            // Remove admin bar for login page and other fleekpages
            if ($template_slug !== '') {
                $this->remove_admin_bar_on_page();
            }
        }
    }

    /**
     * Load fleekpage template via template_include filter
     *
     * @param string $template Current template path
     */
    public function loadFleekpageTemplate(string $template): string
    {
        $template_slug = $this->resolveFleekpageSlugFromRequest();
        if ($template_slug === null) {
            return $template;
        }

        $template_path = $this->getTemplatePath($template_slug);

        if ($template_path !== null && \file_exists($template_path)) {
            $this->applyFleekpageQueryFixes();

            return $template_path;
        }

        return $template;
    }

    private function resolveFleekpageSlugFromRequest(): ?string
    {
        if (!isset($_GET[self::QUERY_PARAM])) {
            return null;
        }

        $raw = \sanitize_text_field((string) $_GET[self::QUERY_PARAM]);

        return $raw !== '' ? $raw : null;
    }

    private function applyFleekpageQueryFixes(): void
    {
        global $wp_query;
        if (!$wp_query->is_404) {
            return;
        }

        $wp_query->is_404 = false;
        $wp_query->is_page = true;
        $wp_query->is_singular = true;
        $wp_query->is_home = false;
        $wp_query->is_front_page = false;
        // Set a dummy post to ensure wp_head() and wp_footer() work correctly
        if (empty($wp_query->posts)) {
            $wp_query->posts = [];
            $wp_query->post_count = 0;
        }
    }

    /**
     * Enqueue assets for fleekpage templates
     */
    public function maybeEnqueueFleekpageAssets(): void
    {
        if (!isset($_GET[self::QUERY_PARAM])) {
            return;
        }

        $template_slug = \sanitize_text_field((string) $_GET[self::QUERY_PARAM]);

        if ($template_slug === '') {
            return;
        }

        $this->maybeEnqueueAssets($template_slug);
    }

    /**
     * Get template file path for a given slug
     *
     * @return string|null Template path or null if not found
     */
    private function getTemplatePath(string $template_slug): ?string
    {
        // Check if slug is in our mapping
        if (isset($this->templateMap[$template_slug])) {
            $template_file = $this->templateMap[$template_slug];

            // If template file starts with 'templates/', use TEMPLATES_DIR
            // Otherwise, use TEMPLATE_DIR
            if (strpos($template_file, 'templates/') === 0) {
                $path = \FLEEKDASH_DIR . self::TEMPLATES_DIR . basename($template_file);
            } else {
                $path = \FLEEKDASH_DIR . self::TEMPLATE_DIR . $template_file;
            }

            if (\file_exists($path)) {
                return $path;
            }
        }

        // Try direct lookup: {slug}-template.php
        $direct_paths = [
            \FLEEKDASH_DIR . self::TEMPLATE_DIR . $template_slug . '-template.php',
            \FLEEKDASH_DIR . self::TEMPLATES_DIR . $template_slug . '-template.php',
            \FLEEKDASH_DIR . self::TEMPLATE_DIR . $template_slug . '.php',
            \FLEEKDASH_DIR . self::TEMPLATES_DIR . $template_slug . '.php',
        ];

        foreach ($direct_paths as $path) {
            if (\file_exists($path)) {
                return $path;
            }
        }

        return null;
    }

    /**
     * Enqueue assets for specific templates if needed
     */
    private function maybeEnqueueAssets(string $template_slug): void
    {
        // Enqueue login assets if it's the login template
        if ($template_slug === 'login') {
            $login = new Login();
            $login->enqueueLoginAssets();
        }
    }

    /**
     * Get URL for a fleekpage
     *
     * @param array<string, mixed> $additional_params Additional query parameters
     */
    public static function getUrl(string $template_slug, array $additional_params = []): string
    {
        $params = array_merge(
            [self::QUERY_PARAM => $template_slug],
            $additional_params
        );

        return \add_query_arg($params, \home_url('/'));
    }

    /**
     * Register a new template mapping
     *
     * @param string $template_file Template file path (relative to views/)
     */
    public function registerTemplate(string $slug, string $template_file): void
    {
        $this->templateMap[$slug] = $template_file;
    }
}
