<?php
/**
 * Smart Doctor API - واجهة AJAX للطبيب
 */
header('Content-Type: application/json; charset=UTF-8');

$config = require __DIR__ . '/config/config.php';
require_once __DIR__ . '/src/Core/Database.php';
require_once __DIR__ . '/src/Core/Session.php';
require_once __DIR__ . '/src/Core/Csrf.php';
require_once __DIR__ . '/src/Core/Auth.php';
require_once __DIR__ . '/src/Core/DoctorAuth.php';
require_once __DIR__ . '/src/Core/UnifiedAuth.php';
require_once __DIR__ . '/src/Core/Tenant.php';

\App\Core\Session::start();

$db = \App\Core\Database::getInstance($config['db'])->connection();
\App\Core\Tenant::resolve($db);
if (\App\Core\Tenant::isSubdomainRejected()) {
    http_response_code(403);
    echo json_encode(['error' => 'مختبر غير صالح'], JSON_UNESCAPED_UNICODE);
    exit;
}
$auth = new \App\Core\Auth($db);
$doctorAuth = new \App\Core\DoctorAuth($db);
$unifiedAuth = new \App\Core\UnifiedAuth($db, $auth);

if (!$doctorAuth->check()) {
    if (!($unifiedAuth->isLoggedIn() && in_array('doctor', $unifiedAuth->availablePortals(), true) && $unifiedAuth->activatePortal('doctor') && $doctorAuth->check())) {
        http_response_code(401);
        echo json_encode(['error' => 'غير مصرح']);
        exit;
    }
}

$doctorId = $doctorAuth->doctorId();
$tenantId = $doctorAuth->tenantId();
$accountId = $doctorAuth->accountId();
\App\Core\Tenant::setId($tenantId);

$tenantCond = ' AND o.tenant_id = ' . (int)$tenantId;
$doctorCond = ' AND o.doctor_id = ' . (int)$doctorId;

// لا ننفذ migrations أثناء runtime؛ نكتفي بفحص schema وتسجيل أي نقص.
try {
    $db->query('SELECT id FROM doctor_search_history LIMIT 1');
} catch (Throwable $e) {
    error_log('doctor_api.php schema missing: doctor_search_history | run migrations before production traffic');
}

function logActivity($db, $accountId, $action, $entityType = null, $entityId = null, $details = null) {
    if ($action === 'log_activity') return;
    try {
        $db->query('SELECT id FROM doctor_activity_log LIMIT 1');
        $stmt = $db->prepare('INSERT INTO doctor_activity_log (doctor_account_id, action, entity_type, entity_id, details, ip_address) VALUES (?, ?, ?, ?, ?, ?)');
        $stmt->execute([$accountId, $action, $entityType, $entityId, $details ? json_encode($details) : null, $_SERVER['REMOTE_ADDR'] ?? null]);
    } catch (Throwable $e) {}
}

$action = $_GET['action'] ?? $_POST['action'] ?? '';

$postOnlyActions = ['save_search', 'log_activity', 'mark_alert_read', 'create_alert'];
if (in_array($action, $postOnlyActions, true) && $_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['error' => 'POST required']);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $host = strtolower((string)($_SERVER['HTTP_HOST'] ?? ''));
    $origin = $_SERVER['HTTP_ORIGIN'] ?? '';
    $referer = $_SERVER['HTTP_REFERER'] ?? '';
    $originHost = strtolower((string)(parse_url($origin, PHP_URL_HOST) ?? ''));
    $refererHost = strtolower((string)(parse_url($referer, PHP_URL_HOST) ?? ''));
    if (($origin !== '' || $referer !== '') && $host !== '' && $originHost !== $host && $refererHost !== $host) {
        http_response_code(403);
        echo json_encode(['error' => 'طلب غير صالح']);
        exit;
    }
    $csrfToken = $_POST['_csrf'] ?? ($_SERVER['HTTP_X_CSRF_TOKEN'] ?? null);
    if (!is_string($csrfToken) || $csrfToken === '' || !\App\Core\Csrf::isValid($csrfToken)) {
        http_response_code(419);
        echo json_encode(['error' => 'CSRF']);
        exit;
    }
}

