<?php
ob_start();

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

/* ================= SESSION ================= */
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

include_once('includes/db.php');

/* ================= Auto Logout ================= */
$timeout_duration = 43200;

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY']) > $timeout_duration) {
    session_unset();
    session_destroy();
    header("Location: login.php?timeout=1");
    exit;
}

$_SESSION['LAST_ACTIVITY'] = time();

/* ================= Check Login ================= */
if (!isset($_SESSION['user_id'])) {
    header("Location: login.php");
    exit;
}

/* ================= HTML HEADER ================= */
include('includes/header.php');

/* ================= CSRF Token ================= */
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
$csrf = $_SESSION['csrf_token'];

/* ================= HELPER ================= */
function calculate_age($dob) {
    if (!$dob || $dob === '0000-00-00') return '';
    try {
        $dobDate = new DateTime($dob);
        $now = new DateTime();
        $diff = $now->diff($dobDate);
        if ($diff->y >= 1) return $diff->y . ' Year' . ($diff->y > 1 ? 's' : '');
        if ($diff->m >= 1) return $diff->m . ' Month' . ($diff->m > 1 ? 's' : '');
        return $diff->d . ' Day' . ($diff->d > 1 ? 's' : '');
    } catch (Exception $e) {
        return '';
    }
}

function sanitize_prescriber_id($id, $pdo) {
    $id = intval($id);
    if ($id <= 0) return null;
    $stmt = $pdo->prepare("SELECT id FROM users WHERE id=? AND user_role='Doctor'");
    $stmt->execute([$id]);
    return $stmt->fetchColumn() ?: null;
}

// Helper function to determine if user can be treated_by
function can_be_treated_by($user_role) {
    return in_array($user_role, ['Doctor', 'Dentist', 'Admin', 'Super_admin']);
}

// Helper function to get or set treated_by
function get_or_set_treated_by($visit, $session_user_id, $session_user_role, $pdo) {
    // If visit already has a treated_by doctor, keep it (never change)
    if (!empty($visit['treated_by'])) {
        return $visit['treated_by'];
    }
    
    // If current user can be treated_by (Doctor, Dentist, Admin, Super_admin)
    // AND current user is NOT a Nurse, set them as treated_by
    if (can_be_treated_by($session_user_role) && $session_user_role !== 'Nurse') {
        return $session_user_id;
    }
    
    // For Nurses or other roles that can't be treated_by, return null
    // The system will need to handle this case elsewhere
    return null;
}

