<?php

namespace App\Services;

use App\Models\Setting;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Log;

class SendSmsService
{
    protected Client $client;

    public function __construct()
    {
        $this->client = new Client([
            'timeout' => 10,
            'verify' => public_path('cacert.pem'),
        ]);
    }

    public function send(
        string $mobile,
        string $message,
        ?string $templateId = null,
        ?string $variablesValues = null,
        ?string $templateIdentifier = null
    ): bool {
        $apiKey = Setting::get('sms_fast2sms_api_key');
        if (!$apiKey) {
            Log::warning('SMS skipped: API key not configured', [
                'template' => $templateIdentifier,
            ]);

            return false;
        }

        $smsUrl = Setting::get('sms_fast2sms_url', 'https://www.fast2sms.com/dev/bulkV2');
        $sender = Setting::get('sms_fast2sms_sender', 'KIYO');
        $route = Setting::get('sms_fast2sms_route', 'q');

        $templateId = $templateId !== null ? trim((string) $templateId) : '';
        $templateId = $templateId !== '' ? $templateId : null;

        $requiresTemplateId = $this->gatewayRequiresTemplateId($smsUrl);

        if ($requiresTemplateId && $templateId === null) {
            Log::warning('SMS skipped: Kiyo gateway requires DLT template_id on the SMS template', [
                'sms_url_host' => parse_url((string) $smsUrl, PHP_URL_HOST),
                'template' => $templateIdentifier,
                'hint' => 'Admin > SMS Templates > set Template ID for this event',
            ]);

            return false;
        }

        if ($requiresTemplateId && $templateId !== null) {
            if ($route === 'q') {
                $route = 'dlt';
            }

            if ($variablesValues === null || trim($variablesValues) === '') {
                Log::warning('SMS skipped: Kiyo DLT requires variables_values', [
                    'template' => $templateIdentifier,
                    'template_id' => $templateId,
                ]);

                return false;
            }
        }

        $normalizedMobile = $this->normalizeIndianMobile($mobile);
        if ($normalizedMobile === '') {
            Log::warning('SMS skipped: invalid mobile number', ['mobile' => $mobile]);

            return false;
        }

        $params = [
            'route' => $route,
            'sender_id' => $sender,
            'message' => $message,
            'language' => 'english',
            'flash' => 0,
            'numbers' => $normalizedMobile,
        ];

        if ($templateId !== null) {
            $params['template_id'] = $templateId;
        }

        if ($variablesValues !== null && trim($variablesValues) !== '') {
            $params['variables_values'] = $variablesValues;
        }
        try {
            $response = $this->client->post($smsUrl, [
                'headers' => [
                    'authorization' => $apiKey,
                ],
                'form_params' => $params,
            ]);

            $result = json_decode($response->getBody()->getContents(), true);

            Log::info('SMS sent', [
                'mobile' => $normalizedMobile,
                'template' => $templateIdentifier,
                'route' => $route,
                'response' => $result,
            ]);

            if (!($result['return'] ?? false)) {
                Log::warning('SMS provider returned failure', ['result' => $result]);

                return false;
            }

            return true;
        } catch (\Throwable $e) {
            Log::warning('SMS HTTP request failed', [
                'mobile' => $normalizedMobile,
                'template' => $templateIdentifier,
                'template_id' => $templateId,
                'route' => $route,
                'error' => $e->getMessage(),
            ]);

            return false;
        }
    }

    /**
     * Build pipe-separated DLT variable values in placeholder order from the template body.
     */
    public function buildVariablesValues(string $body, array $replacements): ?string
    {
        if (!preg_match_all('/\[\[([^\]]+)\]\]/', $body, $matches)) {
            return null;
        }

        $values = [];
        foreach ($matches[1] as $key) {
            $placeholder = '[[' . $key . ']]';
            $values[] = (string) ($replacements[$placeholder] ?? '');
        }

        return implode('|', $values);
    }

    public function normalizeIndianMobile(string $mobile): string
    {
        $mobile = preg_replace('/\D+/', '', $mobile);
        if (!$mobile) {
            return '';
        }

        if (str_starts_with($mobile, '91') && strlen($mobile) > 10) {
            $mobile = substr($mobile, -10);
        }

        return strlen($mobile) >= 10 ? substr($mobile, -10) : '';
    }

    public function gatewayRequiresTemplateId(?string $smsUrl = null): bool
    {
        $smsUrl = $smsUrl ?? Setting::get('sms_fast2sms_url', 'https://www.fast2sms.com/dev/bulkV2');

        return str_contains(strtolower((string) $smsUrl), 'kiyosolutions');
    }
}