switch ($action) {
    case 'patient_card':
        $pid = (int)($_GET['patient_id'] ?? 0);
        if ($pid <= 0) { echo json_encode(['error' => 'معرف غير صالح']); exit; }
        try {
            $stmt = $db->prepare("SELECT p.id, p.full_name, p.patient_code, p.date_of_birth, p.gender, p.phone FROM patients p JOIN lab_orders o ON o.patient_id = p.id WHERE p.id = ? $tenantCond $doctorCond LIMIT 1");
            $stmt->execute([$pid]);
            $p = $stmt->fetch();
            if (!$p) { echo json_encode(['error' => 'غير موجود']); exit; }
            $stmt = $db->prepare("SELECT o.id, o.order_number, o.order_date, o.status FROM lab_orders o WHERE o.patient_id = ? $tenantCond $doctorCond ORDER BY o.order_date DESC LIMIT 5");
            $stmt->execute([$pid]);
            $orders = $stmt->fetchAll();
            $stmt = $db->prepare("SELECT COUNT(*) FROM results r JOIN order_items oi ON oi.id = r.order_item_id JOIN lab_orders o ON o.id = oi.order_id WHERE o.patient_id = ? AND r.flag = 'C' AND o.order_date >= DATE_SUB(CURDATE(), INTERVAL 180 DAY) $tenantCond $doctorCond");
            $stmt->execute([$pid]);
            $criticalCount = (int)$stmt->fetchColumn();
            echo json_encode(['patient' => $p, 'orders' => $orders, 'critical_count' => $criticalCount]);
        } catch (Throwable $e) { echo json_encode(['error' => 'خطأ']); }
        break;

    case 'search_history':
        try {
            $stmt = $db->prepare('SELECT search_query, search_type, created_at FROM doctor_search_history WHERE doctor_account_id = ? ORDER BY created_at DESC LIMIT 10');
            $stmt->execute([$accountId]);
            echo json_encode(['items' => $stmt->fetchAll()]);
        } catch (Throwable $e) { echo json_encode(['items' => []]); }
        break;

    case 'save_search':
        $q = trim($_POST['q'] ?? '');
        $type = in_array($_POST['type'] ?? 'all', ['patient','order','all']) ? $_POST['type'] : 'all';
        if (strlen($q) >= 2) {
            try {
                $stmt = $db->prepare('INSERT INTO doctor_search_history (doctor_account_id, search_query, search_type) VALUES (?, ?, ?)');
                $stmt->execute([$accountId, $q, $type]);
                echo json_encode(['ok' => true]);
            } catch (Throwable $e) { echo json_encode(['ok' => false]); }
        } else { echo json_encode(['ok' => false]); }
        break;

    case 'dashboard_prefs':
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $layout = $_POST['layout'] ?? null;
            $cards = $_POST['cards'] ?? null;
            $theme = $_POST['theme'] ?? 'auto';
            try {
                $stmt = $db->prepare('INSERT INTO doctor_dashboard_preferences (doctor_account_id, layout_json, visible_cards, theme) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE layout_json = VALUES(layout_json), visible_cards = VALUES(visible_cards), theme = VALUES(theme)');
                $stmt->execute([$accountId, $layout ? json_encode($layout) : null, $cards ? json_encode($cards) : null, $theme]);
                echo json_encode(['ok' => true]);
            } catch (Throwable $e) { echo json_encode(['ok' => false]); }
        } else {
            try {
                $stmt = $db->prepare('SELECT layout_json, visible_cards, theme FROM doctor_dashboard_preferences WHERE doctor_account_id = ?');
                $stmt->execute([$accountId]);
                $r = $stmt->fetch();
                echo json_encode($r ? ['layout' => $r['layout_json'] ? json_decode($r['layout_json']) : null, 'cards' => $r['visible_cards'] ? json_decode($r['visible_cards']) : null, 'theme' => $r['theme'] ?? 'auto'] : ['layout' => null, 'cards' => null, 'theme' => 'auto']);
            } catch (Throwable $e) { echo json_encode(['layout' => null, 'cards' => null, 'theme' => 'auto']); }
        }
        break;

    case 'activity_log':
        $limit = min(50, max(5, (int)($_GET['limit'] ?? 20)));
        try {
            $stmt = $db->prepare('SELECT action, entity_type, entity_id, details, created_at FROM doctor_activity_log WHERE doctor_account_id = ? ORDER BY created_at DESC LIMIT ' . (int)$limit);
            $stmt->execute([$accountId]);
            $rows = $stmt->fetchAll();
            foreach ($rows as &$r) { if ($r['details']) $r['details'] = json_decode($r['details']); }
            echo json_encode(['items' => $rows]);
        } catch (Throwable $e) { echo json_encode(['items' => []]); }
        break;

    case 'reminders_calendar':
        $year = (int)($_GET['year'] ?? date('Y'));
        $month = (int)($_GET['month'] ?? date('n'));
        try {
            $stmt = $db->prepare('SELECT r.reminder_date, COUNT(*) AS cnt FROM doctor_follow_up_reminders r WHERE r.doctor_account_id = ? AND r.is_done = 0 AND YEAR(r.reminder_date) = ? AND MONTH(r.reminder_date) = ? GROUP BY r.reminder_date');
            $stmt->execute([$accountId, $year, $month]);
            $byDate = [];
            foreach ($stmt->fetchAll() as $row) $byDate[$row['reminder_date']] = (int)$row['cnt'];
            echo json_encode(['by_date' => $byDate]);
        } catch (Throwable $e) { echo json_encode(['by_date' => []]); }
        break;

    case 'smart_reminder_suggest':
        $pid = (int)($_GET['patient_id'] ?? 0);
        if ($pid <= 0) { echo json_encode(['suggestions' => []]); exit; }
        $suggestions = [];
        try {
            $stmt = $db->prepare("SELECT r.flag, t.name FROM results r JOIN order_items oi ON oi.id = r.order_item_id JOIN lab_orders o ON o.id = oi.order_id JOIN tests t ON t.id = oi.test_id WHERE o.patient_id = ? AND r.flag IN ('L','H','C') AND o.order_date >= DATE_SUB(CURDATE(), INTERVAL 90 DAY) $tenantCond $doctorCond ORDER BY o.order_date DESC LIMIT 5");
            $stmt->execute([$pid]);
            $abnormals = $stmt->fetchAll();
            if (!empty($abnormals)) {
                $suggestions[] = ['date' => date('Y-m-d', strtotime('+2 weeks')), 'note' => 'متابعة نتائج غير طبيعية: ' . implode(', ', array_unique(array_column($abnormals, 'name')))];
            }
            echo json_encode(['suggestions' => $suggestions]);
        } catch (Throwable $e) { echo json_encode(['suggestions' => []]); }
        break;

    case 'log_activity':
        $act = trim($_POST['event'] ?? '');
        $entityType = $_POST['entity_type'] ?? null;
        $entityId = isset($_POST['entity_id']) ? (int)$_POST['entity_id'] : null;
        if (in_array($act, ['view_results', 'view_patient', 'search', 'export'])) {
            logActivity($db, $accountId, $act, $entityType, $entityId);
            echo json_encode(['ok' => true]);
        } else { echo json_encode(['error' => 'إجراء غير صالح']); }
        break;

    case 'notifications_check':
        $critical = 0;
        $overdue = 0;
        $alerts = 0;
        try {
            $stmt = $db->prepare("SELECT COUNT(*) FROM results r JOIN order_items oi ON oi.id = r.order_item_id JOIN lab_orders o ON o.id = oi.order_id WHERE r.flag = 'C' $tenantCond $doctorCond");
            $stmt->execute();
            $critical = (int)$stmt->fetchColumn();
            $stmt = $db->prepare('SELECT COUNT(*) FROM doctor_follow_up_reminders WHERE doctor_account_id = ? AND reminder_date < CURDATE() AND is_done = 0');
            $stmt->execute([$accountId]);
            $overdue = (int)$stmt->fetchColumn();
            $db->query('SELECT id FROM doctor_alerts LIMIT 1');
            $stmt = $db->prepare('SELECT COUNT(*) FROM doctor_alerts WHERE doctor_account_id = ? AND is_read = 0');
            $stmt->execute([$accountId]);
            $alerts = (int)$stmt->fetchColumn();
        } catch (Throwable $e) {}
        echo json_encode(['critical' => $critical, 'overdue' => $overdue, 'alerts' => $alerts]);
        break;

    case 'get_inbox':
        $limit = min(20, max(5, (int)($_GET['limit'] ?? 10)));
        $items = [];
        try {
            // نتائج حرجة (مختصرة)
            $stmt = $db->prepare("
                SELECT o.id AS order_id, o.order_number, o.order_date, p.full_name AS patient_name, t.name AS test_name, r.result_value
                FROM results r
                JOIN order_items oi ON oi.id = r.order_item_id
                JOIN lab_orders o ON o.id = oi.order_id
                JOIN patients p ON p.id = o.patient_id
                JOIN tests t ON t.id = oi.test_id
                WHERE r.flag = 'C' $tenantCond $doctorCond
                ORDER BY o.order_date DESC
                LIMIT 5
            ");
            $stmt->execute();
            foreach ($stmt->fetchAll() as $row) {
                $items[] = [
                    'type' => 'critical_result',
                    'priority' => 100,
                    'title' => 'نتيجة حرجة: ' . ($row['test_name'] ?? ''),
                    'subtitle' => ($row['patient_name'] ?? 'مريض') . ' - الطلب ' . ($row['order_number'] ?? ('#' . (int)$row['order_id'])),
                    'meta' => (string)($row['result_value'] ?? ''),
                    'created_at' => $row['order_date'] ?? null,
                    'url' => 'doctor.php?page=results&order_id=' . (int)$row['order_id'] . '&critical=1'
                ];
            }
        } catch (Throwable $e) {}
        try {
            // تذكيرات متأخرة
            $stmt = $db->prepare("
                SELECT r.id, r.reminder_date, r.note, p.full_name AS patient_name, p.id AS patient_id
                FROM doctor_follow_up_reminders r
                JOIN patients p ON p.id = r.patient_id
                WHERE r.doctor_account_id = ? AND r.is_done = 0 AND r.reminder_date < CURDATE()
                ORDER BY r.reminder_date ASC
                LIMIT 5
            ");
            $stmt->execute([$accountId]);
            foreach ($stmt->fetchAll() as $row) {
                $items[] = [
                    'type' => 'overdue_reminder',
                    'priority' => 80,
                    'title' => 'تذكير متأخر',
                    'subtitle' => ($row['patient_name'] ?? 'مريض') . ' - ' . ($row['note'] ?? 'متابعة'),
                    'meta' => $row['reminder_date'] ?? null,
                    'created_at' => $row['reminder_date'] ?? null,
                    'url' => 'doctor.php?page=reminders'
                ];
            }
        } catch (Throwable $e) {}
        try {
            // تنبيهات غير مقروءة
            $db->query('SELECT id FROM doctor_alerts LIMIT 1');
            $stmt = $db->prepare("SELECT id, title, message, created_at, action_url, priority FROM doctor_alerts WHERE doctor_account_id = ? AND is_read = 0 ORDER BY id DESC LIMIT 10");
            $stmt->execute([$accountId]);
            foreach ($stmt->fetchAll() as $row) {
                $priorityMap = ['urgent' => 90, 'high' => 75, 'medium' => 60, 'normal' => 60, 'low' => 40];
                $items[] = [
                    'type' => 'alert',
                    'priority' => $priorityMap[$row['priority'] ?? 'medium'] ?? 60,
                    'title' => (string)($row['title'] ?? 'تنبيه'),
                    'subtitle' => (string)($row['message'] ?? ''),
                    'meta' => null,
                    'created_at' => $row['created_at'] ?? null,
                    'url' => $row['action_url'] ?: ('doctor.php?page=alerts&mark_read=' . (int)$row['id'])
                ];
            }
        } catch (Throwable $e) {}
        try {
            // مهام متأخرة/اليوم
            $db->query('SELECT id FROM doctor_tasks LIMIT 1');
            $stmt = $db->prepare("
                SELECT id, title, due_date, priority, is_completed
                FROM doctor_tasks
                WHERE doctor_account_id = ? AND is_completed = 0 AND (due_date < CURDATE() OR due_date = CURDATE())
                ORDER BY due_date ASC, priority DESC
                LIMIT 5
            ");
            $stmt->execute([$accountId]);
            foreach ($stmt->fetchAll() as $row) {
                $items[] = [
                    'type' => 'task',
                    'priority' => ($row['due_date'] < date('Y-m-d')) ? 70 : 55,
                    'title' => 'مهمة: ' . (string)($row['title'] ?? ''),
                    'subtitle' => ($row['due_date'] < date('Y-m-d')) ? 'متأخرة' : 'مطلوبة اليوم',
                    'meta' => $row['due_date'] ?? null,
                    'created_at' => $row['due_date'] ?? null,
                    'url' => 'doctor.php?page=tasks'
                ];
            }
        } catch (Throwable $e) {}
        usort($items, static function ($a, $b) {
            $pa = (int)($a['priority'] ?? 0);
            $pb = (int)($b['priority'] ?? 0);
            if ($pa !== $pb) return $pb <=> $pa;
            return strcmp((string)($b['created_at'] ?? ''), (string)($a['created_at'] ?? ''));
        });
        echo json_encode(['items' => array_slice($items, 0, $limit)]);
        break;

    case 'get_alerts':
        $limit = min(50, max(5, (int)($_GET['limit'] ?? 20)));
        $unreadOnly = isset($_GET['unread']) && $_GET['unread'] === '1';
        try {
            $db->query('SELECT id FROM doctor_alerts LIMIT 1');
            $where = 'doctor_account_id = ?';
            $params = [$accountId];
            if ($unreadOnly) {
                $where .= ' AND is_read = 0';
            }
            $stmt = $db->prepare("SELECT * FROM doctor_alerts WHERE $where ORDER BY id DESC LIMIT " . (int)$limit);
            $stmt->execute($params);
            echo json_encode(['items' => $stmt->fetchAll()]);
        } catch (Throwable $e) {
            echo json_encode(['items' => []]);
        }
        break;

    case 'mark_alert_read':
        $alertId = (int)($_POST['alert_id'] ?? 0);
        if ($alertId > 0) {
            try {
                $db->query('SELECT id FROM doctor_alerts LIMIT 1');
                $stmt = $db->prepare('UPDATE doctor_alerts SET is_read = 1, read_at = NOW() WHERE id = ? AND doctor_account_id = ?');
                $stmt->execute([$alertId, $accountId]);
                echo json_encode(['ok' => true]);
            } catch (Throwable $e) {
                echo json_encode(['ok' => false, 'error' => $e->getMessage()]);
            }
        } else {
            echo json_encode(['ok' => false, 'error' => 'معرف غير صالح']);
        }
        break;

    case 'get_tasks':
        $filter = $_GET['filter'] ?? 'all';
        $limit = min(100, max(5, (int)($_GET['limit'] ?? 50)));
        try {
            $db->query('SELECT id FROM doctor_tasks LIMIT 1');
            $where = 'doctor_account_id = ?';
            $params = [$accountId];
            if ($filter === 'pending') {
                $where .= ' AND is_completed = 0';
            } elseif ($filter === 'completed') {
                $where .= ' AND is_completed = 1';
            } elseif ($filter === 'overdue') {
                $where .= ' AND is_completed = 0 AND due_date < CURDATE()';
            } elseif ($filter === 'today') {
                $where .= ' AND is_completed = 0 AND due_date = CURDATE()';
            }
            $stmt = $db->prepare("SELECT * FROM doctor_tasks WHERE $where ORDER BY due_date ASC, priority DESC LIMIT " . (int)$limit);
            $stmt->execute($params);
            echo json_encode(['items' => $stmt->fetchAll()]);
        } catch (Throwable $e) {
            echo json_encode(['items' => []]);
        }
        break;

    case 'create_alert':
        $alertType = in_array($_POST['alert_type'] ?? 'info', ['critical', 'reminder', 'appointment', 'system', 'info']) ? $_POST['alert_type'] : 'info';
        $title = trim($_POST['title'] ?? '');
        $message = trim($_POST['message'] ?? '');
        $priority = in_array($_POST['priority'] ?? 'medium', ['low', 'medium', 'high', 'urgent']) ? $_POST['priority'] : 'medium';
        $entityType = $_POST['entity_type'] ?? null;
        $entityId = isset($_POST['entity_id']) ? (int)$_POST['entity_id'] : null;
        $actionUrl = trim($_POST['action_url'] ?? '');
        if ($title !== '') {
            try {
                $db->query('SELECT id FROM doctor_alerts LIMIT 1');
                $stmt = $db->prepare('INSERT INTO doctor_alerts (doctor_account_id, alert_type, title, message, priority, entity_type, entity_id, action_url) VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
                $stmt->execute([$accountId, $alertType, $title, $message ?: null, $priority, $entityType, $entityId, $actionUrl ?: null]);
                echo json_encode(['ok' => true, 'id' => (int)$db->lastInsertId()]);
            } catch (Throwable $e) {
                echo json_encode(['ok' => false, 'error' => $e->getMessage()]);
            }
        } else {
            echo json_encode(['ok' => false, 'error' => 'العنوان مطلوب']);
        }
        break;

    case 'quick_info':
        $patientId = (int)($_GET['patient_id'] ?? 0);
        if ($patientId > 0) {
            try {
                $stmt = $db->prepare("SELECT p.*, 
                    (SELECT COUNT(*) FROM lab_orders o WHERE o.patient_id = p.id $tenantCond $doctorCond) AS orders_count,
                    (SELECT MAX(o.order_date) FROM lab_orders o WHERE o.patient_id = p.id $tenantCond $doctorCond) AS last_order_date,
                    (SELECT COUNT(*) FROM results r JOIN order_items oi ON oi.id = r.order_item_id JOIN lab_orders o ON o.id = oi.order_id WHERE o.patient_id = p.id AND r.flag = 'C' $tenantCond $doctorCond) AS critical_count
                    FROM patients p WHERE p.id = ? $tenantCond LIMIT 1");
                $stmt->execute([$patientId]);
                $patient = $stmt->fetch();
                if ($patient) {
                    // آخر ملاحظة
                    try {
                        $db->query('SELECT id FROM patient_medical_notes LIMIT 1');
                        $stmt = $db->prepare('SELECT content, created_at FROM patient_medical_notes WHERE patient_id = ? AND doctor_account_id = ? ORDER BY created_at DESC LIMIT 1');
                        $stmt->execute([$patientId, $accountId]);
                        $lastNote = $stmt->fetch();
                    } catch (Throwable $e) {
                        $lastNote = null;
                    }
                    echo json_encode(['patient' => $patient, 'last_note' => $lastNote]);
                } else {
                    echo json_encode(['error' => 'مريض غير موجود']);
                }
            } catch (Throwable $e) {
                echo json_encode(['error' => 'خطأ في جلب البيانات']);
            }
        } else {
            echo json_encode(['error' => 'معرف غير صالح']);
        }
        break;

    default:
        echo json_encode(['error' => 'إجراء غير معروف']);
}
