<?php

namespace CleantalkSP\SpbctWP\VulnerabilityAlarm;

use WP_Error;

class PscCertifiedPluginsApi
{
    const API_URL = 'https://api-research.cleantalk.org/search_general';

    const PER_PAGE = 10;

    const CATALOG_LIST_PARAMS = 'id,slug,app_status,app_name,psc,publication_date,rs_app_version_min,rs_app_version_max';

    /**
     * @param int $page
     * @param int|null $limit
     * @param string|null $list_params
     * @return array{items: array<int, array<string, mixed>>, total: int}|WP_Error
     */
    public static function fetchPage($page = 1, $limit = null, $list_params = null)
    {
        $page = max(1, (int) $page);
        $limit = $limit ?? self::PER_PAGE;
        $list_params = $list_params ?? 'slug,publication_date,app_name,psc,app_status';

        $body = wp_json_encode([
            'psc_like'    => 'PSC',
            'app_status' => 'safe_psc',
            'list_params' => $list_params,
            'limit'       => (int) $limit,
            'page'        => $page,
        ]);

        if ($body === false) {
            return new WP_Error('spbc_psc_api_encode', __('Failed to encode API request.', 'security-malware-firewall'));
        }

        $response = wp_remote_post(self::API_URL, [
            'timeout' => 20,
            'headers' => [
                'Content-Type' => 'application/json',
            ],
            'body' => $body,
        ]);

        if (is_wp_error($response)) {
            return $response;
        }

        $code = (int) wp_remote_retrieve_response_code($response);
        if ($code < 200 || $code >= 300) {
            return new WP_Error(
                'spbc_psc_api_http',
                sprintf(
                    /* translators: %d: HTTP status code */
                    __('PSC catalog API request failed with HTTP code %d.', 'security-malware-firewall'),
                    $code
                )
            );
        }

        $decoded = json_decode(wp_remote_retrieve_body($response), true);
        if (! is_array($decoded)) {
            return new WP_Error(
                'spbc_psc_api_decode',
                __('Invalid PSC catalog API response.', 'security-malware-firewall')
            );
        }

        if (! empty($decoded['error_no'])) {
            $message = ! empty($decoded['error_message'])
                ? sanitize_text_field((string) $decoded['error_message'])
                : __('PSC catalog API returned an error.', 'security-malware-firewall');

            return new WP_Error('spbc_psc_api_error', $message);
        }

        $search_result = $decoded['data']['search_result'] ?? [];
        if (! is_array($search_result)) {
            $search_result = [];
        }

        $total = isset($decoded['data']['counts']) ? (int) $decoded['data']['counts'] : count($search_result);

        return [
            'items' => $search_result,
            'total' => $total,
        ];
    }

    /**
     * Fetch all PSC catalog items in a single request.
     *
     * @return array{items: array<int, array<string, mixed>>, total: int}|WP_Error
     */
    public static function fetchAll()
    {
        return self::fetchPage(1, 500, self::CATALOG_LIST_PARAMS);
    }
}
