<?php
session_start();
ini_set('display_errors', 0);
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
ob_start();

require_once '../db.php';
header('Content-Type: application/json');

$staff_id = (int)($_SESSION['staff_id'] ?? 1);
$action = $_POST['action'] ?? '';

$sys = $conn->query("SELECT date_format, time_format FROM system_workflow_rules LIMIT 1")->fetch_assoc();
$df = $sys['date_format'] ?? 'd-M-Y';
$tf = ($sys['time_format'] == '24') ? 'H:i' : 'h:i A';
$global_date_format = "$df, $tf";

try {
    // ==========================================
    // FETCH KPIs
    // ==========================================
    if ($action === 'fetch_kpis') {
        $date_today = date('Y-m-d');
        
        $kpi = [
            'pending_discharge' => 0, 'today_discharged' => 0,
            'housekeeping_beds' => 0, 'male_pending' => 0, 'female_pending' => 0,
            'ward_breakdown' => []
        ];

        $q = $conn->query("SELECT 
            SUM(CASE WHEN e.status = 'Pending Discharge' THEN 1 ELSE 0 END) as pending,
            SUM(CASE WHEN e.status = 'Pending Discharge' AND p.gender_id = 1 THEN 1 ELSE 0 END) as male_pend,
            SUM(CASE WHEN e.status = 'Pending Discharge' AND p.gender_id = 2 THEN 1 ELSE 0 END) as female_pend,
            SUM(CASE WHEN e.status = 'Discharged' AND DATE(e.discharge_date) = '$date_today' THEN 1 ELSE 0 END) as disc_today
            FROM ipd_admission_episodes e JOIN patient p ON e.patient_no = p.patient_no");
        
        if ($q && $row = $q->fetch_assoc()) {
            $kpi['pending_discharge'] = $row['pending'] ?? 0;
            $kpi['today_discharged'] = $row['disc_today'] ?? 0;
            $kpi['male_pending'] = $row['male_pend'] ?? 0;
            $kpi['female_pending'] = $row['female_pend'] ?? 0;
        }

        $qb = $conn->query("SELECT COUNT(id) as hk FROM ipd_beds WHERE bed_status_id = 4 OR bed_status LIKE '%Cleaning%' OR bed_status LIKE '%Housekeeping%'");
        if ($qb && $b = $qb->fetch_assoc()) $kpi['housekeeping_beds'] = $b['hk'] ?? 0;

        $qw = $conn->query("SELECT w.ward_name, COUNT(e.id) as cnt FROM ipd_admission_episodes e JOIN ipd_wards w ON e.ward_id = w.id WHERE e.status = 'Pending Discharge' GROUP BY w.ward_name ORDER BY cnt DESC LIMIT 5");
        if($qw) while($w = $qw->fetch_assoc()) $kpi['ward_breakdown'][] = $w;

        ob_end_clean(); echo json_encode(['status' => 'success', 'data' => $kpi]); exit;
    }

    // ==========================================
    // FETCH PENDING DISCHARGE QUEUE
    // ==========================================
    if ($action === 'fetch_pending_discharges') {
        $is_filtered = filter_var($_POST['is_filtered'] ?? 'false', FILTER_VALIDATE_BOOLEAN);
        if (!$is_filtered) { ob_end_clean(); echo json_encode(['status' => 'success', 'data' => []]); exit; }

        $ward_id = $_POST['ward_id'] ?? 'ALL';
        $start_date = $_POST['start_date'] ?? '';
        $end_date = $_POST['end_date'] ?? '';

        $sql = "SELECT e.id as episode_id, e.visit_master_id, e.patient_no, e.admission_date, e.status, e.discharge_outcome, e.next_review_date,
                       p.first_name, p.last_name, p.dob, g.gender_name,
                       w.ward_name, b.bed_number, rm.room_number_or_name,
                       vm.payment_category,
                       CONCAT(s.first_name, ' ', s.last_name) as doc_name
                FROM ipd_admission_episodes e
                JOIN patient p ON e.patient_no = p.patient_no
                LEFT JOIN gender g ON p.gender_id = g.id
                JOIN ipd_wards w ON e.ward_id = w.id
                JOIN ipd_beds b ON e.bed_id = b.id
                LEFT JOIN ipd_rooms rm ON e.room_id = rm.id
                LEFT JOIN visit_master vm ON e.visit_master_id = vm.id
                LEFT JOIN staff s ON e.primary_doctor_id = s.staff_id
                WHERE e.status = 'Pending Discharge'";

        if ($ward_id !== 'ALL') $sql .= " AND e.ward_id = " . (int)$ward_id;
        if (!empty($start_date) && !empty($end_date)) $sql .= " AND DATE(e.admission_date) BETWEEN '$start_date' AND '$end_date'";

        $res = $conn->query($sql);
        $data = [];
        if($res) {
            while($row = $res->fetch_assoc()) {
                $row['patient_name'] = trim($row['first_name'] . ' ' . $row['last_name']);
                $row['location_str'] = $row['ward_name'] . ($row['room_number_or_name'] ? ' ('.$row['room_number_or_name'].')' : '') . ' - ' . $row['bed_number'];
                $row['doctor_outcome'] = $row['discharge_outcome'] ?? 'Pending Discharge';
                
                $qDiag = $conn->query("SELECT description FROM clinical_diagnoses WHERE visit_id = {$row['visit_master_id']} AND is_principal = 1 LIMIT 1");
                $row['provisional_diagnosis'] = ($qDiag && $qDiag->num_rows > 0) ? $qDiag->fetch_assoc()['description'] : '<span class="text-danger"><i class="fa fa-triangle-exclamation"></i> No Principal Diagnosis</span>';
                $row['next_review_date_fmt'] = $row['next_review_date'] ? date($global_date_format, strtotime($row['next_review_date'])) : 'Not Scheduled';
                $data[] = $row;
            }
        }

        ob_end_clean(); echo json_encode(['status' => 'success', 'data' => $data]); exit;
    }

    // ==========================================
    // FETCH DISCHARGED HISTORY
    // ==========================================
    if ($action === 'fetch_discharged_history') {
        $is_filtered = filter_var($_POST['is_filtered'] ?? 'false', FILTER_VALIDATE_BOOLEAN);
        if (!$is_filtered) { ob_end_clean(); echo json_encode(['status' => 'success', 'data' => []]); exit; }

        $date_from = !empty($_POST['start_date']) ? $_POST['start_date'] : date('Y-m-d');
        $date_to = !empty($_POST['end_date']) ? $_POST['end_date'] : date('Y-m-d');
        $ward_id = $_POST['ward_id'] ?? 'ALL';

        $sql = "SELECT e.id as episode_id, e.visit_master_id, e.patient_no, e.discharge_date, e.discharge_outcome, e.discharge_notes, e.next_review_date,
                       p.first_name, p.last_name, w.ward_name, b.bed_number,
                       CONCAT(s.first_name, ' ', s.last_name) as discharged_by_nurse
                FROM ipd_admission_episodes e
                JOIN patient p ON e.patient_no = p.patient_no
                JOIN ipd_wards w ON e.ward_id = w.id
                JOIN ipd_beds b ON e.bed_id = b.id
                LEFT JOIN staff s ON e.discharged_by = s.staff_id
                WHERE e.status = 'Discharged' AND DATE(e.discharge_date) BETWEEN '$date_from' AND '$date_to'";

        if ($ward_id !== 'ALL') $sql .= " AND e.ward_id = " . (int)$ward_id;

        $res = $conn->query($sql);
        $data = [];
        if($res) {
            while($row = $res->fetch_assoc()) {
                $row['patient_name'] = trim($row['first_name'] . ' ' . $row['last_name']);
                $row['formatted_date'] = date($global_date_format, strtotime($row['discharge_date']));
                $row['next_review_date_fmt'] = $row['next_review_date'] ? date($global_date_format, strtotime($row['next_review_date'])) : 'Not Scheduled';
                $data[] = $row;
            }
        }

        ob_end_clean(); echo json_encode(['status' => 'success', 'data' => $data]); exit;
    }

    // ==========================================
    // GET CLEARANCE CHECKLIST DETAILS
    // ==========================================
    if ($action === 'get_discharge_clearance_details') {
        $episode_id = (int)$_POST['episode_id'];

        $qEp = $conn->prepare("SELECT e.*, p.first_name, p.last_name, w.ward_name, b.bed_number, vm.payment_category 
                               FROM ipd_admission_episodes e 
                               JOIN patient p ON e.patient_no = p.patient_no 
                               JOIN ipd_wards w ON e.ward_id = w.id 
                               JOIN ipd_beds b ON e.bed_id = b.id 
                               LEFT JOIN visit_master vm ON e.visit_master_id = vm.id
                               WHERE e.id = ?");
        $qEp->bind_param("i", $episode_id); $qEp->execute();
        $ep = $qEp->get_result()->fetch_assoc();

        if(!$ep) { throw new Exception('Episode not found.'); }

        $patient_info = [
            'episode_id' => $ep['id'],
            'visit_id' => $ep['visit_master_id'],
            'bed_id' => $ep['bed_id'],
            'patient_no' => $ep['patient_no'],
            'patient_name' => trim($ep['first_name'] . ' ' . $ep['last_name']),
            'admission_date' => date($global_date_format, strtotime($ep['admission_date'])),
            'location' => $ep['ward_name'] . ' - Bed ' . $ep['bed_number'],
            'payer_type' => $ep['payment_category'] ?? 'Cash',
            'doctor_outcome' => $ep['discharge_outcome'] ?? 'Pending Discharge',
            'next_review_date' => $ep['next_review_date'] ? date('Y-m-d\TH:i', strtotime($ep['next_review_date'])) : ''
        ];

        $diagnoses = [];
        $qDiag = $conn->query("SELECT description, code, gdrg_mapped_code, is_principal FROM clinical_diagnoses WHERE visit_id = {$ep['visit_master_id']} ORDER BY is_principal DESC");
        if($qDiag) while($d = $qDiag->fetch_assoc()) $diagnoses[] = $d;

        $latest_records = [];
        $qRec = $conn->query("SELECT r.recorded_at, r.field_name, r.field_value, s.first_name, s.last_name 
                              FROM ipd_dynamic_responses r 
                              LEFT JOIN staff s ON r.recorded_by = s.staff_id 
                              WHERE r.visit_id = {$ep['visit_master_id']} AND r.is_deleted = 0 
                              ORDER BY r.recorded_at DESC LIMIT 5");
        if($qRec) {
            while($r = $qRec->fetch_assoc()) {
                $r['time_fmt'] = date('d/m, H:i', strtotime($r['recorded_at']));
                $r['author'] = trim($r['first_name'] . ' ' . $r['last_name']);
                $r['field_value'] = strip_tags($r['field_value']); // Strip HTML for clear timeline
                $latest_records[] = $r;
            }
        }

        $qBill = $conn->query("SELECT SUM(balance_due) as total_debt FROM patient_invoices WHERE patient_no = '{$ep['patient_no']}' AND status != 'Paid'");
        $debt = $qBill->fetch_assoc()['total_debt'] ?? '0.00';

        $qRx = $conn->query("SELECT COUNT(id) as total_rx, SUM(CASE WHEN status = 'Dispensed' THEN 1 ELSE 0 END) as dispensed_rx FROM clinical_prescriptions WHERE visit_id = {$ep['visit_master_id']}");
        $rx = $qRx->fetch_assoc();

        $qLab = $conn->query("SELECT COUNT(id) as pending_labs FROM clinical_lab_requests WHERE visit_id = {$ep['visit_master_id']} AND status IN ('Pending', 'Awaiting Sample', 'Awaiting Verification')");
        $labs = $qLab->fetch_assoc()['pending_labs'] ?? 0;

        $clearance = [
            'total_unpaid_bills' => number_format((float)$debt, 2),
            'total_prescriptions' => $rx['total_rx'] ?? 0,
            'dispensed_prescriptions' => $rx['dispensed_rx'] ?? 0,
            'pending_labs' => $labs
        ];

        ob_end_clean(); echo json_encode(['status' => 'success', 'patient' => $patient_info, 'diagnoses' => $diagnoses, 'latest_records' => $latest_records, 'clearance' => $clearance]); exit;
    }

    // ==========================================
    // EXECUTE FINAL DISCHARGE
    // ==========================================
    if ($action === 'execute_final_discharge') {
        $episode_id = (int)$_POST['episode_id'];
        $visit_id = (int)$_POST['visit_id'];
        $bed_id = (int)$_POST['bed_id'];
        $discharge_notes = trim($_POST['discharge_notes']);

        $conn->begin_transaction();

        $qDiag = $conn->query("SELECT id, gdrg_mapped_code FROM clinical_diagnoses WHERE visit_id = $visit_id AND is_principal = 1");
        if($qDiag->num_rows === 0) throw new Exception("Clinical Coding Error: Patient has no Principal Diagnosis recorded.");
        $diag = $qDiag->fetch_assoc();
        if(empty($diag['gdrg_mapped_code'])) throw new Exception("Billing Map Error: Principal Diagnosis lacks a valid G-DRG code.");

        // 1. Update Episode
        $stmtEp = $conn->prepare("UPDATE ipd_admission_episodes SET status = 'Discharged', discharge_date = NOW(), discharged_by = ?, discharge_notes = ? WHERE id = ?");
        $stmtEp->bind_param("isi", $staff_id, $discharge_notes, $episode_id);
        $stmtEp->execute();

        // 2. Free the Bed (Status 4 = Pending Cleaning / Housekeeping)
        $stmtBed = $conn->prepare("UPDATE ipd_beds SET bed_status_id = 4, occupancy_status = 'Vacant', bed_status = 'Pending Cleaning', status_changed_by = ?, last_status_change = NOW() WHERE id = ?");
        $stmtBed->bind_param("ii", $staff_id, $bed_id);
        $stmtBed->execute();

        // 3. System Audit Log
        $ip_addr = $_SERVER['REMOTE_ADDR'] ?? 'Unknown';
        $old_val = json_encode(['episode_id' => $episode_id, 'status' => 'Pending Discharge']);
        $new_val = json_encode(['episode_id' => $episode_id, 'status' => 'Discharged', 'gdrg_validated' => $diag['gdrg_mapped_code']]);
        
        $stmtAud = $conn->prepare("INSERT INTO system_audit_logs (staff_id, action_type, table_name, record_id, old_values, new_values, ip_address) VALUES (?, 'UPDATE', 'ipd_admission_episodes', ?, ?, ?, ?)");
        $strEp = (string)$episode_id;
        $stmtAud->bind_param("issss", $staff_id, $strEp, $old_val, $new_val, $ip_addr);
        $stmtAud->execute();

        $conn->commit();
        ob_end_clean(); echo json_encode(['status' => 'success', 'message' => 'Patient successfully discharged. Bed vacated for cleaning.']); exit;
    }

    // ==========================================
    // UPDATE DISCHARGE NOTES
    // ==========================================
    if ($action === 'update_discharge_notes') {
        $episode_id = (int)$_POST['edit_episode_id'];
        $new_notes = trim($_POST['edit_discharge_notes']);

        $conn->begin_transaction();

        $qOld = $conn->query("SELECT discharge_notes FROM ipd_admission_episodes WHERE id = $episode_id");
        $old_notes = $qOld->fetch_assoc()['discharge_notes'] ?? '';

        $stmtEp = $conn->prepare("UPDATE ipd_admission_episodes SET discharge_notes = ? WHERE id = ?");
        $stmtEp->bind_param("si", $new_notes, $episode_id);
        $stmtEp->execute();

        $ip_addr = $_SERVER['REMOTE_ADDR'] ?? 'Unknown';
        $old_val = json_encode(['episode_id' => $episode_id, 'notes' => $old_notes]);
        $new_val = json_encode(['episode_id' => $episode_id, 'notes' => $new_notes]);
        
        $stmtAud = $conn->prepare("INSERT INTO system_audit_logs (staff_id, action_type, table_name, record_id, old_values, new_values, ip_address) VALUES (?, 'UPDATE', 'ipd_admission_episodes', ?, ?, ?, ?)");
        $strEp = (string)$episode_id;
        $stmtAud->bind_param("issss", $staff_id, $strEp, $old_val, $new_val, $ip_addr);
        $stmtAud->execute();

        $conn->commit();
        ob_end_clean(); echo json_encode(['status' => 'success', 'message' => 'Discharge notes updated successfully. Audit log created.']); exit;
    }

    throw new Exception("Invalid Action Request.");

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