<?php

namespace App\Services;

use App\Models\SystemSetting;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class SmsService
{
    protected ?string $username;
    protected ?string $password;
    protected ?string $senderNumber;
    protected bool $enabled;

    public function __construct()
    {
        $this->loadSettings();
    }

    /**
     * Load SMS settings from database.
     */
    protected function loadSettings(): void
    {
        // تنظیمات پیامک سراسری (فقط vendor_id = null)
        $settings = SystemSetting::withoutVendorScope()
            ->whereNull('vendor_id')
            ->whereIn('key', [
                'sms_enabled',
                'sms_melipayamak_username',
                'sms_melipayamak_password',
                'sms_sender_number',
            ])->pluck('value', 'key');

        $this->enabled = filter_var($settings->get('sms_enabled', 'false'), FILTER_VALIDATE_BOOLEAN);
        $this->username = $settings->get('sms_melipayamak_username');
        $this->password = $settings->get('sms_melipayamak_password');
        $this->senderNumber = $settings->get('sms_sender_number');
    }

    /**
     * Check if SMS service is properly configured.
     */
    public function isConfigured(): bool
    {
        return $this->enabled 
            && !empty($this->username) 
            && !empty($this->password) 
            && !empty($this->senderNumber);
    }

    /**
     * Send SMS to a single recipient.
     */
    public function send(string $to, string $message): array
    {
        if (!$this->isConfigured()) {
            return [
                'success' => false,
                'message' => 'سرویس پیامک پیکربندی نشده است',
            ];
        }

        // Normalize phone number
        $to = $this->normalizePhoneNumber($to);
        
        if (!$to) {
            return [
                'success' => false,
                'message' => 'شماره موبایل نامعتبر است',
            ];
        }

        try {
            $response = Http::timeout(30)->post('https://rest.payamak-panel.com/api/SendSMS/SendSMS', [
                'username' => $this->username,
                'password' => $this->password,
                'to' => $to,
                'from' => $this->senderNumber,
                'text' => $message,
                'isFlash' => false,
            ]);

            $data = $response->json();
            
            // Melipayamak returns RecId > 0 on success
            if (isset($data['RecId']) && $data['RecId'] > 0) {
                Log::info('SMS sent successfully', [
                    'to' => $to,
                    'rec_id' => $data['RecId'],
                ]);

                return [
                    'success' => true,
                    'rec_id' => $data['RecId'],
                    'message' => 'پیامک با موفقیت ارسال شد',
                ];
            }

            // Log error
            Log::warning('SMS sending failed', [
                'to' => $to,
                'response' => $data,
            ]);

            return [
                'success' => false,
                'message' => $this->getErrorMessage($data['RetStatus'] ?? -1),
                'error_code' => $data['RetStatus'] ?? -1,
            ];
        } catch (\Exception $e) {
            Log::error('SMS service error', [
                'to' => $to,
                'error' => $e->getMessage(),
            ]);

            return [
                'success' => false,
                'message' => 'خطا در ارتباط با سرویس پیامک',
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * Send SMS using pattern/template (for transactional messages).
     */
    public function sendPattern(string $to, string $patternCode, array $patternValues): array
    {
        if (!$this->isConfigured()) {
            return [
                'success' => false,
                'message' => 'سرویس پیامک پیکربندی نشده است',
            ];
        }

        $to = $this->normalizePhoneNumber($to);
        
        if (!$to) {
            return [
                'success' => false,
                'message' => 'شماره موبایل نامعتبر است',
            ];
        }

        try {
            // Build pattern text from values
            $patternText = implode(';', array_values($patternValues));

            $response = Http::timeout(30)->post('https://rest.payamak-panel.com/api/SendSMS/BaseServiceNumber', [
                'username' => $this->username,
                'password' => $this->password,
                'to' => $to,
                'text' => $patternText,
                'bodyId' => $patternCode,
            ]);

            $data = $response->json();
            
            if (isset($data['RecId']) && $data['RecId'] > 0) {
                Log::info('Pattern SMS sent successfully', [
                    'to' => $to,
                    'pattern_code' => $patternCode,
                    'rec_id' => $data['RecId'],
                ]);

                return [
                    'success' => true,
                    'rec_id' => $data['RecId'],
                    'message' => 'پیامک با موفقیت ارسال شد',
                ];
            }

            Log::warning('Pattern SMS sending failed', [
                'to' => $to,
                'pattern_code' => $patternCode,
                'response' => $data,
            ]);

            return [
                'success' => false,
                'message' => $this->getErrorMessage($data['RetStatus'] ?? -1),
                'error_code' => $data['RetStatus'] ?? -1,
            ];
        } catch (\Exception $e) {
            Log::error('Pattern SMS service error', [
                'to' => $to,
                'pattern_code' => $patternCode,
                'error' => $e->getMessage(),
            ]);

            return [
                'success' => false,
                'message' => 'خطا در ارتباط با سرویس پیامک',
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * Send SMS to multiple recipients.
     */
    public function sendBulk(array $recipients, string $message): array
    {
        $results = [];
        
        foreach ($recipients as $to) {
            $results[$to] = $this->send($to, $message);
        }

        return $results;
    }

    /**
     * Get credit balance.
     */
    public function getCredit(): array
    {
        if (!$this->isConfigured()) {
            return [
                'success' => false,
                'message' => 'سرویس پیامک پیکربندی نشده است',
            ];
        }

        try {
            $response = Http::timeout(30)->post('https://rest.payamak-panel.com/api/SendSMS/GetCredit', [
                'username' => $this->username,
                'password' => $this->password,
            ]);

            $data = $response->json();
            
            if (isset($data['Value'])) {
                return [
                    'success' => true,
                    'credit' => $data['Value'],
                ];
            }

            return [
                'success' => false,
                'message' => 'خطا در دریافت اعتبار',
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'خطا در ارتباط با سرویس پیامک',
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * Normalize phone number to Iranian format.
     */
    protected function normalizePhoneNumber(?string $phone): ?string
    {
        if (empty($phone)) {
            return null;
        }

        // Remove all non-digit characters
        $phone = preg_replace('/\D/', '', $phone);

        // Handle different formats
        if (str_starts_with($phone, '98') && strlen($phone) === 12) {
            // Already in 98... format
            return $phone;
        }

        if (str_starts_with($phone, '09') && strlen($phone) === 11) {
            // Convert 09... to 989...
            return '98' . substr($phone, 1);
        }

        if (str_starts_with($phone, '9') && strlen($phone) === 10) {
            // Convert 9... to 989...
            return '98' . $phone;
        }

        // Invalid format
        return null;
    }

    /**
     * Get human-readable error message.
     */
    protected function getErrorMessage(int $code): string
    {
        return match ($code) {
            0 => 'نام کاربری یا رمز عبور اشتباه است',
            1 => 'ارسال موفقیت آمیز بود',
            2 => 'اعتبار کافی نیست',
            3 => 'محدودیت در ارسال روزانه',
            4 => 'محدودیت در حجم ارسال',
            5 => 'شماره فرستنده نامعتبر است',
            6 => 'سامانه در حال بروزرسانی است',
            7 => 'متن حاوی کلمه فیلتر شده است',
            9 => 'ارسال از طریق وب سرویس امکان پذیر نیست',
            10 => 'کاربر مورد نظر یافت نشد',
            11 => 'پارامترها ناقص است',
            12 => 'حساب کاربری غیر فعال است',
            default => 'خطای نامشخص در ارسال پیامک',
        };
    }
}
