<?php

namespace App\Core;

use PDO;
use Throwable;

/**
 * خدمة تنبيهات الأطباء - النتائج الحرجة، WhatsApp، doctor_alerts، التنبيهات المتعددة
 */
class DoctorNotification
{
    private PDO $db;
    private array $config;

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

    /**
     * إشعار الطبيب عند صدور نتيجة حرجة
     * @param string|null $baseUrl أساس الرابط (مثل doctor.php) لبناء action_url
     */
    public function notifyCriticalResult(int $orderId, int $patientId, int $doctorId, int $tenantId, string $testName, string $resultValue, ?string $orderNumber = null, ?string $baseUrl = null): void
    {
        if ($doctorId <= 0) return;

        try {
            Tenant::setId($tenantId);

            // جلب حسابات الطبيب المرتبطة بهذا المختبر
            $stmt = $this->db->prepare(
                'SELECT da.id, da.phone, da.whatsapp_notify_critical
                 FROM doctor_accounts da
                 WHERE da.doctor_id = ? AND da.tenant_id = ? AND da.is_active = 1'
            );
            $stmt->execute([$doctorId, $tenantId]);
            $accounts = $stmt->fetchAll();

            if (empty($accounts)) return;

            $patientName = '';
            $orderNum = $orderNumber;
            $stmt = $this->db->prepare('SELECT full_name FROM patients WHERE id = ?');
            $stmt->execute([$patientId]);
            $p = $stmt->fetch();
            if ($p) $patientName = $p['full_name'];
            if (empty($orderNum)) {
                $stmt = $this->db->prepare('SELECT order_number FROM lab_orders WHERE id = ?');
                $stmt->execute([$orderId]);
                $o = $stmt->fetch();
                if ($o) $orderNum = $o['order_number'];
            }

            $title = 'نتيجة حرجة - مراجعة فورية';
            $body = sprintf(
                'المريض: %s | الطلب: %s | الفحص: %s | النتيجة: %s',
                $patientName,
                $orderNum ?? $orderId,
                $testName,
                $resultValue
            );

            $actionUrl = ($baseUrl ?? 'doctor.php') . '?page=results&order_id=' . $orderId;

            foreach ($accounts as $acc) {
                $accountId = (int)$acc['id'];

                // إنشاء تنبيه في doctor_alerts مع action_url
                try {
                    $this->db->query('SELECT id FROM doctor_alerts LIMIT 1');
                    $alertCols = 'doctor_account_id, alert_type, title, message, patient_id, order_id, priority, is_read';
                    $alertVals = '?, ?, ?, ?, ?, ?, ?, 0';
                    $alertParams = [$accountId, 'critical', $title, $body, $patientId, $orderId, 'urgent'];
                    try {
                        $this->db->query('SELECT action_url FROM doctor_alerts LIMIT 1');
                        $alertCols .= ', action_url';
                        $alertVals .= ', ?';
                        $alertParams[] = $actionUrl;
                    } catch (Throwable $x) {}
                    $ins = $this->db->prepare(
                        "INSERT INTO doctor_alerts ($alertCols, created_at) VALUES ($alertVals, NOW())"
                    );
                    $ins->execute($alertParams);
                } catch (Throwable $e) {
                    // قد لا يكون جدول doctor_alerts موجوداً
                }

                // إرسال WhatsApp إذا مفعّل
                if (!empty($acc['whatsapp_notify_critical']) && trim((string)($acc['phone'] ?? '')) !== '') {
                    $this->sendWhatsAppToDoctor($accountId, (string)$acc['phone'], $body, $orderId, $patientId);
                }
            }
        } catch (Throwable $e) {
            error_log('DoctorNotification::notifyCriticalResult: ' . $e->getMessage());
        }
    }

