<?php
// CRITICAL: Prevent PHP from outputting HTML warnings that corrupt JSON
error_reporting(0);
ini_set('display_errors', 0);
ob_start(); 

if (session_status() === PHP_SESSION_NONE) { session_start(); }

require_once '../db.php';

header('Content-Type: application/json');

function getAge($dob) {
    if (empty($dob) || $dob === '0000-00-00') return 'N/A';
    $date = date_create($dob);
    if (!$date) return 'N/A';
    return date_diff($date, date_create('today'))->y;
}

try {
    // ==========================================
    // BULLETPROOF ISOLATED AUTO-HEALING
    // ==========================================
    $conn->query("CREATE TABLE IF NOT EXISTS `ipd_admission_episodes` (
        `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
        `patient_no` varchar(30) NOT NULL,
        `visit_master_id` bigint(20) UNSIGNED DEFAULT NULL,
        `request_id` int(10) UNSIGNED DEFAULT NULL,
        `ward_id` int(10) UNSIGNED NOT NULL,
        `room_id` int(10) UNSIGNED DEFAULT NULL,
        `bed_id` int(10) UNSIGNED NOT NULL,
        `admission_source_id` int(11) DEFAULT NULL,
        `admission_priority_id` int(11) DEFAULT NULL,
        `admission_reason_id` int(11) DEFAULT NULL,
        `admission_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
        `discharge_date` datetime DEFAULT NULL,
        `status` enum('Admitted','Transferred','Discharged','Deceased') DEFAULT 'Admitted',
        `admitted_by` int(10) UNSIGNED NOT NULL,
        PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");

    $conn->query("ALTER TABLE `ipd_admission_episodes` MODIFY `room_id` int(10) UNSIGNED DEFAULT NULL;");

    $extended_columns = [
        'primary_doctor_id' => "int(10) UNSIGNED DEFAULT NULL",
        'provisional_diagnosis' => "varchar(255) DEFAULT NULL",
        'principal_complaint' => "text DEFAULT NULL",
        'is_referral' => "tinyint(1) DEFAULT 0",
        'referral_facility' => "varchar(150) DEFAULT NULL",
        'referral_date' => "date DEFAULT NULL",
        'admission_notes' => "text DEFAULT NULL"
    ];

    foreach ($extended_columns as $col_name => $col_definition) {
        $chkCol = $conn->query("SHOW COLUMNS FROM `ipd_admission_episodes` LIKE '$col_name'");
        if ($chkCol && $chkCol->num_rows == 0) {
            $conn->query("ALTER TABLE `ipd_admission_episodes` ADD COLUMN `$col_name` $col_definition");
        }
    }

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

    // ==========================================
    // 1. FETCH PENDING OPD ADMISSION REQUESTS (Strictly Filtered)
    // ==========================================
    if ($action === 'fetch_pending_requests') {
        $start_date = $_POST['start_date'] ?? date('Y-m-d');
        $end_date = $_POST['end_date'] ?? date('Y-m-d');
        $ward_filter = $_POST['ward'] ?? 'ALL';

        $sql = "SELECT r.id as request_id, r.patient_no, r.requested_ward, r.admission_diagnosis, 
                       r.created_at, p.first_name, p.last_name, p.gender_id, p.mobile,
                       s.first_name as doc_first, s.last_name as doc_last
                FROM clinical_admission_requests r
                JOIN patient p ON r.patient_no = p.patient_no
                LEFT JOIN staff s ON r.requested_by = s.staff_id
                WHERE r.status = 'Pending' 
                AND DATE(r.created_at) BETWEEN ? AND ?";
        
        if ($ward_filter !== 'ALL') {
            $sql .= " AND r.requested_ward = ?";
            $stmt = $conn->prepare($sql);
            $stmt->bind_param("sss", $start_date, $end_date, $ward_filter);
        } else {
            $stmt = $conn->prepare($sql);
            $stmt->bind_param("ss", $start_date, $end_date);
        }
        
        $stmt->execute();
        $res = $stmt->get_result();
        
        $data = [];
        if ($res) {
            while ($row = $res->fetch_assoc()) {
                $row['patient_name'] = trim($row['first_name'] . ' ' . $row['last_name']);
                $row['doctor_name'] = !empty($row['doc_first']) ? 'Dr. ' . $row['doc_first'] . ' ' . $row['doc_last'] : 'N/A';
                $data[] = $row;
            }
        }
        ob_end_clean(); echo json_encode(['data' => $data]); exit;
    }

    // ==========================================
    // 2. DIRECT ADMISSION: SEARCH PATIENT
    // ==========================================
    if ($action === 'search_patient') {
        $term = '%' . trim($_POST['search_term']) . '%';
        $sql = "SELECT p.patient_no, p.first_name, p.middle_name, p.last_name, p.dob, p.gender_id, p.mobile, p.ghana_card_no, p.patient_address,
                       p.blood_group, p.allergies, p.medical_conditions, p.emergency_name, p.emergency_number,
                       p.nhis_no, p.other_insurance_id, p.other_insurance_no,
                       i.insurance_name as corp_insurance_name
                FROM patient p
                LEFT JOIN insurance_type i ON p.other_insurance_id = i.id
                WHERE p.is_active = 1 AND (p.first_name LIKE ? OR p.last_name LIKE ? OR p.patient_no LIKE ? OR p.mobile LIKE ?) 
                LIMIT 15";
                
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("ssss", $term, $term, $term, $term);
        $stmt->execute();
        $res = $stmt->get_result();
        
        $data = [];
        while ($row = $res->fetch_assoc()) {
            $row['age'] = getAge($row['dob']);
            $row['gender'] = ($row['gender_id'] == 1) ? 'Male' : (($row['gender_id'] == 2) ? 'Female' : 'Unspecified');
            $row['full_name'] = trim($row['first_name'] . ' ' . ($row['middle_name'] ? $row['middle_name'] . ' ' : '') . $row['last_name']);
            $data[] = $row;
        }
        ob_end_clean(); echo json_encode(['status' => 'success', 'data' => $data]); exit;
    }

    // ==========================================
    // 3. GET CLINICAL PLAN (OPD) - Now fetches Principal Diagnosis & dynamic fields
    // ==========================================
    if ($action === 'get_clinical_plan') {
        $request_id = (int)$_POST['request_id'];
        
        $sql = "SELECT r.*, p.first_name, p.middle_name, p.last_name, p.dob, p.gender_id, p.mobile, p.ghana_card_no, p.patient_address,
                       p.blood_group, p.allergies, p.medical_conditions, p.emergency_name, p.emergency_number,
                       p.nhis_no, p.other_insurance_id, p.other_insurance_no,
                       n.chief_complaint, n.treatment_plan_notes,
                       v.payment_category, v.ccc_code,
                       i.insurance_name as corp_insurance_name
                FROM clinical_admission_requests r
                JOIN patient p ON r.patient_no = p.patient_no
                LEFT JOIN clinical_notes n ON r.visit_master_id = n.visit_id
                LEFT JOIN visit_master v ON r.visit_master_id = v.id
                LEFT JOIN insurance_type i ON p.other_insurance_id = i.id
                WHERE r.id = ?";
                
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("i", $request_id);
        $stmt->execute();
        $data = $stmt->get_result()->fetch_assoc();
        
        if($data) {
            $data['age'] = getAge($data['dob']);
            $data['gender'] = ($data['gender_id'] == 1) ? 'Male' : (($data['gender_id'] == 2) ? 'Female' : 'Unspecified');
            $data['patient_name'] = trim($data['first_name'] . ' ' . ($data['middle_name'] ? $data['middle_name'] . ' ' : '') . $data['last_name']);
            
            // Fetch Principal Diagnosis from clinical_diagnoses table
            $diag_res = $conn->query("SELECT code, description FROM clinical_diagnoses WHERE visit_id = {$data['visit_master_id']} AND is_principal = 1 LIMIT 1");
            if($diag_res && $dRow = $diag_res->fetch_assoc()) {
                $data['principal_diagnosis'] = $dRow['code'] . ' - ' . $dRow['description'];
            } else {
                $data['principal_diagnosis'] = $data['admission_diagnosis']; // Fallback
            }

            // FETCH DYNAMIC CONSULTATION RESPONSES
            $dyn_res = $conn->query("SELECT field_name, field_value FROM clinical_dynamic_responses WHERE visit_id = {$data['visit_master_id']}");
            $dynamic_fields = [];
            if($dyn_res) {
                while($dr = $dyn_res->fetch_assoc()) {
                    // Only fetch fields that are not empty
                    if(!empty(trim($dr['field_value']))) {
                        $dynamic_fields[$dr['field_name']] = $dr['field_value'];
                    }
                }
            }
            $data['dynamic_responses'] = $dynamic_fields;
        }
        
        ob_end_clean(); echo json_encode(['status' => 'success', 'data' => $data]); exit;
    }

    // ==========================================
    // 4. FETCH VITAL & LAB HISTORY
    // ==========================================
    if ($action === 'fetch_patient_history') {
        $visit_id = (int)$_POST['visit_id'];
        
        $v_res = $conn->query("SELECT temperature, pulse_rate as pulse, bp_systolic, bp_diastolic, respiratory_rate as respiration_rate, spo2, recorded_at as created_at FROM patient_vitals WHERE visit_id = $visit_id ORDER BY id DESC LIMIT 5");
        $vitals = []; 
        if($v_res) { while($r = $v_res->fetch_assoc()) $vitals[] = $r; }
        
        $l_res = $conn->query("SELECT id, test_name, status, request_date FROM clinical_lab_requests WHERE visit_id = $visit_id ORDER BY id DESC LIMIT 10");
        $labs = []; 
        if($l_res) { while($r = $l_res->fetch_assoc()) $labs[] = $r; }
        
        ob_end_clean(); echo json_encode(['status' => 'success', 'vitals' => $vitals, 'labs' => $labs]); exit;
    }

    // ==========================================
    // 4.1 FETCH DETAILED LAB RESULTS
    // ==========================================
    if ($action === 'fetch_lab_results') {
        $ids = $_POST['request_ids'] ?? [];
        if (empty($ids)) { echo json_encode(['status' => 'error', 'message' => 'No investigations selected.']); exit; }
        
        $id_list = implode(',', array_map('intval', $ids));
        $html = "";
        
        $reqs = $conn->query("SELECT id, test_name, pathologist_remarks, status FROM clinical_lab_requests WHERE id IN ($id_list)");
        
        while($r = $reqs->fetch_assoc()) {
            $statusBadge = ($r['status'] == 'Verified') ? "<span class='badge bg-success float-end'>Verified</span>" : "<span class='badge bg-warning text-dark float-end'>Completed (Unverified)</span>";
            $html .= "<div class='card shadow-sm border-0 mb-4 rounded-3'>";
            $html .= "<div class='card-header bg-white border-bottom pt-3 pb-2'><h6 class='fw-bold text-primary m-0'>{$r['test_name']} {$statusBadge}</h6></div>";
            $html .= "<div class='card-body p-0 table-responsive'>";
            
            $results = $conn->query("SELECT res.result_value, res.reference_range_used, res.result_flag, p.parameter_name, p.unit_of_measure FROM clinical_lab_results res JOIN lab_parameters p ON res.parameter_id = p.id WHERE res.request_id = {$r['id']}");
            
            if($results && $results->num_rows > 0) {
                $html .= "<table class='table table-sm table-hover align-middle m-0' style='font-size:13px;'>
                            <thead class='table-light'><tr><th class='ps-3'>Parameter</th><th>Result</th><th>Unit</th><th>Ref Range</th><th class='pe-3'>Flag</th></tr></thead><tbody>";
                while($row = $results->fetch_assoc()) {
                    $flagColor = ($row['result_flag'] == 'Normal') ? 'text-success fw-semibold' : 'text-danger fw-bold';
                    $html .= "<tr>
                                <td class='ps-3'>{$row['parameter_name']}</td>
                                <td class='fw-bold' style='color:#0f172a;'>{$row['result_value']}</td>
                                <td class='text-muted'>{$row['unit_of_measure']}</td>
                                <td class='text-muted'>{$row['reference_range_used']}</td>
                                <td class='{$flagColor} pe-3'>{$row['result_flag']}</td>
                              </tr>";
                }
                $html .= "</tbody></table>";
            } else {
                $html .= "<div class='p-4 text-center text-muted small'>No discrete parameter results found. Check remarks.</div>";
            }
            $html .= "</div>";
            
            if(!empty($r['pathologist_remarks'])) {
                $html .= "<div class='card-footer bg-light border-top-0 p-3'><p class='small m-0' style='color:#b45309;'><b><i class='fa-solid fa-user-doctor me-1'></i> Pathologist / Scientist Remarks:</b><br>{$r['pathologist_remarks']}</p></div>";
            }
            $html .= "</div>"; 
        }
        
        echo json_encode(['status' => 'success', 'html' => $html]);
        exit;
    }

    // ==========================================
    // 5. VISUAL INFRASTRUCTURE MATRIX
    // ==========================================
    if ($action === 'fetch_wards') {
        $res = $conn->query("SELECT id, ward_name, physical_bed_capacity, current_active_census FROM ipd_wards WHERE is_active = 1");
        $data = []; while($row = $res->fetch_assoc()) { $data[] = $row; }
        ob_end_clean(); echo json_encode(['status' => 'success', 'data' => $data]); exit;
    }

    if ($action === 'fetch_ward_matrix') {
        $ward_id = (int)$_POST['ward_id'];
        $res = $conn->query("SELECT id, room_number_or_name FROM ipd_rooms WHERE ward_id = $ward_id AND is_active = 1");
        $rooms = []; while($row = $res->fetch_assoc()) { $rooms[] = $row; }
        
        $res2 = $conn->query("SELECT b.id, b.bed_number, b.bed_status_id, s.status_name, s.is_admittable 
                              FROM ipd_beds b JOIN ipd_setup_bed_statuses s ON b.bed_status_id = s.id 
                              WHERE b.ward_id = $ward_id AND b.room_id IS NULL AND b.is_active = 1");
        $direct_beds = []; while($row = $res2->fetch_assoc()) { $direct_beds[] = $row; }
        
        ob_end_clean(); echo json_encode(['status' => 'success', 'rooms' => $rooms, 'direct_beds' => $direct_beds]); exit;
    }

    if ($action === 'fetch_room_beds') {
        $room_id = (int)$_POST['room_id'];
        $res = $conn->query("SELECT b.id, b.bed_number, b.bed_status_id, s.status_name, s.is_admittable 
                             FROM ipd_beds b JOIN ipd_setup_bed_statuses s ON b.bed_status_id = s.id 
                             WHERE b.room_id = $room_id AND b.is_active = 1");
        $beds = []; while($row = $res->fetch_assoc()) { $beds[] = $row; }
        ob_end_clean(); echo json_encode(['status' => 'success', 'beds' => $beds]); exit;
    }

    // ==========================================
    // 6. FETCH WORKFLOW DICTIONARIES
    // ==========================================
    if ($action === 'fetch_dictionaries') {
        $sources = []; $res = $conn->query("SELECT id, source_name as name FROM ipd_setup_admission_sources WHERE is_active = 1");
        while($row = $res->fetch_assoc()) $sources[] = $row;
        
        $priorities = []; $res = $conn->query("SELECT id, priority_level as name FROM ipd_setup_admission_priorities WHERE is_active = 1");
        while($row = $res->fetch_assoc()) $priorities[] = $row;
        
        $reasons = []; $res = $conn->query("SELECT id, reason_name as name FROM ipd_setup_admission_reasons WHERE is_active = 1");
        while($row = $res->fetch_assoc()) $reasons[] = $row;
        
        $doctors = []; $res = $conn->query("SELECT staff_id, first_name, last_name FROM staff WHERE is_doctor_id = 1 AND is_active = 1");
        while($row = $res->fetch_assoc()) { $doctors[] = ['id' => $row['staff_id'], 'name' => 'Dr. ' . $row['first_name'] . ' ' . $row['last_name']]; }

        $insurers = []; $res = $conn->query("SELECT id, company_name as name FROM corporate_insurance_providers WHERE is_active = 1");
        while($row = $res->fetch_assoc()) $insurers[] = $row;

        ob_end_clean(); echo json_encode(['status' => 'success', 'sources' => $sources, 'priorities' => $priorities, 'reasons' => $reasons, 'doctors' => $doctors, 'insurers' => $insurers]); exit;
    }

    // ==========================================
    // 7. FINAL ADMISSION SUBMISSION
    // ==========================================
    if ($action === 'admit_patient') {
        $conn->begin_transaction();
        
        $patient_no = trim($_POST['patient_no']);
        
        // CRITICAL CHECK: Prevent admitting a patient who is already admitted
        $chkActive = $conn->prepare("SELECT id, ward_id FROM ipd_admission_episodes WHERE patient_no = ? AND status IN ('Admitted', 'Transferred')");
        $chkActive->bind_param("s", $patient_no);
        $chkActive->execute();
        $resActive = $chkActive->get_result();
        if ($resActive->num_rows > 0) {
            throw new Exception("This patient is already actively admitted. You cannot process a new admission until the current one is discharged.");
        }
        $chkActive->close();

        $request_id = !empty($_POST['request_id']) ? (int)$_POST['request_id'] : null;
        $visit_id = !empty($_POST['visit_master_id']) ? (int)$_POST['visit_master_id'] : null;
        
        $ward_id = (int)$_POST['ward_id'];
        $room_id = !empty($_POST['room_id']) ? (int)$_POST['room_id'] : null;
        $bed_id = (int)$_POST['bed_id'];
        
        $source_id = (int)$_POST['admission_source'];
        $priority_id = (int)$_POST['admission_priority'];
        $reason_id = (int)$_POST['admission_reason'];
        $doctor_id = (int)$_POST['primary_doctor'];
        $notes = trim($_POST['admission_notes']);
        $prov_diagnosis = trim($_POST['provisional_diagnosis'] ?? '');
        $principal_comp = trim($_POST['principal_complaint'] ?? '');
        
        $payment_category = $_POST['payment_category'] ?? 'Cash';
        $ccc_code = !empty($_POST['ccc_code']) ? trim($_POST['ccc_code']) : null;
        
        $is_referral = isset($_POST['is_referral']) ? 1 : 0;
        $referral_facility = $is_referral ? trim($_POST['referral_facility']) : null;
        $referral_date = $is_referral ? trim($_POST['referral_date']) : null;

        $staff_id = $_SESSION['staff_id'] ?? 1;

        // Verify Bed Vacancy
        $chkBed = $conn->query("SELECT bed_status_id FROM ipd_beds WHERE id = $bed_id FOR UPDATE");
        $bedData = $chkBed->fetch_assoc();
        if(!$bedData || $bedData['bed_status_id'] != 1) {
            throw new Exception("The selected bed is no longer vacant. Please choose another bed.");
        }

        // Update Patient Insurance Details
        if ($payment_category === 'NHIS' && !empty($_POST['nhis_no'])) {
            $stmtP = $conn->prepare("UPDATE patient SET nhis_no = ? WHERE patient_no = ?");
            $stmtP->bind_param("ss", $_POST['nhis_no'], $patient_no); $stmtP->execute();
        } elseif ($payment_category === 'Corporate' && !empty($_POST['corp_provider_id'])) {
            $stmtP = $conn->prepare("UPDATE patient SET other_insurance_id = ?, other_insurance_no = ? WHERE patient_no = ?");
            $stmtP->bind_param("iss", $_POST['corp_provider_id'], $_POST['corp_policy_no'], $patient_no); $stmtP->execute();
        }

        // Handle Visit Linking (OPD vs Direct)
        if (empty($visit_id)) {
            $appt_no = 'IPD-' . date('Ymd') . '-' . rand(1000, 9999);
            $v_stmt = $conn->prepare("INSERT INTO visit_master (appointment_no, patient_no, primary_doctor_id, visit_date, visit_time, payment_category, nhis_service_type, billing_structure, ccc_code, status, attendance_type) VALUES (?, ?, ?, CURDATE(), CURTIME(), ?, 'In-patient', 'All Inclusive', ?, 'In Progress', 'EAE')");
            $v_stmt->bind_param("ssiss", $appt_no, $patient_no, $doctor_id, $payment_category, $ccc_code);
            $v_stmt->execute();
            $visit_id = $conn->insert_id;
        } else {
            if ($payment_category === 'NHIS' && !empty($ccc_code)) {
                $u_stmt = $conn->prepare("UPDATE visit_master SET ccc_code = ?, nhis_service_type = 'In-patient' WHERE id = ?");
                $u_stmt->bind_param("si", $ccc_code, $visit_id);
                $u_stmt->execute();
            } else {
                $conn->query("UPDATE visit_master SET nhis_service_type = 'In-patient' WHERE id = $visit_id");
            }
        }

        // Insert Admission Episode safely
        $stmt = $conn->prepare("INSERT INTO ipd_admission_episodes (patient_no, visit_master_id, request_id, ward_id, room_id, bed_id, admission_source_id, admission_priority_id, admission_reason_id, primary_doctor_id, provisional_diagnosis, principal_complaint, is_referral, referral_facility, referral_date, admission_notes, admitted_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
        $stmt->bind_param("siiiiiiiiiisisssi", $patient_no, $visit_id, $request_id, $ward_id, $room_id, $bed_id, $source_id, $priority_id, $reason_id, $doctor_id, $prov_diagnosis, $principal_comp, $is_referral, $referral_facility, $referral_date, $notes, $staff_id);
        $stmt->execute();
        $episode_id = $conn->insert_id;

        // Occupy Bed
        $stmt2 = $conn->prepare("UPDATE ipd_beds SET bed_status_id = 2, current_admission_episode_id = ? WHERE id = ?");
        $stmt2->bind_param("ii", $episode_id, $bed_id);
        $stmt2->execute();

        if ($request_id) {
            $stmt3 = $conn->prepare("UPDATE clinical_admission_requests SET status = 'Admitted' WHERE id = ?");
            $stmt3->bind_param("i", $request_id);
            $stmt3->execute();
        }
        
        $conn->query("UPDATE ipd_wards SET current_active_census = current_active_census + 1 WHERE id = $ward_id");

        $conn->commit();
        ob_end_clean(); echo json_encode(['status' => 'success', 'message' => 'Patient successfully admitted.', 'patient_no' => $patient_no]); exit;
    }

} catch (Exception $e) {
    if(isset($conn)) $conn->rollback();
    ob_end_clean(); echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); exit;
}
?>