<?php

namespace App\Modules\Sms\Plivo;

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

/**
 * PRC-107 — Plivo SMS provider.
 *
 * Settings:
 *   auth_id, auth_token, from, default_country_code (opsiyonel)
 */
class Plivo extends AbstractSms
{
    public function sendSms(array $params): array
    {
        $to = $params['to'] ?? null;
        $content = $params['content'] ?? null;
        if (! $to || ! $content) {
            return ['success' => false, 'error' => 'Required fields missing (to, content)'];
        }
        if ($this->isTestMode) {
            Log::info('Plivo TEST SMS', ['to' => $to]);

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

        $authId = $this->getConfig('auth_id');
        $authToken = $this->getConfig('auth_token');
        $from = $this->getConfig('from');
        if (! $authId || ! $authToken || ! $from) {
            return ['success' => false, 'error' => 'Plivo configuration incomplete'];
        }

        try {
            $resp = Http::withBasicAuth($authId, $authToken)
                ->timeout(30)
                ->post("https://api.plivo.com/v1/Account/{$authId}/Message/", [
                    'src' => $from,
                    'dst' => $this->normalizeMsisdn($to, $this->getConfig('default_country_code')),
                    'text' => $content,
                ]);

            // Plivo accept'te HTTP 202 döner. HTTP başarısı TEK BAŞINA yeterli değil:
            // gövdedeki message_uuid yoksa (ya da hata yapısı varsa) başarı sayma.
            if (! $resp->successful()) {
                return ['success' => false, 'error' => 'Plivo HTTP '.$resp->status()];
            }

            $data = $resp->json();

            // Gövde-statüsü ile gate: bir hata mesajı varsa (ör. geçersiz numara / kredi)
            // Plivo 'error' alanı döndürebilir.
            if (isset($data['error']) && $data['error'] !== null && $data['error'] !== '') {
                return ['success' => false, 'error' => 'Plivo rejected the message'];
            }

            $messageId = $data['message_uuid'][0] ?? ($data['message_uuid'] ?? null);
            if (! $messageId) {
                // message_id UYDURMA — Plivo mesaj kabulünü doğrulamadı.
                return ['success' => false, 'error' => 'Plivo did not return a message_uuid'];
            }

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

    public function testConnection(array $params): array
    {
        $authId = $params['auth_id'] ?? $this->getConfig('auth_id');
        $authToken = $params['auth_token'] ?? $this->getConfig('auth_token');
        if (! $authId || ! $authToken) {
            return ['success' => false, 'message' => 'auth_id/auth_token required'];
        }

        try {
            $resp = Http::withBasicAuth($authId, $authToken)->timeout(15)
                ->get("https://api.plivo.com/v1/Account/{$authId}/");

            if ($resp->successful()) {
                return ['success' => true, 'message' => 'Plivo connection OK'];
            }

            // 401 = kimlik doğrulama başarısız (yanlış auth_id/token).
            if ($resp->status() === 401) {
                return ['success' => false, 'message' => 'Plivo authentication failed (check auth_id/auth_token)'];
            }

            return ['success' => false, 'message' => 'Plivo HTTP '.$resp->status()];
        } catch (\Throwable $e) {
            return ['success' => false, 'message' => 'Plivo connection error'];
        }
    }

    /**
     * Plivo Delivery Report (DLR) webhook payload'unu normalize eder.
     *
     * Plivo, Message URL'ine POST ile şu alanları gönderir:
     *   MessageUUID, Status (queued|sent|delivered|undelivered|rejected|failed), ...
     * Bkz: https://www.plivo.com/docs/sms/api/message#delivery-report
     *
     * @return array{provider_message_id: string, status: 'delivered'|'failed', detail: ?string}|null
     */
    public function handleDeliveryReport(array $payload): ?array
    {
        // Plivo PascalCase gönderir; olası küçük harf varyantlarını da kapsa.
        $messageId = $payload['MessageUUID']
            ?? $payload['message_uuid']
            ?? $payload['MessageUuid']
            ?? null;
        $rawStatus = $payload['Status']
            ?? $payload['status']
            ?? null;

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

        $normalized = strtolower((string) $rawStatus);
        $status = $normalized === 'delivered' ? 'delivered' : 'failed';

        return [
            'provider_message_id' => (string) $messageId,
            'status' => $status,
            'detail' => $normalized,
        ];
    }

    public function getFeatures(): array
    {
        // handleDeliveryReport GERÇEKTEN implemente edildi → delivery_reports=true.
        return array_merge(parent::getFeatures(), [
            'delivery_reports' => true,
        ]);
    }

    public function getRequiredConfigFields(): array
    {
        return ['auth_id', 'auth_token', 'from'];
    }

    public function getConfigFields(): array
    {
        return [
            'auth_id' => ['type' => 'text', 'label' => 'Plivo Auth ID', 'required' => true],
            'auth_token' => ['type' => 'password', 'label' => 'Plivo Auth Token', 'required' => true, 'encrypted' => true],
            'from' => ['type' => 'text', 'label' => 'Sender Number / Short Code', 'required' => true],
            'default_country_code' => ['type' => 'text', 'label' => 'Default Country Code (e.g. 1, 44)', 'required' => false],
            'test_mode' => ['type' => 'boolean', 'label' => 'Test Mode', 'default' => true],
        ];
    }
}
