<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ — NUCLEAR+++
// File: /includes/class-ai-provider-sync.php
// Description: Syncs AI provider credentials to Core API on activate/deactivate - NUCLEAR+++
// Last Edited: 2026-05-24
// ==================================================

namespace AutoMarketerAI;

defined('ABSPATH') || exit;

final class AiProviderSync
{
    // Maps WP module IDs to Core provider names
    private const PROVIDER_MAP = [
        'ai-claude'  => 'claude',
        'ai-openai'  => 'openai',
        'ai-gemini'  => 'gemini',
        'ai-grok'    => 'grok',
        'ai-mistral' => 'mistral',
    ];

    // Send provider key + model to Core for encrypted storage.
    // Called after WP has saved the key to wp_options during activation.
    // Returns true on success, false on failure — caller decides whether to surface the error.
    public static function store(string $wp_provider_id, string $api_key, string $model): bool
    {
        $provider = self::PROVIDER_MAP[$wp_provider_id] ?? '';
        if ($provider === '') {
            return false;
        }

        $body = (string) json_encode([
            'provider' => $provider,
            'api_key'  => $api_key,
            'model'    => $model,
        ]);

        $response = self::signedRequest('POST', '/api/tenant/ai-provider', $body);

        return $response === 200;
    }

    // Remove provider credentials from Core.
    // Called when user deactivates a provider on the Modules page.
    // Returns true on success, false on failure.
    public static function remove(string $wp_provider_id): bool
    {
        $provider = self::PROVIDER_MAP[$wp_provider_id] ?? '';
        if ($provider === '') {
            return false;
        }

        $body     = (string) json_encode([]);
        $response = self::signedRequest('DELETE', '/api/tenant/ai-provider', $body);

        return $response === 200;
    }

    // Send an HMAC-signed request to Core and return the HTTP status code.
    // Returns 0 on connection failure.
    private static function signedRequest(string $method, string $path, string $body): int
    {
        if (!defined('AMAI_CORE_URL') || AMAI_CORE_URL === '') {
            return 0;
        }

        $url       = rtrim(AMAI_CORE_URL, '/') . $path;
        $timestamp = (string) time();
        $nonce     = bin2hex(random_bytes(16));
        $tenant    = amai_tenant_id();
        $key_id    = 'WP_PROXY';

        $raw_secret = (string) get_option('amai_tenant_hmac_secret', '');
        if ($raw_secret === '') {
            return 0;
        }
        $secret    = hex2bin($raw_secret);
        $body_b64  = base64_encode(hash('sha256', $body, true));
        $canonical = implode('|', [$method, $path, $timestamp, $nonce, $tenant, $key_id, $body_b64]);
        $signature = rtrim(base64_encode(hash_hmac('sha256', $canonical, $secret, true)), "\n");

        $args = [
            'method'  => $method,
            'timeout' => 15,
            'headers' => [
                'Content-Type'       => 'application/json',
                'X-Amai-Tenant'      => $tenant,
                'X-Amai-Key-Id'      => $key_id,
                'X-Amai-Timestamp'   => $timestamp,
                'X-Amai-Nonce'       => $nonce,
                'X-Amai-Body-SHA256' => $body_b64,
                'X-Amai-Signature'   => $signature,
            ],
            'body' => $body,
        ];

        $response = wp_remote_request($url, $args);

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

        return (int) wp_remote_retrieve_response_code($response);
    }

    // Fetch the canonical provider model list from Core.
    // Returns array keyed by Core provider name on success, empty array on failure.
    // Failures are silent -- callers fall back to local module data.
    public static function fetchModels(): array
    {
        [$status, $body] = self::signedRequestWithBody('GET', '/api/providers/models', '');
        if ($status !== 200 || $body === '') {
            return [];
        }
        $decoded = json_decode($body, true);
        if (!is_array($decoded) || !isset($decoded['providers']) || !is_array($decoded['providers'])) {
            return [];
        }
        return $decoded['providers'];
    }

    // Fetch the canonical image provider model list from Core.
    // Returns array keyed by Core image provider name on success, empty array on failure.
    // Failures are silent -- callers fall back to local module data.
    public static function fetchImageModels(): array
    {
        [$status, $body] = self::signedRequestWithBody('GET', '/api/providers/image-models', '');
        if ($status !== 200 || $body === '') {
            return [];
        }
        $decoded = json_decode($body, true);
        if (!is_array($decoded) || !isset($decoded['providers']) || !is_array($decoded['providers'])) {
            return [];
        }
        return $decoded['providers'];
    }

    // Send an HMAC-signed request to Core and return [http_status, response_body].
    // Returns [0, ''] on connection failure.
    private static function signedRequestWithBody(string $method, string $path, string $body): array
    {
        if (!defined('AMAI_CORE_URL') || AMAI_CORE_URL === '') {
            return [0, ''];
        }

        $url        = rtrim(AMAI_CORE_URL, '/') . $path;
        $timestamp  = (string) time();
        $nonce      = bin2hex(random_bytes(16));
        $tenant     = amai_tenant_id();
        $key_id     = 'WP_PROXY';

        $raw_secret = (string) get_option('amai_tenant_hmac_secret', '');
        if ($raw_secret === '') {
            return [0, ''];
        }
        $secret    = hex2bin($raw_secret);
        $body_b64  = base64_encode(hash('sha256', $body, true));
        $canonical = implode('|', [$method, $path, $timestamp, $nonce, $tenant, $key_id, $body_b64]);
        $signature = rtrim(base64_encode(hash_hmac('sha256', $canonical, $secret, true)), "\n");

        $args = [
            'method'  => $method,
            'timeout' => 15,
            'headers' => [
                'Content-Type'       => 'application/json',
                'X-Amai-Tenant'      => $tenant,
                'X-Amai-Key-Id'      => $key_id,
                'X-Amai-Timestamp'   => $timestamp,
                'X-Amai-Nonce'       => $nonce,
                'X-Amai-Body-SHA256' => $body_b64,
                'X-Amai-Signature'   => $signature,
            ],
            'body' => $body,
        ];

        $response = wp_remote_request($url, $args);

        if (is_wp_error($response)) {
            return [0, ''];
        }

        return [
            (int) wp_remote_retrieve_response_code($response),
            (string) wp_remote_retrieve_body($response),
        ];
    }
}