    /**
     * إشعار الطبيب بأن نتائج الطلب جاهزة للمراجعة (عند اكتمال الطلب من المختبر أو من شاشة الطلبات).
     * يتجنب إدراج تنبيه مكرر إذا وُجد تنبيه غير مقروء لنفس الطلب ونفس العنوان.
     */
    public function notifyOrderResultsReady(int $doctorId, int $tenantId, int $orderId, ?string $orderNumber = null, ?int $patientId = null): void
    {
        if ($doctorId <= 0) {
            return;
        }
        try {
            $this->db->query('SELECT id FROM doctor_alerts LIMIT 1');
        } catch (Throwable $e) {
            return;
        }
        try {
            Tenant::setId($tenantId);

            $accStmt = $this->db->prepare('SELECT id FROM doctor_accounts WHERE doctor_id = ? AND tenant_id = ? AND is_active = 1 ORDER BY id DESC LIMIT 1');
            $accStmt->execute([$doctorId, $tenantId]);
            $doctorAccountId = (int)($accStmt->fetchColumn() ?: 0);
            if ($doctorAccountId <= 0) {
                return;
            }

            $title = 'نتائج جاهزة للمراجعة';
            try {
                $dupStmt = $this->db->prepare(
                    'SELECT id FROM doctor_alerts WHERE doctor_account_id = ? AND entity_type = ? AND entity_id = ? AND title = ? AND is_read = 0 LIMIT 1'
                );
                $dupStmt->execute([$doctorAccountId, 'order', $orderId, $title]);
                if ($dupStmt->fetch()) {
                    return;
                }
            } catch (Throwable $e) {
                // أعمدة قديمة: نتابع بدون منع تكرار
            }

            $patientName = '';
            if ($patientId !== null && $patientId > 0) {
                $pStmt = $this->db->prepare('SELECT full_name FROM patients WHERE id = ? LIMIT 1');
                $pStmt->execute([$patientId]);
                $patientName = (string)($pStmt->fetchColumn() ?: '');
            }

            $message = 'اكتمل الطلب ' . ($orderNumber !== null && $orderNumber !== '' ? $orderNumber : ('#' . $orderId));
            if ($patientName !== '') {
                $message .= ' للمريض: ' . $patientName;
            }
            $actionUrl = 'doctor.php?page=results&order_id=' . $orderId;

            $this->createAlert(
                $doctorAccountId,
                'info',
                $title,
                $message,
                'high',
                $patientId,
                $orderId,
                $actionUrl,
                'order',
                $orderId
            );
        } catch (Throwable $e) {
            error_log('DoctorNotification::notifyOrderResultsReady: ' . $e->getMessage());
        }
    }

