<?php

namespace App\Core;

use PDO;
use Throwable;

class WhatsApp
{
    private PDO $db;
    private bool $enabled = false;
    private string $provider = 'meta_cloud_api';
    private string $apiUrl = '';
    private string $fromNumber = '';
    private string $accessToken = '';
    private string $instanceId = '';

    public function __construct(PDO $db, array $config)
    {
        $this->db = $db;

        $this->enabled = (bool)($config['enabled'] ?? false);
        $this->provider = (string)($config['provider'] ?? 'meta_cloud_api');
        $this->apiUrl = (string)($config['api_url'] ?? '');
        $this->fromNumber = (string)($config['from_number'] ?? '');
        $this->accessToken = (string)($config['access_token'] ?? '');
        $this->instanceId = (string)($config['instance_id'] ?? '');

        $this->loadSettingsOverrides();
    }

    private ?string $paymentLink = null;
    private ?string $paymentNumber = null;

    private function loadSettingsOverrides(): void
    {
        try {
            $tid = (int)Tenant::id();
            $stmt = $this->db->prepare(
                'SELECT setting_key, setting_value FROM settings WHERE tenant_id = ? AND setting_key IN ("whatsapp_enabled","whatsapp_provider","whatsapp_api_url","whatsapp_from_number","whatsapp_access_token","whatsapp_instance_id","payment_link","payment_number")'
            );
            $stmt->execute([$tid]);
            foreach ($stmt->fetchAll() as $row) {
                $key = $row['setting_key'];
                $value = (string)$row['setting_value'];
                if ($key === 'whatsapp_enabled') {
                    $this->enabled = $value === '1';
                } elseif ($key === 'whatsapp_provider') {
                    $this->provider = in_array($value, ['ultramsg', 'meta_cloud_api'], true) ? $value : 'meta_cloud_api';
                } elseif ($key === 'whatsapp_api_url') {
                    $this->apiUrl = $value;
                } elseif ($key === 'whatsapp_from_number') {
                    $this->fromNumber = $value;
                } elseif ($key === 'whatsapp_access_token') {
                    $this->accessToken = $value;
                } elseif ($key === 'whatsapp_instance_id') {
                    $this->instanceId = $value;
                } elseif ($key === 'payment_link') {
                    $this->paymentLink = $value !== '' ? $value : null;
                } elseif ($key === 'payment_number') {
                    $this->paymentNumber = $value !== '' ? $value : null;
                }
            }
        } catch (Throwable $e) {
        }
    }

    public function createNotificationForOrder(int $orderId, int $patientId): void
    {
        try {
            // تجنب إرسال أكثر من رسالة واحدة لكل طلب (عند اعتماد عدة فحوصات)
            $chk = $this->db->prepare('SELECT id FROM whatsapp_notifications WHERE order_id = ? AND status IN ("sent","pending") LIMIT 1');
            $chk->execute([$orderId]);
            if ($chk->fetch()) {
                return;
            }

            $stmt = $this->db->prepare(
                'SELECT o.order_number, p.full_name, p.phone
                 FROM lab_orders o
                 JOIN patients p ON p.id = o.patient_id
                 WHERE o.id = :order_id AND p.id = :patient_id'
            );
            $stmt->execute([
                'order_id' => $orderId,
                'patient_id' => $patientId
            ]);
            $row = $stmt->fetch();
            if (!$row) {
                return;
            }

            $phone = $this->normalizePhone(trim((string)$row['phone']));
            if ($phone === '') {
                return;
            }

            $message = 'تم اعتماد نتائج فحوصاتك رقم ' .
                (string)$row['order_number'] .
                ' في المختبر. شكرا لثقتك بنا.';
            $resultsLink = $this->getDirectResultsLink($orderId);
            if ($resultsLink !== '') {
                $message .= "\nعرض نتائجك مباشرة: " . $resultsLink;
            }

            $stmt = $this->db->prepare(
                'INSERT INTO whatsapp_notifications
                 (order_id, patient_id, phone, message, status, created_at)
                 VALUES (:order_id, :patient_id, :phone, :message, :status, NOW())'
            );
            $stmt->execute([
                'order_id' => $orderId,
                'patient_id' => $patientId,
                'phone' => $phone,
                'message' => $message,
                'status' => $this->enabled ? 'pending' : 'pending'
            ]);

            $notificationId = (int)$this->db->lastInsertId();

            if ($this->enabled) {
                $this->sendNow($notificationId, $phone, $message);
            }
        } catch (Throwable $e) {
        }
    }

