<?php

namespace FleekDash\Services;

class ResponseService
{
    /**
     * Cache TTL in seconds (1 hour default)
     */
    const DEFAULT_CACHE_TTL = 3600;

    /**
     * Returns a success response (flexible signature)
     * Usage A: success($data)
     * Usage B: success($message, $data)
     */
    public static function success($arg1 = '', $arg2 = [], $cache_ttl = null)
    {
        $message = '';
        $data = [];

        // If first argument is array/object → treat as data
        if (is_array($arg1) || is_object($arg1)) {
            $data = $arg1;
            $message = '';
        } elseif (is_string($arg1)) {
            // If first is string and second is array/object → (message, data)
            $message = $arg1;
            $data = (is_array($arg2) || is_object($arg2)) ? $arg2 : [];
        }

        $response = [
            'success' => true,
            'message' => $message,
            'data' => $data,
        ];

        // Apply caching if TTL is provided
        if (!is_null($cache_ttl)) {
            self::cacheResponse(self::generateCacheKey(), $response, $cache_ttl);
        }

        return \rest_ensure_response($response);
    }

    /**
     * Returns an error response as WP_REST_Response (REST API compatible).
     * Uses rest_ensure_response() so WP_Error is converted to proper REST format.
     *
     * @return \WP_REST_Response
     */
    public static function error($message, $errors = null, $code = 400)
    {
        $wp_error = new \WP_Error(
            'fleekdash_error',
            $message,
            [
                'status' => $code,
                'errors' => $errors
            ],
        );
        return \rest_ensure_response($wp_error);
    }

    /**
     * Generates a cache key based on current request
     */
    private static function generateCacheKey()
    {
        return 'fleekdash_api_' . md5(
            $_SERVER['REQUEST_URI'] .
            json_encode($_GET) .
            \get_current_user_id()
        );
    }

    /**
     * Caches the response
     */
    private static function cacheResponse($key, $data, $ttl)
    {
        wp_cache_set($key, $data, 'fleekdash_api', $ttl);
    }

    /**
     * Gets cached response
     */
    public static function getCachedResponse($key = null)
    {
        $key = $key ?? self::generateCacheKey();
        return wp_cache_get($key, 'fleekdash_api');
    }

    /**
     * Returns a paginated success response
     * $pagination should include keys: current_page, per_page, total, total_pages
     */
    public static function paginate($items, $pagination = [], $cache_ttl = null)
    {
        $itemsCount = is_array($items) ? count($items) : 0;
        $perPage = isset($pagination['per_page']) ? (int) $pagination['per_page'] : $itemsCount;
        $total = isset($pagination['total']) ? (int) $pagination['total'] : $itemsCount;

        $payload = [
            'success' => true,
            'data' => is_array($items) ? $items : [],
            'pagination' => [
                'current_page' => isset($pagination['current_page']) ? (int) $pagination['current_page'] : 1,
                'per_page' => $perPage,
                'total' => $total,
                'total_pages' => isset($pagination['total_pages']) ? (int) $pagination['total_pages'] : 1,
            ],
        ];

        if (!is_null($cache_ttl)) {
            self::cacheResponse(self::generateCacheKey(), $payload, $cache_ttl);
        }

        return \rest_ensure_response($payload);
    }

    /**
     * Common no-cache headers for dynamic endpoints that must not be cached.
     * Prevents browser from caching responses that change frequently.
     */
    private const NO_CACHE_HEADERS = [
        'Cache-Control'     => 'no-store, no-cache, must-revalidate, max-age=0',
        'Pragma'            => 'no-cache',
        'Expires'           => '0',
        'Surrogate-Control' => 'no-store',
    ];

    /**
     * Apply strict no-cache headers to a REST response.
     * Use this for endpoints that return dynamic data that changes frequently
     * (e.g., language installation status, download progress, etc.)
     *
     * @param \WP_REST_Response $response The REST response object
     * @return \WP_REST_Response Response with no-cache headers applied
     */
    public static function withNoCacheHeaders($response)
    {
        if (!($response instanceof \WP_REST_Response)) {
            return $response;
        }

        foreach (self::NO_CACHE_HEADERS as $header => $value) {
            $response->header($header, $value);
        }

        return $response;
    }
}
