<?php
/**
 * AJAX Route Handler
 *
 * @package ZenoChatbot\Framework\Http
 */

namespace ZenoChatbot\Framework\Http;

// Prevent direct access
use ZenoChatbot\App;

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

/**
 * AJAX Route Handler Class
 */
class Ajax {

    /**
     * Application instance
     *
     * @var \ZenoChatbot\Framework\Foundation\Application
     */
    private static $app;

    /**
     * Registered AJAX routes
     *
     * @var array
     */
    private static $routes = [];

    /**
     * Current route being registered
     *
     * @var array
     */
    private static $currentRoute;

    /**
     * Set application instance
     *
     * @param \ZenoChatbot\Framework\Foundation\Application $app
     */
    public static function setApp($app) {
        static::$app = $app;
    }

    /**
     * Register an AJAX route
     *
     * @param string $action
     * @param string|callable $callback
     * @return static::
     */
    public static function register($action, $callback) {

        static::$currentRoute = [
            'action' => $action,
            'callback' => $callback,
            'secure' => false,
            'public' => true
        ];

        return new static();
    }

    /**
     * Make the route secure (logged-in users only)
     *
     * @return static::
     */
    public function secure() {

        if (static::$currentRoute) {
            static::$currentRoute['secure'] = true;
            static::$currentRoute['public'] = false;
        }

        static::registerRoute();
        return $this;
    }

    /**
     * Make the route public (both logged-in and non-logged-in users)
     *
     * @return static
     */
    public function public() {

        if (static::$currentRoute) {
            static::$currentRoute['secure'] = false;
            static::$currentRoute['public'] = true;
        }

        static::registerRoute();
        return $this;
    }

    /**
     * Register the current route with WordPress
     */
    private static function registerRoute() {

        if (!static::$currentRoute) {
            return;
        }

        $route = static::$currentRoute;
        $action = $route['action'];
        $callback = $route['callback'];

        // Create the WordPress callback that captures the application instance
        $app = static::$app;
        $wpCallback = function() use ($callback, $app) {
            // Set request type for proper response handling
            $app->setRequestType('ajax');
            static::handleAjaxRequest($callback, $app);
        };

        // Register with WordPress AJAX hooks
        if ($route['secure']) {
            // Only for logged-in users
            add_action("wp_ajax_{$action}", $wpCallback);
        } else {
            // For both logged-in and non-logged-in users
            add_action("wp_ajax_{$action}", $wpCallback);
            add_action("wp_ajax_nopriv_{$action}", $wpCallback);
        }

        // Store the route
        static::$routes[$action] = $route;

        // Clear the current route
        static::$currentRoute = null;
    }

    /**
     * Handle AJAX request
     *
     * @param string|callable $callback
     * @param \ZenoChatbot\Framework\Foundation\Application $app
     */
    private static function handleAjaxRequest($callback, $app) {


        if(!static::isValidNonce()) {
            wp_die('Security check failed', 'Security Error', ['response' => 403]);
        }

        try {

            if (is_string($callback) && strpos($callback, '@') !== false) {
                // Handle Controller@method format
                list($controller, $method) = explode('@', $callback);

                // Resolve controller through application container
                $controllerInstance = $app->make($controller);

                if (!method_exists($controllerInstance, $method)) {
                    wp_die("Method {$method} not found in {$controller}", 'Method Not Found', ['response' => 404]);
                }

                // Call the method
                call_user_func([$controllerInstance, $method]);

            } elseif (is_callable($callback)) {
                // Handle direct callable - pass app instance
                call_user_func($callback, $app);

            } else {
                wp_die('Invalid callback format', 'Invalid Callback', ['response' => 500]);
            }

        } catch (\Throwable $e) {
            // Handle exceptions for AJAX requests
            $status = 500;
            error_log('[ZenoChatbot][AJAX] Unhandled exception: ' . $e->getMessage());

            // Send JSON error response
            wp_send_json_error([
                'message' => 'Something went wrong. Please try again.',
                'error' => 'internal_error'
            ], $status);
        }
    }

    /**
     * Get all registered routes
     *
     * @return array
     */
    public static function getRoutes() {
        return static::$routes;
    }

    /**
     * Clear all routes
     */
    public static function clearRoutes() {
        static::$routes = [];
        static::$currentRoute = null;
    }

    /**
     * Check if the route exists
     *
     * @param string $action
     * @return bool
     */
    public static function hasRoute($action) {
        return isset(static::$routes[$action]);
    }

    /**
     * Get route by action
     *
     * @param string $action
     * @return array|null
     */
    public static function getRoute($action) {
        return static::$routes[$action] ?? null;
    }

    public static function isValidNonce()
    {
        $request = App::make('request');
        return wp_verify_nonce($request->input('zenochatbot_nonce'), 'zenochatbot_nonce');
    }

    public static function registerAjaxRoutes()
    {
        Ajax::clearRoutes();
        $routeConfig = static::$app->getRouteConfig();
        if (isset($routeConfig['ajax'])) {
            require_once static::$app->basePath($routeConfig['ajax']);
        }
    }
}