    private function normalizePhone(string $phone): string
    {
        $digits = preg_replace('/\D/', '', $phone);
        if (strlen($digits) < 8) return '';
        if (strlen($digits) === 10 && substr($digits, 0, 1) === '0') {
            $digits = '964' . substr($digits, 1);
        } elseif (strlen($digits) === 11 && substr($digits, 0, 2) === '07') {
            $digits = '964' . substr($digits, 1);
        } elseif (strlen($digits) === 9 && substr($digits, 0, 1) === '7') {
            $digits = '964' . $digits;
        }
        return '+' . $digits;
    }

    /** رابط مباشر لعرض النتائج بدون بحث أو تسجيل دخول */
    private function getDirectResultsLink(int $orderId): string
    {
        try {
            $db = $this->db;
            $db->query('SELECT id FROM report_share_links LIMIT 1');

            $stmt = $db->prepare('SELECT token FROM report_share_links WHERE order_id = ? AND expires_at > NOW() LIMIT 1');
            $stmt->execute([$orderId]);
            $row = $stmt->fetch();
            if (!$row) {
                $token = bin2hex(random_bytes(32));
                $expires = date('Y-m-d H:i:s', strtotime('+30 days'));
                $ins = $db->prepare('INSERT INTO report_share_links (order_id, token, expires_at) VALUES (?, ?, ?)');
                $ins->execute([$orderId, $token, $expires]);
            } else {
                $token = $row['token'];
            }

            $base = ($_SERVER['REQUEST_SCHEME'] ?? 'https') . '://' . ($_SERVER['HTTP_HOST'] ?? '');
            $scriptDir = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'] ?? ''));
            if ($scriptDir !== '/' && $scriptDir !== '') $base .= $scriptDir;
            $base .= '/index.php?page=print_result&share_token=' . urlencode($token);

            $tid = (int)Tenant::id();
            if ($tid > 1) {
                $t = $db->prepare('SELECT slug FROM tenants WHERE id = ?');
                $t->execute([$tid]);
                $tr = $t->fetch();
                if ($tr && !empty($tr['slug'])) {
                    $base .= '&tenant=' . urlencode($tr['slug']);
                }
            }
            return $base;
        } catch (Throwable $e) {
            return '';
        }
    }

    /** إرسال تذكير بالديون للمريض */
    public function sendDebtReminder(int $patientId, float $debtAmount, string $invoiceNumbers = '', int $orderId = 0): bool
    {
        if (!$this->enabled) return false;
        try {
            $stmt = $this->db->prepare('SELECT full_name, phone FROM patients WHERE id = ?');
            $stmt->execute([$patientId]);
            $row = $stmt->fetch();
            if (!$row || trim((string)$row['phone']) === '') return false;
            $phone = $this->normalizePhone(trim($row['phone']));
            if ($phone === '') return false;
            if ($orderId <= 0) {
                $oStmt = $this->db->prepare('SELECT o.id FROM lab_orders o JOIN invoices i ON i.order_id = o.id WHERE o.patient_id = ? AND (i.net_amount - i.paid_amount) > 0 LIMIT 1');
                $oStmt->execute([$patientId]);
                $oRow = $oStmt->fetch();
                $orderId = $oRow ? (int)$oRow['id'] : 0;
            }
            if ($orderId <= 0) return false;
            $name = $row['full_name'] ?? 'المريض';
            $msg = "عزيزي/عزيزتي $name: يتبقى لديك مبلغ " . number_format($debtAmount, 2) . " غير مدفوع.";
            if ($invoiceNumbers !== '') $msg .= " (فواتير: $invoiceNumbers)";
            $msg .= " يرجى التكرم بالتواصل مع المختبر للتسوية.";
            if ($this->paymentLink !== null && $this->paymentLink !== '') {
                $msg .= "\nرابط الدفع: " . $this->paymentLink;
            }
            if ($this->paymentNumber !== null && $this->paymentNumber !== '') {
                $msg .= "\nرقم الحوالة/الدفع: " . $this->paymentNumber;
            }
            $stmt = $this->db->prepare('INSERT INTO whatsapp_notifications (order_id, patient_id, phone, message, status) VALUES (?, ?, ?, ?, ?)');
            $stmt->execute([$orderId, $patientId, $phone, $msg, 'pending']);
            $nid = (int)$this->db->lastInsertId();
            $this->sendNow($nid, $phone, $msg);
            return true;
        } catch (Throwable $e) {
            return false;
        }
    }

