<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class GreenApiService
{
    public function enabled(): bool
    {
        return (bool) config('greenapi.enabled');
    }

    public function sendMessage(string $chatIdOrPhone, string $message): ?array
    {
        if (! $this->enabled()) {
            return null;
        }

        $idInstance = config('greenapi.id_instance');
        $token = config('greenapi.api_token_instance');
        $apiUrl = config('greenapi.api_url');

        if (empty($idInstance) || empty($token) || empty($apiUrl)) {
            Log::warning('GREENAPI is enabled but credentials are missing');
            return null;
        }

        $chatId = $this->toChatId($chatIdOrPhone);

        if (empty($chatId)) {
            Log::warning('GREENAPI sendMessage skipped: invalid chatId/phone', ['input' => $chatIdOrPhone]);
            return null;
        }

        $url = "{$apiUrl}/waInstance{$idInstance}/sendMessage/{$token}";

        try {
            $resp = Http::timeout(8)->connectTimeout(3)->asJson()->post($url, [
                'chatId' => $chatId,
                'message' => $message,
            ]);

            if (! $resp->successful()) {
                Log::error('GREENAPI sendMessage failed', [
                    'status' => $resp->status(),
                    'body' => $resp->body(),
                    'chatId' => $chatId,
                ]);
                return null;
            }

            return $resp->json();
        } catch (\Throwable $e) {
            Log::error('GREENAPI sendMessage exception', ['error' => $e->getMessage()]);
            return null;
        }
    }


    /**
     * Send WhatsApp message after the HTTP response is sent, so form submits and
     * step changes do not wait for GREEN-API and the frontend does not freeze.
     */
    public function sendMessageAfterResponse(string $chatIdOrPhone, string $message): void
    {
        try {
            dispatch(function () use ($chatIdOrPhone, $message) {
                app(self::class)->sendMessage($chatIdOrPhone, $message);
            })->afterResponse();
        } catch (\Throwable $e) {
            Log::error('GREENAPI sendMessageAfterResponse dispatch failed', ['error' => $e->getMessage()]);
        }
    }

    public function receiveNotification(int $timeoutSeconds = 5): ?array
    {
        if (! $this->enabled()) {
            return null;
        }

        $idInstance = config('greenapi.id_instance');
        $token = config('greenapi.api_token_instance');
        $apiUrl = config('greenapi.api_url');

        if (empty($idInstance) || empty($token) || empty($apiUrl)) {
            return null;
        }

        $timeoutSeconds = max(5, min(60, $timeoutSeconds));
        $url = "{$apiUrl}/waInstance{$idInstance}/receiveNotification/{$token}?receiveTimeout={$timeoutSeconds}";

        try {
            $resp = Http::timeout($timeoutSeconds + 10)->get($url);

            if (! $resp->successful()) {
                Log::error('GREENAPI receiveNotification failed', [
                    'status' => $resp->status(),
                    'body' => $resp->body(),
                ]);
                return null;
            }

            // When queue is empty, API can return null / empty response
            $json = $resp->json();
            return $json ?: null;
        } catch (\Throwable $e) {
            Log::error('GREENAPI receiveNotification exception', ['error' => $e->getMessage()]);
            return null;
        }
    }

    public function deleteNotification(int $receiptId): ?array
    {
        if (! $this->enabled()) {
            return null;
        }

        $idInstance = config('greenapi.id_instance');
        $token = config('greenapi.api_token_instance');
        $apiUrl = config('greenapi.api_url');

        if (empty($idInstance) || empty($token) || empty($apiUrl)) {
            return null;
        }

        $url = "{$apiUrl}/waInstance{$idInstance}/deleteNotification/{$token}/{$receiptId}";

        try {
            $resp = Http::timeout(8)->connectTimeout(3)->delete($url);

            if (! $resp->successful()) {
                Log::error('GREENAPI deleteNotification failed', [
                    'status' => $resp->status(),
                    'body' => $resp->body(),
                    'receiptId' => $receiptId,
                ]);
                return null;
            }

            return $resp->json();
        } catch (\Throwable $e) {
            Log::error('GREENAPI deleteNotification exception', ['error' => $e->getMessage()]);
            return null;
        }
    }

    /**
     * Convert a phone (017..., +880..., 880...) or chatId to chatId format used by Green-API: 88017...@c.us
     */
    public function toChatId(string $chatIdOrPhone): string
    {
        $s = trim($chatIdOrPhone);

        if ($s === '') {
            return '';
        }

        // If already a WhatsApp chatId format
        if (str_contains($s, '@c.us') || str_contains($s, '@g.us')) {
            return $s;
        }

        // Keep digits only
        $digits = preg_replace('/\D+/', '', $s);
        if (empty($digits)) {
            return '';
        }

        $defaultCC = preg_replace('/\D+/', '', (string) config('greenapi.default_country_code', ''));
        if ($defaultCC === '') {
            $defaultCC = '880';
        }

        // If starts with 0 (common local format), replace leading 0 with country code
        if (str_starts_with($digits, '0')) {
            $digits = $defaultCC . ltrim($digits, '0');
        }

        // If begins with "00" international format, drop it (00CC.... -> CC....)
        if (str_starts_with($digits, '00')) {
            $digits = substr($digits, 2);
        }

        return $digits . '@c.us';
    }
}
