<?php

declare(strict_types=1);

namespace App\Framework\Notification\Channels\WhatsApp;

use App\Framework\Core\ValueObjects\PhoneNumber;
use App\Framework\Http\Headers;
use App\Framework\Http\Method;
use App\Framework\HttpClient\ClientRequest;
use App\Framework\HttpClient\HttpClient;
use App\Framework\Notification\Channels\WhatsApp\ValueObjects\WhatsAppMessageId;
use App\Framework\Notification\Channels\WhatsApp\ValueObjects\WhatsAppTemplateId;

/**
 * WhatsApp Business API client
 *
 * Handles communication with WhatsApp Business API using framework's HttpClient
 */
final readonly class WhatsAppClient
{
    public function __construct(
        private HttpClient $httpClient,
        private WhatsAppConfig $config
    ) {
    }

    /**
     * Send a text message
     */
    public function sendTextMessage(PhoneNumber $to, string $message): WhatsAppResponse
    {
        $payload = [
            'messaging_product' => 'whatsapp',
            'to' => $to->toString(),
            'type' => 'text',
            'text' => [
                'body' => $message,
            ],
        ];

        return $this->sendRequest($payload);
    }

    /**
     * Send a template message
     *
     * @param PhoneNumber $to Recipient phone number
     * @param WhatsAppTemplateId $templateId Template name
     * @param string $languageCode Language code (e.g., 'en_US', 'de_DE')
     * @param array<string> $parameters Template parameters
     */
    public function sendTemplateMessage(
        PhoneNumber $to,
        WhatsAppTemplateId $templateId,
        string $languageCode,
        array $parameters = []
    ): WhatsAppResponse {
        $components = [];

        if (!empty($parameters)) {
            $components[] = [
                'type' => 'body',
                'parameters' => array_map(
                    fn ($value) => ['type' => 'text', 'text' => $value],
                    $parameters
                ),
            ];
        }

        $payload = [
            'messaging_product' => 'whatsapp',
            'to' => $to->toString(),
            'type' => 'template',
            'template' => [
                'name' => $templateId->toString(),
                'language' => [
                    'code' => $languageCode,
                ],
                'components' => $components,
            ],
        ];

        return $this->sendRequest($payload);
    }

    /**
     * Send request to WhatsApp API using HttpClient
     */
    private function sendRequest(array $payload): WhatsAppResponse
    {
        // Create JSON request with Authorization header
        $request = ClientRequest::json(
            method: Method::POST,
            url: $this->config->getMessagesEndpoint(),
            data: $payload
        );

        // Add Authorization header
        $headers = $request->headers->with('Authorization', 'Bearer ' . $this->config->accessToken);

        // Update request with new headers
        $request = new ClientRequest(
            method: $request->method,
            url: $request->url,
            headers: $headers,
            body: $request->body,
            options: $request->options
        );

        $response = $this->httpClient->send($request);

        if (!$response->isSuccessful()) {
            $data = $response->isJson() ? $response->json() : [];
            $errorMessage = $data['error']['message'] ?? 'Unknown error';
            $errorCode = $data['error']['code'] ?? 0;

            throw new WhatsAppApiException(
                "WhatsApp API error ({$errorCode}): {$errorMessage}",
                $response->status->value
            );
        }

        // Parse successful response
        $data = $response->json();
        $messageId = $data['messages'][0]['id'] ?? null;

        if ($messageId === null) {
            throw new \RuntimeException('WhatsApp API response missing message ID');
        }

        return new WhatsAppResponse(
            success: true,
            messageId: WhatsAppMessageId::fromString($messageId),
            rawResponse: $data
        );
    }
}