// Helper function to log section changes to history table
function logSectionChange($pdo, $ticket_id, $section, $old_value, $new_value, $changed_by) {
    try {
        // Check if history table exists
        $stmtCheck = $pdo->query("SHOW TABLES LIKE 'visit_ticket_history'");
        if ($stmtCheck->rowCount() > 0) {
            // Only log if there's an actual change and values are different
            if ($old_value != $new_value) {
                $stmt = $pdo->prepare("
                    INSERT INTO visit_ticket_history 
                    (visit_ticket_id, section, old_value, new_value, changed_by, changed_at) 
                    VALUES (?, ?, ?, ?, ?, NOW())
                ");
                $stmt->execute([$ticket_id, $section, $old_value, $new_value, $changed_by]);
                return true;
            }
        }
        return false;
    } catch (PDOException $e) {
        error_log("Error logging section change: " . $e->getMessage());
        return false;
    }
}

// Helper function to get lab test names from IDs
function getLabTestNames($lab_ids, $pdo) {
    if (empty($lab_ids)) return [];
    
    $lab_names = [];
    $valid_ids = array_filter($lab_ids, function($id) { return !empty($id); });
    
    if (!empty($valid_ids)) {
        $placeholders = implode(',', array_fill(0, count($valid_ids), '?'));
        $stmt = $pdo->prepare("SELECT id, name FROM products WHERE id IN ($placeholders)");
        $stmt->execute($valid_ids);
        $labs = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($labs as $lab) {
            $lab_names[$lab['id']] = $lab['name'];
        }
    }
    
    return $lab_names;
}

// ADDED: Function to get last 3 updates for each section
function getLastThreeUpdates($section, $visit_ticket_id) {
    global $pdo;
    
    if (!isset($pdo)) {
        return "";
    }
    
    try {
        $stmt = $pdo->prepare("
            SELECT h.*, u.username, u.user_role 
            FROM visit_ticket_history h
            LEFT JOIN users u ON h.changed_by = u.id
            WHERE h.visit_ticket_id = ? AND h.section = ?
            ORDER BY h.changed_at DESC
            LIMIT 3
        ");
        $stmt->execute([$visit_ticket_id, $section]);
        $updates = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        if (!empty($updates)) {
            $output = '<div class="updates-container" style="max-width: 300px; text-align: right;">';
            foreach ($updates as $update) {
                $username = htmlspecialchars($update['username'] ?? 'System');
                $role = htmlspecialchars($update['user_role'] ?? 'System');
                $timestamp = isset($update['changed_at']) ? date('M d, H:i', strtotime($update['changed_at'])) : '';
                
                $output .= '<small class="update-item" style="display: block; font-size: 11px; color: #666; line-height: 1.2; margin-bottom: 2px;">';
                $output .= '<i class="icon-user" style="margin-right: 3px;"></i>' . $username . ' (' . $role . ')';
                if ($timestamp) {
                    $output .= ' - ' . $timestamp;
                }
                $output .= '</small>';
            }
            $output .= '</div>';
            return $output;
        }
    } catch (Exception $e) {
        error_log("Error fetching updates: " . $e->getMessage());
    }
    return "";
}

/* ================= Handle Discharge Patient Action ================= */
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['discharge_patient'])) {
    // Verify CSRF token
    if (!isset($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
        $_SESSION['flash'] = ['message' => 'Invalid CSRF token', 'color' => '#dc3545'];
        header("Location: visit_ticket.php?id=" . ($_POST['visit_id'] ?? 0));
        exit;
    }
    
    // Check if user has permission to discharge
    $user_role = $_SESSION['user_role'] ?? '';
    $allowed_roles = ['Doctor', 'Dentist', 'Admin', 'Super_admin'];
    if (!in_array($user_role, $allowed_roles)) {
        $_SESSION['flash'] = ['message' => 'You do not have permission to discharge patients', 'color' => '#dc3545'];
        header("Location: visit_ticket.php?id=" . ($_POST['visit_id'] ?? 0));
        exit;
    }
    
    $visit_id = (int)($_POST['visit_id'] ?? 0);
    if (!$visit_id) {
        $_SESSION['flash'] = ['message' => 'Invalid Visit ID', 'color' => '#dc3545'];
        header("Location: visit_ticket.php?id=" . $visit_id);
        exit;
    }
    
    // Check if visit exists
    $stmt = $pdo->prepare("SELECT id, discharge_time FROM visits WHERE id = ?");
    $stmt->execute([$visit_id]);
    $visit_check = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if (!$visit_check) {
        $_SESSION['flash'] = ['message' => 'Visit not found', 'color' => '#dc3545'];
        header("Location: visit_ticket.php?id=" . $visit_id);
        exit;
    }
    
    // Check if already discharged
    if (!empty($visit_check['discharge_time'])) {
        $_SESSION['flash'] = ['message' => 'Patient is already discharged', 'color' => '#dc3545'];
        header("Location: visit_ticket.php?id=" . $visit_id);
        exit;
    }
    
    try {
        // Begin transaction
        $pdo->beginTransaction();
        
        // Set discharge time only - keep visit status as 'open'
        // Don't set closed_at or change status
        $current_time = date('Y-m-d H:i:s');
        $stmt = $pdo->prepare("
            UPDATE visits SET 
                discharge_time = ?
            WHERE id = ?
        ");
        $stmt->execute([
            $current_time, 
            $visit_id
        ]);
        
        // Commit transaction
        $pdo->commit();
        
        $_SESSION['flash'] = ['success' => true, 'message' => 'Patient discharged successfully. Treatment completed.', 'color' => '#28a745'];
        header("Location: visit_ticket.php?id=" . $visit_id);
        exit;
        
    } catch (PDOException $e) {
        // Rollback on error
        $pdo->rollBack();
        $_SESSION['flash'] = ['success' => false, 'message' => 'Error discharging patient: ' . $e->getMessage(), 'color' => '#dc3545'];
        header("Location: visit_ticket.php?id=" . $visit_id);
        exit;
    }
}

/* ================= Get Visit ID ================= */
$visit_id = (int)($_GET['id'] ?? 0);
if (!$visit_id) {
    $_SESSION['flash'] = ['message'=>'Invalid Visit ID','color'=>'#dc3545'];
    header("Location: all_visits.php"); exit;
}

/* ================= Fetch Visit & Patient Details ================= */
$stmt = $pdo->prepare("
    SELECT v.*, 
           p.id AS patient_id, p.first_name, p.middle_name, p.last_name,
           p.d_o_b, p.gender, p.phone, p.email,
           p.country, p.province, p.district, p.sector, p.cell, p.village,
           p.file_id,
           d.name AS department_name,
           u.username AS doctor_name,
           i.name AS insurance_name,
           inv.id AS invoice_id,
           inv.invoice_number
    FROM visits v
    JOIN patients p ON p.id = v.patient_id
    LEFT JOIN departments d ON d.id = v.department_id
    LEFT JOIN users u ON u.id = v.treated_by
    LEFT JOIN insurance_partners i ON i.id = v.insurance_id
    LEFT JOIN invoices inv ON inv.visit_id = v.id
    WHERE v.id = ?
");
$stmt->execute([$visit_id]);
$visit = $stmt->fetch(PDO::FETCH_ASSOC);

/* ================= Visit Status & Permissions ================= */
$isVisitClosed = ($visit['status'] === 'closed');
$canReopenVisit = in_array($_SESSION['user_role'], ['Admin', 'Super_admin']);

if (!$visit) {
    $_SESSION['flash'] = ['message' => 'Visit not found.', 'color' => '#dc3545'];
    header('Location: all_visits.php'); exit;
}

/* ================= Facility Access Control ================= */
if (!isset($_SESSION['facility_id'])) die("Facility not set");
$facility_id = (int) $_SESSION['facility_id'];
$patient_facility_id = $visit['facility_id'] ?? 0;
if ($_SESSION['user_role'] !== 'Super_admin' && $facility_id != $patient_facility_id) {
    $_SESSION['flash'] = ['message'=>'Unauthorized access','color'=>'#dc3545'];
    header("Location: all_visits.php"); exit;
}

/* ================= Determine View Link Based on Role ================= */
$role = $_SESSION['user_role'] ?? '';
$view_link = in_array($role, ['Receptionist', 'Cashier', 'Doctor','Nurse']) 
    ? (!empty($visit['invoice_id']) ? "invoices.php?id={$visit['invoice_id']}" : "invoices.php?visit_id={$visit_id}&patient_id={$visit['patient_id']}")
    : "visit_ticket.php?id={$visit_id}";

/* ================= Format Address ================= */
$address = preg_replace('/\s+/', ' ', trim($visit['country'].' '.$visit['province'].' '.$visit['district'].' '.$visit['sector'].' '.$visit['cell'].' '.$visit['village']));

/* ================= Fetch or Create Visit Ticket ================= */
$stmt = $pdo->prepare("SELECT * FROM visit_tickets WHERE visit_id=? LIMIT 1");
$stmt->execute([$visit_id]);
$ticket = $stmt->fetch(PDO::FETCH_ASSOC);

if ($ticket) {
    $ticket_id = $ticket['id'];
} else {
    $ticket_no = 'VT-' . date('Ymd') . '-' . $visit_id;
    $pdo->prepare("INSERT INTO visit_tickets (visit_id, patient_id, visit_number, new_case) VALUES (?, ?, ?, 'Yes')")
        ->execute([$visit_id, $visit['patient_id'], $ticket_no]);
    $ticket_id = $pdo->lastInsertId();
    $ticket = ['id'=>$ticket_id, 'visit_number'=>$ticket_no];
}

/* ================= Fetch Doctors ================= */
$stmt = $pdo->prepare("SELECT id, username FROM users WHERE user_role='Doctor' AND status='active'");
$stmt->execute();
$doctors = $stmt->fetchAll(PDO::FETCH_ASSOC);

/* ================= Fetch Lab Products ================= */
$labProductsStmt = $pdo->prepare("
    SELECT * 
    FROM products 
    WHERE category_type='lab_test' 
      AND status='enabled'
      AND facility_id = ?
");
$labProductsStmt->execute([$facility_id]);
$labProducts = $labProductsStmt->fetchAll(PDO::FETCH_ASSOC);

/* ================= Initialize Ticket Data ================= */
$existingLabOrders  = [];
$requestedLabIds    = [];
$imagingReports     = [];
$hmis_report = [];

/* ================= Fetch Existing Lab Orders ================= */
if (!empty($ticket)) {
    $stmtLab = $pdo->prepare("
        SELECT lo.id AS lab_order_id, lo.product_id, lo.result_value, lo.status,
               p.name AS lab_name,
               pr.category_id AS lab_test_category_id,
               lt.sub_tests
        FROM lab_orders lo
        JOIN products p ON lo.product_id = p.id
        LEFT JOIN products pr ON pr.id = lo.product_id
        LEFT JOIN lab_test lt ON lt.id = pr.category_id
        WHERE lo.visit_ticket_id = ? AND lo.facility_id = ?
        ORDER BY lo.id
    ");
    $stmtLab->execute([$ticket_id, $facility_id]);
    $existingLabOrders = $stmtLab->fetchAll(PDO::FETCH_ASSOC);
    $requestedLabIds = array_column($existingLabOrders, 'product_id');

    foreach ($existingLabOrders as &$lab) {
        $lab['sub_tests'] = !empty($lab['sub_tests']) ? json_decode($lab['sub_tests'], true) : [];
        if (is_string($lab['result_value']) && $lab['result_value'] !== '') {
            $decoded = json_decode($lab['result_value'], true);
            $lab['result_value'] = $decoded !== null ? $decoded : $lab['result_value'];
        }
    }
    unset($lab);

    $imagingReports = !empty($ticket['imaging_reports']) ? json_decode($ticket['imaging_reports'], true) : [];

    /* ================== Existing HMIS Report ================== */
    $hmis_report = !empty($ticket['hmis_report']) ? json_decode($ticket['hmis_report'], true) : [];
}

/* ================== Fetch HMIS Indicators grouped by category ================== */
$facility_id = $_SESSION['facility_id'] ?? null; // current facility

$sql = "
    SELECT hi.id, hi.indicator_name, hi.description,
           hc.id AS category_id, hc.name AS category_name,
           hc.gender, hc.min_years, hc.max_years, hc.age_ranges
    FROM hmis_indicators hi
    JOIN hmis_category hc ON hi.category_id = hc.id
    WHERE hc.status = 'active'
      AND (hc.facility_id IS NULL OR hc.facility_id = :facility_id)
    ORDER BY hc.name, hi.indicator_name
";

$stmt = $pdo->prepare($sql);
$stmt->execute([
    ':facility_id' => $facility_id
]);

$all_hmis = $stmt->fetchAll(PDO::FETCH_ASSOC);

/* ================== Group HMIS by Category ================== */
$grouped_hmis = [];
foreach ($all_hmis as $h) {
    $grouped_hmis[$h['category_name']][] = [
        'id' => $h['id'],
        'indicator_name' => $h['indicator_name'],
        'description' => $h['description'],
        'gender' => $h['gender'],        // male, female, or NULL
        'min_years' => $h['min_years'],
        'max_years' => $h['max_years'],
        'age_ranges' => $h['age_ranges'] // JSON text, e.g., ["0-1","1-5","5-14"]
    ];
}

/* ================= Check if history table exists ================= */
$historyTableExists = false;
try {
    $stmtCheck = $pdo->query("SHOW TABLES LIKE 'visit_ticket_history'");
    $historyTableExists = $stmtCheck->rowCount() > 0;
} catch (PDOException $e) {
    $historyTableExists = false;
}

/* ================= BLOCK CHANGES IF VISIT IS CLOSED ================= */
if ($isVisitClosed && $_SERVER['REQUEST_METHOD'] === 'POST' && !isset($_POST['save_section']) && !isset($_POST['reopen_visit']) && !isset($_POST['discharge_patient'])) {
    $_SESSION['flash'] = ['message' => 'This visit is CLOSED. No changes are allowed.','color'=>'#dc3545'];
    header("Location: visit_ticket.php?id=$visit_id");
    exit;
}

/* ================= Handle Section-Based Form Submission ================= */
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_section'])) {
    // Verify CSRF token
    if (!isset($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
        die('Invalid CSRF token');
    }
    
    $section = $_POST['section'] ?? '';
    
    // BLOCK if visit is closed and user is trying to save a section
    if ($isVisitClosed && !isset($_POST['reopen_visit'])) {
        $_SESSION['flash'] = ['message' => 'This visit is CLOSED. No changes are allowed.', 'color' => '#dc3545'];
        header("Location: visit_ticket.php?id=$visit_id");
        exit;
    }

    // ================== Determine/Update treated_by ==================
    $current_user_id = $_SESSION['user_id'];
    $current_user_role = $_SESSION['user_role'];
    
    // Get or set treated_by based on logic
    $treated_by_user = get_or_set_treated_by($visit, $current_user_id, $current_user_role, $pdo);
    
    // If treated_by should be set (user is Doctor/Dentist/Admin/Super_admin and not Nurse)
    // and visit doesn't have treated_by yet, update it
    if ($treated_by_user && empty($visit['treated_by'])) {
        try {
            $stmtUpdateVisit = $pdo->prepare("UPDATE visits SET treated_by = ? WHERE id = ?");
            $stmtUpdateVisit->execute([$treated_by_user, $visit_id]);
            
            // Update local visit array to reflect the change
            $visit['treated_by'] = $treated_by_user;
        } catch (PDOException $e) {
            // Log error but don't stop execution
            error_log("Error updating treated_by: " . $e->getMessage());
        }
    }

    // Get current user for logging
    $changed_by = $_SESSION['user_id'];

    switch ($section) {
        case 'catchment':
            $catchment_area = trim($_POST['catchment_area'] ?? '');
            $new_case = trim($_POST['new_case'] ?? '');
            
            // Get old values
            $old_catchment_area = $ticket['catchment_area'] ?? '';
            $old_new_case = $ticket['new_case'] ?? '';
            
            $stmt = $pdo->prepare("UPDATE visit_tickets SET catchment_area = ?, new_case = ? WHERE id = ?");
            $stmt->execute([$catchment_area, $new_case, $ticket_id]);
            
            // Log changes if history table exists
            if ($historyTableExists) {
                $old_data = json_encode(['catchment_area' => $old_catchment_area, 'new_case' => $old_new_case]);
                $new_data = json_encode(['catchment_area' => $catchment_area, 'new_case' => $new_case]);
                logSectionChange($pdo, $ticket_id, 'catchment', $old_data, $new_data, $changed_by);
            }
            
            // Update local ticket array
            $ticket['catchment_area'] = $catchment_area;
            $ticket['new_case'] = $new_case;
            
            $_SESSION['flash'] = ['message' => 'Catchment area saved successfully!', 'color' => '#28a745'];
            break;
            
        case 'vital_signs':
            $vitals = [
                'systolic' => $_POST['systolic'] ?? null,
                'diastolic' => $_POST['diastolic'] ?? null,
                'heart_rate' => $_POST['heart_rate'] ?? null,
                'temperature' => $_POST['temperature'] ?? null,
                'resp_rate' => $_POST['resp_rate'] ?? null,
                'spo2' => $_POST['spo2'] ?? null,
                'weight' => $_POST['weight'] ?? null,
                'height' => $_POST['height'] ?? null,
                'vital_comment' => $_POST['vital_comment'] ?? null
            ];
            
            // Get old values
            $old_vitals = [
                'systolic' => $ticket['systolic'] ?? null,
                'diastolic' => $ticket['diastolic'] ?? null,
                'heart_rate' => $ticket['heart_rate'] ?? null,
                'temperature' => $ticket['temperature'] ?? null,
                'resp_rate' => $ticket['resp_rate'] ?? null,
                'spo2' => $ticket['spo2'] ?? null,
                'weight' => $ticket['weight'] ?? null,
                'height' => $ticket['height'] ?? null,
                'vital_comment' => $ticket['vital_comment'] ?? null
            ];
            
            $stmt = $pdo->prepare("
                UPDATE visit_tickets SET 
                    systolic = ?, diastolic = ?, heart_rate = ?,
                    temperature = ?, resp_rate = ?, spo2 = ?, 
                    weight = ?, height = ?, vital_comment = ?
                WHERE id = ?
            ");
            $stmt->execute([
                $vitals['systolic'], $vitals['diastolic'], $vitals['heart_rate'],
                $vitals['temperature'], $vitals['resp_rate'], $vitals['spo2'],
                $vitals['weight'], $vitals['height'], $vitals['vital_comment'],
                $ticket_id
            ]);
            
            // Log all vital changes as a single entry if history table exists
            if ($historyTableExists) {
                $old_data = json_encode($old_vitals);
                $new_data = json_encode($vitals);
                logSectionChange($pdo, $ticket_id, 'vital_signs', $old_data, $new_data, $changed_by);
            }
            
            // Update local ticket array
            $ticket = array_merge($ticket, $vitals);
            
            $_SESSION['flash'] = ['message' => 'Vital signs saved successfully!', 'color' => '#28a745'];
            break;
            
        case 'chief_complaints':
            $chief_complaints = trim($_POST['chief_complaints'] ?? '');
            $old_chief_complaints = $ticket['chief_complaints'] ?? '';
            
            $stmt = $pdo->prepare("UPDATE visit_tickets SET chief_complaints = ? WHERE id = ?");
            $stmt->execute([$chief_complaints, $ticket_id]);
            
            // Log change if history table exists
            if ($historyTableExists) {
                logSectionChange($pdo, $ticket_id, 'chief_complaints', $old_chief_complaints, $chief_complaints, $changed_by);
            }
            
            // Update local ticket array
            $ticket['chief_complaints'] = $chief_complaints;
            
            $_SESSION['flash'] = ['message' => 'Chief complaints saved successfully!', 'color' => '#28a745'];
            break;
            
        case 'physical_examination':
            $physical_examination = trim($_POST['physical_examination'] ?? '');
            $old_physical_examination = $ticket['physical_examination'] ?? '';
            
            $stmt = $pdo->prepare("UPDATE visit_tickets SET physical_examination = ? WHERE id = ?");
            $stmt->execute([$physical_examination, $ticket_id]);
            
            // Log change if history table exists
            if ($historyTableExists) {
                logSectionChange($pdo, $ticket_id, 'physical_examination', $old_physical_examination, $physical_examination, $changed_by);
            }
            
            // Update local ticket array
            $ticket['physical_examination'] = $physical_examination;
            
            $_SESSION['flash'] = ['message' => 'Physical examination saved successfully!', 'color' => '#28a745'];
            break;
            
        case 'differential_diagnosis':
            $differential_diagnosis = trim($_POST['differential_diagnosis'] ?? '');
            $old_differential_diagnosis = $ticket['differential_diagnosis'] ?? '';
            
            $stmt = $pdo->prepare("UPDATE visit_tickets SET differential_diagnosis = ? WHERE id = ?");
            $stmt->execute([$differential_diagnosis, $ticket_id]);
            
            // Log change if history table exists
            if ($historyTableExists) {
                logSectionChange($pdo, $ticket_id, 'differential_diagnosis', $old_differential_diagnosis, $differential_diagnosis, $changed_by);
            }
            
            // Update local ticket array
            $ticket['differential_diagnosis'] = $differential_diagnosis;
            
            $_SESSION['flash'] = ['message' => 'Differential diagnosis saved successfully!', 'color' => '#28a745'];
            break;
            
        case 'lab_orders':
            // Get current user info
            $current_user_id = $_SESSION['user_id'];
            $current_user_role = $_SESSION['user_role'];
            
            // Determine who requested the lab order
            $requested_by_user = null;
            
            // If we have a treated_by doctor, use them
            if (!empty($visit['treated_by'])) {
                $requested_by_user = $visit['treated_by'];
            } 
            // If current user can be treated_by (not Nurse), use current user
            elseif (can_be_treated_by($current_user_role) && $current_user_role !== 'Nurse') {
                $requested_by_user = $current_user_id;
            }
            // For Nurses or if no treated_by, use current user as fallback
            else {
                $requested_by_user = $current_user_id;
            }
            
            // Ensure we have a valid user ID (not null)
            if (empty($requested_by_user)) {
                // Fallback to any active doctor from facility
                $stmtDoctor = $pdo->prepare("
                    SELECT id FROM users 
                    WHERE user_role IN ('Doctor', 'Dentist') 
                    AND status='active' 
                    AND facility_id = ? 
                    LIMIT 1
                ");
                $stmtDoctor->execute([$facility_id]);
                $requested_by_user = $stmtDoctor->fetchColumn() ?? 1;
            }
            
            $submittedLabIds = $_POST['lab_test_id'] ?? [];
            $submittedLabValues = $_POST['lab_value'] ?? [];
            
            // Get lab test names for history logging
            $previousLabNames = getLabTestNames($requestedLabIds, $pdo);
            
            // Track changes for logging
            $labChanges = [];
            $currentLabNames = [];
            
            if (!empty($submittedLabIds)) {
                foreach ($submittedLabIds as $idx => $lab_id) {
                    if (empty($lab_id)) continue;
                    $lab_value = $submittedLabValues[$idx] ?? null;

                    // Get lab name for this test
                    $stmtName = $pdo->prepare("SELECT name FROM products WHERE id = ?");
                    $stmtName->execute([$lab_id]);
                    $labName = $stmtName->fetchColumn();
                    $currentLabNames[$lab_id] = $labName ?: "Test ID: $lab_id";

                    // Check if lab order already exists for this ticket, product, and facility
                    $stmtCheck = $pdo->prepare("
                        SELECT id, result_value 
                        FROM lab_orders 
                        WHERE visit_ticket_id=? AND product_id=? AND facility_id=? 
                        LIMIT 1
                    ");
                    $stmtCheck->execute([$ticket_id, $lab_id, $visit['facility_id']]);
                    $existingOrder = $stmtCheck->fetch(PDO::FETCH_ASSOC);

                    if ($existingOrder) {
                        // Update result_value if new data provided
                        $existing_result = json_decode($existingOrder['result_value'], true);
                        if ($existing_result === null) $existing_result = [];

                        if (is_array($lab_value)) {
                            $final_value = json_encode(array_merge($existing_result, $lab_value));
                        } else {
                            $final_value = $lab_value ?? $existingOrder['result_value'];
                        }

                        // Check if value actually changed
                        $old_value = $existingOrder['result_value'];
                        if ($old_value != $final_value) {
                            $stmt = $pdo->prepare("UPDATE lab_orders SET result_value=? WHERE id=?");
                            $stmt->execute([$final_value, $existingOrder['id']]);
                            
                            // Track change for logging
                            $labChanges[] = [
                                'action' => 'updated',
                                'lab_name' => $currentLabNames[$lab_id],
                                'lab_id' => $existingOrder['id']
                            ];
                        }

                    } else {
                        // Safe insert
                        if (is_array($lab_value)) $lab_value = json_encode($lab_value);
                        $stmt = $pdo->prepare("
                            INSERT INTO lab_orders 
                            (visit_ticket_id, patient_id, product_id, requested_by, status, result_value, facility_id)
                            VALUES (?, ?, ?, ?, 'pending', ?, ?)
                        ");
                        $stmt->execute([
                            $ticket_id,
                            $visit['patient_id'],
                            $lab_id,
                            $requested_by_user,
                            $lab_value,
                            $visit['facility_id']
                        ]);
                        
                        $new_lab_order_id = $pdo->lastInsertId();
                        
                        // Track addition for logging
                        $labChanges[] = [
                            'action' => 'added',
                            'lab_name' => $currentLabNames[$lab_id],
                            'lab_id' => $new_lab_order_id
                        ];
                    }
                }
            }
            
            // DELETE REMOVED LAB ORDERS & RELATED INVOICES
            $labIdsToDelete = array_diff($requestedLabIds, $submittedLabIds);

            if (!empty($labIdsToDelete)) {
                $placeholders = implode(',', array_fill(0, count($labIdsToDelete), '?'));

                // Fetch lab_order IDs to delete, filtered by facility
                $stmt = $pdo->prepare("
                    SELECT lo.id, lo.product_id, p.name 
                    FROM lab_orders lo
                    JOIN products p ON lo.product_id = p.id
                    WHERE lo.visit_ticket_id = ? 
                      AND lo.product_id IN ($placeholders)
                      AND lo.facility_id = ?
                ");
                $params = array_merge([$ticket_id], $labIdsToDelete, [$visit['facility_id']]);
                $stmt->execute($params);
                $labOrdersToDelete = $stmt->fetchAll(PDO::FETCH_ASSOC);

                if (!empty($labOrdersToDelete)) {
                    $labOrderIds = array_column($labOrdersToDelete, 'id');
                    $placeholdersLabOrder = implode(',', array_fill(0, count($labOrderIds), '?'));

                    // Delete invoices associated with these lab orders
                    $sqlInvoice = "DELETE FROM invoices WHERE lab_order_id IN ($placeholdersLabOrder)";
                    $pdo->prepare($sqlInvoice)->execute($labOrderIds);

                    // Delete the lab orders themselves
                    $sqlLab = "DELETE FROM lab_orders WHERE id IN ($placeholdersLabOrder)";
                    $pdo->prepare($sqlLab)->execute($labOrderIds);
                    
                    // Track deletions for logging
                    foreach ($labOrdersToDelete as $deletedOrder) {
                        $labChanges[] = [
                            'action' => 'deleted',
                            'lab_name' => $deletedOrder['name'] ?: "Test ID: " . $deletedOrder['product_id'],
                            'lab_id' => $deletedOrder['id']
                        ];
                    }
                }
            }
            
            // Update lab_order_ids in visit_tickets table
            $lab_order_ids_json = json_encode($submittedLabIds);
            $stmt = $pdo->prepare("UPDATE visit_tickets SET lab_order_ids = ? WHERE id = ?");
            $stmt->execute([$lab_order_ids_json, $ticket_id]);
            
            // Log all lab changes as a single entry if history table exists
            if ($historyTableExists && !empty($labChanges)) {
                // Create user-friendly history data
                $old_data = json_encode([
                    'previous_lab_names' => array_values($previousLabNames),
                    'previous_lab_count' => count($previousLabNames)
                ]);
                
                $new_data = json_encode([
                    'lab_changes' => $labChanges,
                    'current_lab_names' => array_values($currentLabNames),
                    'current_lab_count' => count($currentLabNames)
                ]);
                
                logSectionChange($pdo, $ticket_id, 'lab_orders', $old_data, $new_data, $changed_by);
            }
            
            $_SESSION['flash'] = ['message' => 'Lab orders saved successfully!', 'color' => '#28a745'];
            break;
            
        case 'imaging_reports':
            $imaging_reports = [];
            if (!empty($_POST['imaging_type'])) {
                foreach ($_POST['imaging_type'] as $i => $type) {
                    if (empty($type) && empty($_POST['imaging_report'][$i]) && empty($_POST['imaging_recommendation'][$i])) continue;
                    $imaging_reports[] = [
                        'type' => $type,
                        'report' => $_POST['imaging_report'][$i] ?? '',
                        'recommendation' => $_POST['imaging_recommendation'][$i] ?? ''
                    ];
                }
            }
            
            $imaging_json = json_encode($imaging_reports);
            $old_imaging_json = $ticket['imaging_reports'] ?? '[]';
            
            $stmt = $pdo->prepare("UPDATE visit_tickets SET imaging_reports = ? WHERE id = ?");
            $stmt->execute([$imaging_json, $ticket_id]);
            
            // Log change if history table exists
            if ($historyTableExists) {
                logSectionChange($pdo, $ticket_id, 'imaging_reports', $old_imaging_json, $imaging_json, $changed_by);
            }
            
            // Update local ticket array
            $ticket['imaging_reports'] = $imaging_json;
            
            $_SESSION['flash'] = ['message' => 'Imaging reports saved successfully!', 'color' => '#28a745'];
            break;
            
        case 'final_diagnoses':
            $final_diag_title = $_POST['final_diagnosis_title'] ?? [];
            $final_diag_code = $_POST['final_diagnosis_code'] ?? [];
            $final_diag_comment = $_POST['final_diagnosis_comment'] ?? [];
            
            // Filter out empty rows
            $filtered_titles = [];
            $filtered_codes = [];
            $filtered_comments = [];
            
            for ($i = 0; $i < count($final_diag_title); $i++) {
                $title = trim($final_diag_title[$i] ?? '');
                $code = trim($final_diag_code[$i] ?? '');
                $comment = trim($final_diag_comment[$i] ?? '');
                
                if (!empty($title) || !empty($code) || !empty($comment)) {
                    $filtered_titles[] = $title;
                    $filtered_codes[] = $code;
                    $filtered_comments[] = $comment;
                }
            }
            
            $titles_json = json_encode($filtered_titles);
            $codes_json = json_encode($filtered_codes);
            $comments_json = json_encode($filtered_comments);
            
            // Get old values
            $old_titles = json_decode($ticket['final_diagnosis_title'] ?? '[]', true) ?: [];
            $old_codes = json_decode($ticket['final_diagnosis_code'] ?? '[]', true) ?: [];
            $old_comments = json_decode($ticket['final_diagnosis_comment'] ?? '[]', true) ?: [];
            
            $stmt = $pdo->prepare("
                UPDATE visit_tickets SET 
                    final_diagnosis_title = ?, 
                    final_diagnosis_code = ?, 
                    final_diagnosis_comment = ? 
                WHERE id = ?
            ");
            $stmt->execute([$titles_json, $codes_json, $comments_json, $ticket_id]);
            
            // Log all changes as a single entry if history table exists
            if ($historyTableExists) {
                $old_data = json_encode([
                    'titles' => $old_titles,
                    'codes' => $old_codes,
                    'comments' => $old_comments
                ]);
                $new_data = json_encode([
                    'titles' => $filtered_titles,
                    'codes' => $filtered_codes,
                    'comments' => $filtered_comments
                ]);
                logSectionChange($pdo, $ticket_id, 'final_diagnoses', $old_data, $new_data, $changed_by);
            }
            
            // Update local ticket array
            $ticket['final_diagnosis_title'] = $titles_json;
            $ticket['final_diagnosis_code'] = $codes_json;
            $ticket['final_diagnosis_comment'] = $comments_json;
            
            $_SESSION['flash'] = ['message' => 'Final diagnoses saved successfully!', 'color' => '#28a745'];
            break;
            
        case 'other_management':
            $other_management = trim($_POST['other_management'] ?? '');
            $old_other_management = $ticket['other_management'] ?? '';
            
            $stmt = $pdo->prepare("UPDATE visit_tickets SET other_management = ? WHERE id = ?");
            $stmt->execute([$other_management, $ticket_id]);
            
            // Log change if history table exists
            if ($historyTableExists) {
                logSectionChange($pdo, $ticket_id, 'other_management', $old_other_management, $other_management, $changed_by);
            }
            
            // Update local ticket array
            $ticket['other_management'] = $other_management;
            
            $_SESSION['flash'] = ['message' => 'Other management saved successfully!', 'color' => '#28a745'];
            break;
            
        case 'hmis_report':
            $hmis_report = $_POST['hmis_report'] ?? [];
            $hmis_json = json_encode(array_filter($hmis_report));
            $old_hmis_json = $ticket['hmis_report'] ?? '[]';
            
            $stmt = $pdo->prepare("UPDATE visit_tickets SET hmis_report = ? WHERE id = ?");
            $stmt->execute([$hmis_json, $ticket_id]);
            
            // Log change if history table exists
            if ($historyTableExists) {
                logSectionChange($pdo, $ticket_id, 'hmis_report', $old_hmis_json, $hmis_json, $changed_by);
            }
            
            // Update local ticket array
            $ticket['hmis_report'] = $hmis_json;
            
            $_SESSION['flash'] = ['message' => 'HMIS report saved successfully!', 'color' => '#28a745'];
            break;
            
        default:
            $_SESSION['flash'] = ['message' => 'Invalid section specified.', 'color' => '#dc3545'];
            break;
    }
    
    // Redirect back to the same page
    header("Location: visit_ticket.php?id=$visit_id");
    exit;
}

/* ================= Handle Old Full Form Submission (for backward compatibility) ================= */
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_ticket'])) {
    if (!isset($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
        die('Invalid CSRF token');
    }

    // ================== Determine/Update treated_by ==================
    $current_user_id = $_SESSION['user_id'];
    $current_user_role = $_SESSION['user_role'];
    
    // Get or set treated_by based on logic
    $treated_by_user = get_or_set_treated_by($visit, $current_user_id, $current_user_role, $pdo);
    
    // If treated_by should be set (user is Doctor/Dentist/Admin/Super_admin and not Nurse)
    // and visit doesn't have treated_by yet, update it
    if ($treated_by_user && empty($visit['treated_by'])) {
        try {
            $stmtUpdateVisit = $pdo->prepare("UPDATE visits SET treated_by = ? WHERE id = ?");
            $stmtUpdateVisit->execute([$treated_by_user, $visit_id]);
            
            // Update local visit array to reflect the change
            $visit['treated_by'] = $treated_by_user;
        } catch (PDOException $e) {
            // Log error but don't stop execution
            error_log("Error updating treated_by: " . $e->getMessage());
        }
    }

    // ================== Vital Signs ==================
    $vitals = [
        'systolic'=> $_POST['systolic'] ?? null,
        'diastolic'=> $_POST['diastolic'] ?? null,
        'heart_rate'=> $_POST['heart_rate'] ?? null,
        'temperature'=> $_POST['temperature'] ?? null,
        'resp_rate'=> $_POST['resp_rate'] ?? null,
        'spo2'=> $_POST['spo2'] ?? null,
        'weight'=> $_POST['weight'] ?? null,
        'height'=> $_POST['height'] ?? null,
        'vital_comment'=> $_POST['vital_comment'] ?? null
    ];

    // ================== History ==================
    $history = [
        'chief_complaints'=> $_POST['chief_complaints'] ?? null,
        'physical_examination'=> $_POST['physical_examination'] ?? null,
        'differential_diagnosis'=> $_POST['differential_diagnosis'] ?? null,
        'other_management'=> $_POST['other_management'] ?? null
    ];

    // ================== Final Diagnoses ==================
    $final_diag_title   = $_POST['final_diagnosis_title'] ?? [];
    $final_diag_code    = $_POST['final_diagnosis_code'] ?? [];
    $final_diag_comment = $_POST['final_diagnosis_comment'] ?? [];
    $diag_count = max(count($final_diag_title), count($final_diag_code), count($final_diag_comment));
    $final_diag_title   = array_pad($final_diag_title, $diag_count, '');
    $final_diag_code    = array_pad($final_diag_code, $diag_count, '');
    $final_diag_comment = array_pad($final_diag_comment, $diag_count, '');

    // ================== Imaging Reports ==================
    $imaging_reports = [];
    if(!empty($_POST['imaging_type'])) {
        foreach ($_POST['imaging_type'] as $i => $type) {
            if (empty($type) && empty($_POST['imaging_report'][$i]) && empty($_POST['imaging_recommendation'][$i])) continue;
            $imaging_reports[] = [
                'type'=> $type,
                'report'=> $_POST['imaging_report'][$i] ?? '',
                'recommendation'=> $_POST['imaging_recommendation'][$i] ?? ''
            ];
        }
    }

    // ================== HMIS ==================
    $hmis_report = $_POST['hmis_report'] ?? []; // array of selected indicator IDs

    // ================== Catchment Area & New Case ==================
    $catchment_area = trim($_POST['catchment_area'] ?? '');
    $new_case       = trim($_POST['new_case'] ?? '');

    // ================== Update Visit Ticket ==================
    try {
        $stmt = $pdo->prepare("
            UPDATE visit_tickets SET
                systolic=?, diastolic=?, heart_rate=?,
                temperature=?, resp_rate=?, spo2=?, weight=?, height=?, vital_comment=?,
                chief_complaints=?,
                physical_examination=?, differential_diagnosis=?, other_management=?,
                final_diagnosis_title=?, final_diagnosis_code=?, final_diagnosis_comment=?,
                imaging_reports=?, hmis_report=?,
                catchment_area=?,
                new_case=?
            WHERE id=?
        ");

        $stmt->execute([
            $vitals['systolic'], $vitals['diastolic'], $vitals['heart_rate'],
            $vitals['temperature'], $vitals['resp_rate'], $vitals['spo2'],
            $vitals['weight'], $vitals['height'], $vitals['vital_comment'],
            $history['chief_complaints'],
            $history['physical_examination'], $history['differential_diagnosis'], $history['other_management'],
            json_encode($final_diag_title), json_encode($final_diag_code), json_encode($final_diag_comment),
            json_encode($imaging_reports), json_encode($hmis_report),
            $catchment_area,
            $new_case,
            $ticket_id
        ]);

        $_SESSION['flash'] = ['message'=>'Visit ticket updated successfully!','color'=>'#28a745'];
        header("Location: visit_ticket.php?id=$visit_id&ticket_id=$ticket_id");
        exit;

    } catch (PDOException $e) {
        $_SESSION['flash'] = ['message'=>'Error updating ticket: ' . $e->getMessage(),'color'=>'#dc3545'];
    }
}

/* ================= Fetch Patient-wide Treatment History ================= */
$stmt = $pdo->prepare("
    SELECT t.*, v.visit_date 
    FROM treatments t
    JOIN visits v ON v.id = t.visit_id
    WHERE v.patient_id = ?
    ORDER BY t.created_at DESC
");
$stmt->execute([$visit['patient_id']]);
$treatment_list = $stmt->fetchAll(PDO::FETCH_ASSOC);

ob_end_flush();
?>