    private function sendNow(int $notificationId, string $phone, string $message): void
    {
        if ($this->provider === 'ultramsg') {
            if ($this->instanceId === '' || $this->accessToken === '') return;
            $url = 'https://api.ultramsg.com/' . trim($this->instanceId, '/') . '/messages/chat';
            $payload = http_build_query([
                'token' => $this->accessToken,
                'to' => $phone,
                'body' => $message,
                'priority' => 10
            ]);
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
        } else {
            if ($this->apiUrl === '' || $this->accessToken === '' || $this->fromNumber === '') return;
            $payload = json_encode([
                'to' => $phone,
                'from' => $this->fromNumber,
                'message' => $message
            ]);
            $ch = curl_init($this->apiUrl);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $this->accessToken
            ]);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
        }

        $response = curl_exec($ch);
        $error = curl_error($ch);
        $statusCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        $newStatus = 'failed';
        $providerId = null;
        $errorMessage = null;

        if ($error === '' && $statusCode >= 200 && $statusCode < 300) {
            $newStatus = 'sent';
            if ($this->provider === 'ultramsg' && $response) {
                $json = json_decode($response, true);
                if (!empty($json['id'])) $providerId = $json['id'];
            }
        } else {
            $errorMessage = $error !== '' ? $error : 'HTTP ' . $statusCode;
            if ($response && strlen($response) < 200) $errorMessage .= ': ' . $response;
        }

        try {
            $stmt = $this->db->prepare(
                'UPDATE whatsapp_notifications
                 SET status = :status, provider_message_id = :pid, error_message = :err, sent_at = NOW()
                 WHERE id = :id'
            );
            $stmt->execute([
                'status' => $newStatus,
                'pid' => $providerId,
                'err' => $errorMessage,
                'id' => $notificationId
            ]);
        } catch (Throwable $e) {
        }
    }

    /**
     * إرسال رسالة لرقم معيّن (لأغراض مثل تنبيهات الأطباء)
     * @return bool نجاح الإرسال
     */
    public function sendToNumber(string $phone, string $message): bool
    {
        if (!$this->enabled) return false;
        $phone = $this->normalizePhone($phone);
        if ($phone === '') return false;

        if ($this->provider === 'ultramsg') {
            if ($this->instanceId === '' || $this->accessToken === '') return false;
            $url = 'https://api.ultramsg.com/' . trim($this->instanceId, '/') . '/messages/chat';
            $payload = http_build_query([
                'token' => $this->accessToken,
                'to' => $phone,
                'body' => $message,
                'priority' => 10
            ]);
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
        } else {
            if ($this->apiUrl === '' || $this->accessToken === '' || $this->fromNumber === '') return false;
            $payload = json_encode([
                'to' => $phone,
                'from' => $this->fromNumber,
                'message' => $message
            ]);
            $ch = curl_init($this->apiUrl);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $this->accessToken
            ]);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
        }

        $response = curl_exec($ch);
        $statusCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return $statusCode >= 200 && $statusCode < 300;
    }
}