<?php

namespace App\Modules\Sms\WhatsAppBusiness;

use App\Core\Sms\AbstractSms;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class WhatsAppBusiness extends AbstractSms
{
    public function sendSms(array $params): array
    {
        $to = $params['to'] ?? null;
        $content = $params['content'] ?? null;
        $templateName = $params['metadata']['template_name'] ?? null;
        $templateLanguage = $params['metadata']['template_language'] ?? 'en';
        $templateComponents = $params['metadata']['template_components'] ?? [];

        if (! $to) {
            return ['success' => false, 'error' => 'Required field missing (to)'];
        }

        if (! $templateName && ! $content) {
            return ['success' => false, 'error' => 'Either template_name or content is required'];
        }

        if ($this->isTestMode) {
            Log::info('WhatsApp Business TEST message', [
                'to' => $to,
                'content' => $content,
                'template' => $templateName,
            ]);

            return ['success' => true, 'message_id' => 'test_whatsapp_' . uniqid()];
        }

        try {
            $phoneNumberId = $this->getConfig('phone_number_id');
            $accessToken = $this->getConfig('access_token');

            if (empty($phoneNumberId) || empty($accessToken)) {
                return ['success' => false, 'error' => 'WhatsApp Business configuration is incomplete'];
            }

            $url = "https://graph.facebook.com/v18.0/{$phoneNumberId}/messages";

            if ($templateName) {
                $payload = $this->buildTemplatePayload($to, $templateName, $templateLanguage, $templateComponents);
            } else {
                $payload = $this->buildTextPayload($to, $content);
            }

            $response = Http::withHeaders([
                'Authorization' => "Bearer {$accessToken}",
                'Content-Type' => 'application/json',
            ])->post($url, $payload);

            $data = $response->json();

            // HTTP 2xx TEK BAŞINA yeterli değil: Meta Cloud API başarı gövdesinde
            // messages[0].id döner. Bu alan yoksa (ör. queued-only/hata yapısı)
            // başarıyı UYDURMA — message_id fabricate etmek yerine success:false.
            $messageId = $data['messages'][0]['id'] ?? null;

            if ($response->successful() && $messageId) {
                Log::info('WhatsApp message sent successfully', ['to' => $to, 'id' => $messageId]);

                return ['success' => true, 'message_id' => $messageId];
            }

            // Gövdeden güvenli hata mesajı çıkar (ham gövde/token loglama).
            $apiError = $data['error']['message'] ?? 'Unexpected WhatsApp API response';
            Log::error('WhatsApp Business API failed', ['to' => $to, 'error' => $apiError]);

            return ['success' => false, 'error' => 'WhatsApp API error: ' . $apiError];
        } catch (\Throwable $e) {
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    public function testConnection(array $params): array
    {
        try {
            $phoneNumberId = $this->getConfig('phone_number_id');
            $accessToken = $this->getConfig('access_token');

            if (empty($phoneNumberId) || empty($accessToken)) {
                throw new \Exception('WhatsApp phone_number_id and access_token are required');
            }

            $url = "https://graph.facebook.com/v18.0/{$phoneNumberId}";

            $response = Http::withHeaders([
                'Authorization' => "Bearer {$accessToken}",
            ])->get($url);

            if ($response->successful()) {
                return ['success' => true, 'message' => 'WhatsApp Business API connection successful'];
            }

            // Ham gövde (token/hesap detayı içerebilir) döndürme; sadece Graph
            // error mesajını çıkar.
            $apiError = $response->json('error.message') ?? 'Connection failed';

            return ['success' => false, 'error' => $apiError];
        } catch (\Throwable $e) {
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    public function getConfigFields(): array
    {
        return [
            'phone_number_id' => ['type' => 'text', 'label' => 'Phone Number ID', 'required' => true],
            'access_token' => ['type' => 'password', 'label' => 'Access Token', 'required' => true],
            'business_account_id' => ['type' => 'text', 'label' => 'Business Account ID', 'required' => false],
            'default_country_code' => ['type' => 'text', 'label' => 'Default Country Code (dial code, e.g. 90)', 'required' => false],
            'test_mode' => ['type' => 'boolean', 'label' => 'Test Mode', 'default' => true],
        ];
    }

    public function getFeatures(): array
    {
        return [
            'single_sms' => false,
            'whatsapp' => true,
            'template_messaging' => true,
            // handleDeliveryReport GERÇEKTEN implemente edilmiştir (Meta webhook
            // statuses[] parse) — bu yüzden true dürüsttür.
            'delivery_reports' => true,
            'test_mode' => true,
            'unicode' => true,
        ];
    }

    /**
     * Meta WhatsApp Cloud API webhook status callback'ini normalize eder.
     *
     * Meta gövdesi: entry[].changes[].value.statuses[] — her statü:
     *  { id, status: 'sent'|'delivered'|'read'|'failed', ... }.
     * İlk statü nesnesini kanonik forma indirger; 'delivered'/'read' → delivered,
     * 'failed' → failed, diğerleri (sent/queued) DLR sayılmaz (null).
     *
     * NOT: Webhook doğrulaması (X-Hub-Signature-256) çağıran katmanın işidir;
     * bu metod yalnız zaten-doğrulanmış payload'u parse eder.
     *
     * @return array{provider_message_id: string, status: 'delivered'|'failed', detail: ?string}|null
     */
    public function handleDeliveryReport(array $payload): ?array
    {
        $statuses = $payload['entry'][0]['changes'][0]['value']['statuses']
            ?? $payload['statuses']
            ?? null;

        if (! is_array($statuses) || empty($statuses)) {
            return null;
        }

        $status = $statuses[0];
        $providerMessageId = $status['id'] ?? null;
        $rawStatus = $status['status'] ?? null;

        if (! $providerMessageId || ! $rawStatus) {
            return null;
        }

        $canonical = match ($rawStatus) {
            'delivered', 'read' => 'delivered',
            'failed' => 'failed',
            default => null, // sent/queued vb. terminal DLR değil
        };

        if ($canonical === null) {
            return null;
        }

        $detail = $status['errors'][0]['title']
            ?? $status['errors'][0]['message']
            ?? $rawStatus;

        return [
            'provider_message_id' => (string) $providerMessageId,
            'status' => $canonical,
            'detail' => $detail !== null ? (string) $detail : null,
        ];
    }

    protected function getModuleLabel(): string
    {
        return 'WhatsApp Business';
    }

    protected function getModuleDescription(): string
    {
        return 'WhatsApp Business Cloud API (Meta)';
    }

    private function buildTemplatePayload(string $to, string $templateName, string $language, array $components): array
    {
        $payload = [
            'messaging_product' => 'whatsapp',
            'to' => $this->formatPhoneNumber($to),
            'type' => 'template',
            'template' => [
                'name' => $templateName,
                'language' => ['code' => $language],
            ],
        ];

        if (! empty($components)) {
            $payload['template']['components'] = $components;
        }

        return $payload;
    }

    /**
     * Serbest-metin (type:text) gövdesi. DİKKAT: Meta politikası gereği serbest
     * metin YALNIZCA müşterinin son mesajından itibaren 24 saatlik oturum
     * penceresi içinde teslim edilir; pencere dışında Meta mesajı REDDEDER
     * (bu durumda sendSms gövde-statüsünden gerçek hatayı döndürür, sahte-başarı
     * üretmez). Pencere dışı bildirimler onaylı şablonla (template) gönderilmelidir.
     */
    private function buildTextPayload(string $to, string $content): array
    {
        return [
            'messaging_product' => 'whatsapp',
            'to' => $this->formatPhoneNumber($to),
            'type' => 'text',
            'text' => ['body' => $content],
        ];
    }

    /**
     * WhatsApp E.164 (salt-rakam, '+' hariç) numara ister. Ülke kodunu HARDCODE
     * etmeden AbstractSms::normalizeMsisdn'e delege eder; varsayılan arama kodu
     * modül-config'ten (default_country_code) okunur, yoksa null geçilir
     * (helper uydurma ülke kodu eklemez — girdi zaten uluslararası varsayılır).
     */
    private function formatPhoneNumber(string $phone): string
    {
        $defaultDialCode = $this->getConfig('default_country_code') ?: null;

        return $this->normalizeMsisdn($phone, $defaultDialCode);
    }
}
