<?php

namespace FleekDash\Services;

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

class ServiceWorkerService
{
    private const MSG_NOT_FOUND = 'Service worker not found';

    private const MSG_LOAD_FAILED = 'Failed to load service worker';

    public function __construct()
    {
        // Register AJAX handlers (admin and public)
        \add_action('wp_ajax_fleekdash_sw', [$this, 'serveServiceWorker']);
        \add_action('wp_ajax_nopriv_fleekdash_sw', [$this, 'serveServiceWorker']);

        // MIGRATED TO V2.2: FeaturesRoutes (Phase 4.2)
        // REST API endpoint now registered via FeaturesRoutes
        // \add_action('rest_api_init', [$this, 'registerRestEndpoints']);

        // Register direct endpoint for Service Worker
        \add_action('init', [$this, 'registerDirectEndpoint']);

        // Register rewrite rule for Service Worker
        \add_action('init', [$this, 'addRewriteRules']);
        \add_filter('query_vars', [$this, 'addQueryVars']);
        \add_action('template_redirect', [$this, 'handleServiceWorkerRequest']);
    }

    /**
     * Serve the service worker script with the proper headers so it can control /wp-admin/.
     */
    public function serveServiceWorker(): void
    {
        // Path to the bundled service worker within the plugin
        $base_dir = rtrim(\FLEEKDASH_DIR, "\\/");
        $sw_path = $base_dir . '/public/sw.js';

        if (!file_exists($sw_path)) {
            http_response_code(404);
            header('Content-Type: text/plain; charset=utf-8');
            echo self::MSG_NOT_FOUND;
            // Use wp_die() instead of exit() to avoid redirect issues
            wp_die(self::MSG_NOT_FOUND, 'Not Found', ['response' => 404]);
        }

        // Read file contents
        $contents = file_get_contents($sw_path);
        if ($contents === false) {
            http_response_code(500);
            header('Content-Type: text/plain; charset=utf-8');
            echo self::MSG_LOAD_FAILED;
            wp_die(self::MSG_LOAD_FAILED, 'Server Error', ['response' => 500]);
        }

        // Ensure correct headers
        header('Content-Type: application/javascript; charset=utf-8');
        // Allow the service worker to control the admin scope
        header('Service-Worker-Allowed: /');
        // Avoid caching to make updates easier during development; adjust if needed
        header('Cache-Control: no-cache, no-store, must-revalidate');
        header('Pragma: no-cache');
        header('Expires: 0');

        echo $contents;
        wp_die('', '', ['response' => 200]);
    }

    /**
     * Register REST API endpoints for Service Worker
     */
    public function registerRestEndpoints(): void
    {
        \register_rest_route('fleekdash/v1', '/service-worker', [
            'methods' => 'GET',
            'callback' => [$this, 'serveServiceWorkerRest'],
            'permission_callback' => [$this, 'allowPublicServiceWorker'],
        ]);
    }

    public function allowPublicServiceWorker(): bool
    {
        return true;
    }

    /**
     * Serve Service Worker via REST API
     */
    public function serveServiceWorkerRest(): \WP_REST_Response
    {
        // Path to the bundled service worker within the plugin
        $base_dir = rtrim(\FLEEKDASH_DIR, "\\/");
        $sw_path = $base_dir . '/public/sw.js';

        if (!file_exists($sw_path)) {
            return new \WP_REST_Response(self::MSG_NOT_FOUND, 404);
        }

        // Read file contents
        $contents = file_get_contents($sw_path);
        if ($contents === false) {
            return new \WP_REST_Response(self::MSG_LOAD_FAILED, 500);
        }

        // Create response with proper headers - use data property to avoid JSON encoding
        $response = new \WP_REST_Response($contents, 200);
        $response->set_data($contents);
        $response->header('Content-Type', 'application/javascript; charset=utf-8');
        $response->header('Service-Worker-Allowed', '/');
        $response->header('Cache-Control', 'no-cache, no-store, must-revalidate');
        $response->header('Pragma', 'no-cache');
        $response->header('Expires', '0');

        return $response;
    }

    /**
     * Register direct endpoint for Service Worker
     */
    public function registerDirectEndpoint(): void
    {
        // Check if this is a request for the service worker
        if (isset($_GET['fleekdash_sw']) && $_GET['fleekdash_sw'] === '1') {
            $this->serveServiceWorker();
        }
    }

    /**
     * Add rewrite rules for Service Worker
     */
    public function addRewriteRules(): void
    {
        add_rewrite_rule('^fleekdash-sw\.js$', 'index.php?fleekdash_service_worker=1', 'top');
    }

    /**
     * Add query vars for Service Worker
     *
     * @param string[] $vars
     */
    public function addQueryVars(array $vars): array
    {
        $vars[] = 'fleekdash_service_worker';

        return $vars;
    }

    /**
     * Handle Service Worker request
     */
    public function handleServiceWorkerRequest(): void
    {
        if (get_query_var('fleekdash_service_worker') === '1') {
            $this->serveServiceWorker();
        }
    }
}