    /**
     * إنشاء تنبيه عام (للتذكيرات، المواعيد، إلخ)
     * @param string $priority من: low, normal, high, urgent
     */
    public function createAlert(int $doctorAccountId, string $alertType, string $title, string $message, string $priority = 'normal', ?int $patientId = null, ?int $orderId = null, ?string $actionUrl = null, ?string $entityType = null, ?int $entityId = null): bool
    {
        try {
            $this->db->query('SELECT id FROM doctor_alerts LIMIT 1');
            $stmt = $this->db->prepare(
                'INSERT INTO doctor_alerts (doctor_account_id, alert_type, title, message, patient_id, order_id, priority, is_read, action_url, entity_type, entity_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?, NOW())'
            );
            $stmt->execute([$doctorAccountId, $alertType, $title, $message ?: null, $patientId, $orderId, $priority, $actionUrl, $entityType, $entityId]);
            return true;
        } catch (Throwable $e) {
            error_log('DoctorNotification::createAlert: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * إشعار الطبيب عند حجز مريض موعد (واتساب + تنبيه)
     */
    public function notifyAppointmentBooking(int $doctorAccountId, string $patientName, string $patientPhone, string $aptDate, string $aptTime, ?string $note, int $patientId, ?string $waMeForPatient = null): void
    {
        try {
            $stmt = $this->db->prepare('SELECT da.phone, da.whatsapp_notify_appointments FROM doctor_accounts da WHERE da.id = ?');
            $stmt->execute([$doctorAccountId]);
            $acc = $stmt->fetch();
            if (!$acc) return;

            $timeShort = substr($aptTime, 0, 5);
            $message = "🩺 *حجز موعد جديد*\n\n";
            $message .= "👤 المريض: {$patientName}\n";
            $message .= "📞 الهاتف: {$patientPhone}\n";
            $message .= "📅 التاريخ: {$aptDate}\n";
            $message .= "🕐 الوقت: {$timeShort}\n";
            if (!empty($note)) $message .= "📝 ملاحظة: {$note}\n";

            $actionUrl = 'doctor.php?page=appointments&date=' . urlencode($aptDate);
            $this->createAlert($doctorAccountId, 'appointment', 'حجز موعد جديد', $message, 'high', $patientId, null, $actionUrl, 'appointment', null);

            $notifyAppointments = isset($acc['whatsapp_notify_appointments']) ? (int)$acc['whatsapp_notify_appointments'] : 1;
            if ($notifyAppointments && trim((string)($acc['phone'] ?? '')) !== '') {
                $this->sendWhatsAppToDoctor($doctorAccountId, (string)$acc['phone'], $message, null, $patientId);
            }
        } catch (Throwable $e) {
            error_log('DoctorNotification::notifyAppointmentBooking: ' . $e->getMessage());
        }
    }

    /**
     * إشعار تذكير متأخر
     */
    public function notifyReminderOverdue(int $doctorAccountId, string $patientName, int $patientId, string $reminderNote, string $reminderDate): void
    {
        $this->createAlert(
            $doctorAccountId,
            'reminder',
            'تذكير متأخر',
            sprintf('مريض: %s - %s (تاريخ التذكير: %s)', $patientName, $reminderNote, $reminderDate),
            'high',
            $patientId,
            null,
            'doctor.php?page=results&patient_id=' . $patientId . '#reminder',
            'patient',
            $patientId
        );
    }

    /**
     * إرسال رسالة WhatsApp للطبيب (بالخلفية عبر الطابور)
     * إذا الطبيب عنده واتساب مالتة (instance+token) يستخدمها، وإلا إعدادات المختبر
     */
    private function sendWhatsAppToDoctor(int $accountId, string $phone, string $message, ?int $orderId, ?int $patientId): void
    {
        $phone = preg_replace('/\D/', '', trim($phone));
        if (strlen($phone) < 8) return;
        if (strlen($phone) === 10 && $phone[0] === '0') $phone = '964' . substr($phone, 1);
        elseif (strlen($phone) === 9 && $phone[0] === '7') $phone = '964' . $phone;
        $phone = '+' . $phone;

        $whatsappConfig = $this->config['whatsapp'] ?? [];
        try {
            $this->db->query('SELECT id FROM whatsapp_send_queue LIMIT 1');
        } catch (Throwable $e) {
            return;
        }

        $tenantId = 1;
        $useDoctorConfig = 0;
        try {
            $stmt = $this->db->prepare('SELECT tenant_id, whatsapp_instance_id, whatsapp_access_token FROM doctor_accounts WHERE id = ?');
            $stmt->execute([$accountId]);
            $da = $stmt->fetch();
            if ($da) {
                $tenantId = (int)$da['tenant_id'];
                $inst = trim((string)($da['whatsapp_instance_id'] ?? ''));
                $token = trim((string)($da['whatsapp_access_token'] ?? ''));
                if ($inst !== '' && $token !== '') $useDoctorConfig = 1;
            }
        } catch (Throwable $e) {}

        if ($useDoctorConfig === 0 && empty($whatsappConfig['enabled'])) return;

        try {
            $this->db->exec("CREATE TABLE IF NOT EXISTS doctor_whatsapp_alerts (
                id INT AUTO_INCREMENT PRIMARY KEY,
                doctor_account_id INT NOT NULL,
                order_id INT NULL,
                patient_id INT NULL,
                message TEXT,
                phone VARCHAR(30),
                status ENUM('pending','sent','failed') DEFAULT 'pending',
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                sent_at DATETIME NULL
            )");
        } catch (Throwable $e) {}

        try {
            $this->db->prepare(
                'INSERT INTO doctor_whatsapp_alerts (doctor_account_id, order_id, patient_id, message, phone, status) VALUES (?, ?, ?, ?, ?, ?)'
            )->execute([$accountId, $orderId, $patientId, $message, $phone, 'pending']);

            $stmt = $this->db->prepare('INSERT INTO whatsapp_send_queue (tenant_id, doctor_account_id, phone, message, use_doctor_config) VALUES (?, ?, ?, ?, ?)');
            $stmt->execute([$tenantId, $accountId, $phone, $message, $useDoctorConfig]);
        } catch (Throwable $e) {
            error_log('DoctorNotification sendWhatsApp: ' . $e->getMessage());
        }
    }
}
