<?php

declare(strict_types=1);

namespace FecaMailshots\WordPress;

final class ProductionWordPressFacade implements WordPressFacade
{
    public function addAction(string $hook, callable $callback): void
    {
        add_action($hook, $this->guardCallback($callback, $hook));
    }

    public function addMenuPage(string $pageTitle, string $menuTitle, string $capability, string $slug, callable $callback): void
    {
        add_menu_page($pageTitle, $menuTitle, $capability, $slug, $this->guardCallback($callback, 'admin_page_' . $slug), 'dashicons-email-alt', 58);
    }

    public function addSubmenuPage(string $parentSlug, string $pageTitle, string $menuTitle, string $capability, string $slug, callable $callback): void
    {
        add_submenu_page($parentSlug, $pageTitle, $menuTitle, $capability, $slug, $this->guardCallback($callback, 'admin_page_' . $slug));
    }

    public function currentUserCan(string $capability): bool
    {
        return current_user_can($capability);
    }

    public function verifyNonce(string $nonce, string $action): bool
    {
        return wp_verify_nonce($nonce, $action) === 1;
    }

    public function createNonce(string $action): string
    {
        return (string) wp_create_nonce($action);
    }

    public function requestParam(string $name, ?string $default = null): ?string
    {
        if (isset($_POST[$name])) {
            return $this->normalizeRequestValue($_POST[$name]);
        }
        if (isset($_GET[$name])) {
            return $this->normalizeRequestValue($_GET[$name]);
        }
        return $default;
    }

    /** @param mixed $value */
    private function normalizeRequestValue($value): string
    {
        if (!function_exists('wp_unslash')) {
            throw new \RuntimeException('WordPress function wp_unslash is unavailable in ProductionWordPressFacade.');
        }
        return (string) wp_unslash($value);
    }

    public function sendJson(array $payload, int $statusCode = 200): void
    {
        status_header($statusCode);
        wp_send_json($payload);
    }

    public function adminUrl(string $path = ''): string
    {
        return admin_url($path);
    }

    public function currentUserId(): int
    {
        return (int) get_current_user_id();
    }

    public function getOption(string $name, $default = null)
    {
        return get_option($name, $default);
    }

    public function updateOption(string $name, $value): bool
    {
        return (bool) update_option($name, $value);
    }

    public function deleteOption(string $name): bool
    {
        return (bool) delete_option($name);
    }

    private function guardCallback(callable $callback, string $context): callable
    {
        return function (...$args) use ($callback, $context) {
            try {
                return $callback(...$args);
            } catch (\Throwable $e) {
                $message = 'Mailshots plugin error: ' . $e->getMessage();
                error_log($message);
                if (strpos($context, 'admin_post_') === 0 || strpos($context, 'rest_api_init') === 0) {
                    $this->sendJson(['ok' => false, 'errors' => [$message]], 500);
                    return null;
                }
                echo '<div class="wrap feca-mailshots-admin">';
                echo '<div class="notice notice-error"><p>' . htmlspecialchars($message, ENT_QUOTES) . '</p></div>';
                echo '</div>';
                return null;
            }
        };
    }
}
