<?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'] ?? $_GET['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 {
    // ==========================================
    // AGGRESSIVE AUTO-HEALING
    // ==========================================
    $chk1 = $conn->query("SHOW COLUMNS FROM clinical_admission_requests LIKE 'transfer_type'");
    if($chk1 && $chk1->num_rows == 0) {
        $conn->query("ALTER TABLE `clinical_admission_requests` ADD COLUMN `transfer_type` ENUM('New Admission', 'Ward Transfer', 'Theatre Transfer') DEFAULT 'New Admission' AFTER `requested_ward`");
        $conn->query("ALTER TABLE `clinical_admission_requests` ADD COLUMN `target_ward_id` INT(11) DEFAULT NULL AFTER `transfer_type`");
        $conn->query("ALTER TABLE `clinical_admission_requests` ADD COLUMN `from_ward_id` INT(11) DEFAULT NULL AFTER `target_ward_id`");
        $conn->query("ALTER TABLE `clinical_admission_requests` ADD COLUMN `from_bed_id` INT(11) DEFAULT NULL AFTER `from_ward_id`");
        $conn->query("ALTER TABLE `clinical_admission_requests` MODIFY COLUMN `status` ENUM('Pending', 'Admitted', 'Discharged', 'Cancelled', 'Rejected') DEFAULT 'Pending'");
        $conn->query("ALTER TABLE `clinical_admission_requests` ADD COLUMN `rejection_reason` TEXT DEFAULT NULL AFTER `status`");
    }

    // ==========================================
    // FETCH KPIs
    // ==========================================
    if ($action === 'fetch_kpis') {
        $date_from = !empty($_POST['date_from']) ? $_POST['date_from'] : date('Y-m-d');
        $date_to = !empty($_POST['date_to']) ? $_POST['date_to'] : date('Y-m-d');
        $ward_id = $_POST['ward_id'] ?? 'ALL';

        $kpi = ['incoming_pending' => 0, 'outgoing_pending' => 0, 'completed_transfers' => 0, 'rejected_transfers' => 0];
        $base_where = "transfer_type IN ('Ward Transfer', 'Theatre Transfer') AND DATE(created_at) BETWEEN '$date_from' AND '$date_to'";

        $inc_sql = "SELECT COUNT(id) as cnt FROM clinical_admission_requests WHERE status = 'Pending' AND " . $base_where;
        if($ward_id !== 'ALL') $inc_sql .= " AND target_ward_id = " . (int)$ward_id;
        if($q = $conn->query($inc_sql)) $kpi['incoming_pending'] = $q->fetch_assoc()['cnt'] ?? 0;

        $out_sql = "SELECT COUNT(id) as cnt FROM clinical_admission_requests WHERE status = 'Pending' AND " . $base_where;
        if($ward_id !== 'ALL') $out_sql .= " AND from_ward_id = " . (int)$ward_id;
        if($q = $conn->query($out_sql)) $kpi['outgoing_pending'] = $q->fetch_assoc()['cnt'] ?? 0;

        $comp_sql = "SELECT COUNT(id) as cnt FROM clinical_admission_requests WHERE status = 'Admitted' AND " . $base_where;
        if($ward_id !== 'ALL') $comp_sql .= " AND (target_ward_id = " . (int)$ward_id . " OR from_ward_id = " . (int)$ward_id . ")";
        if($q = $conn->query($comp_sql)) $kpi['completed_transfers'] = $q->fetch_assoc()['cnt'] ?? 0;

        $rej_sql = "SELECT COUNT(id) as cnt FROM clinical_admission_requests WHERE status = 'Rejected' AND " . $base_where;
        if($ward_id !== 'ALL') $rej_sql .= " AND (target_ward_id = " . (int)$ward_id . " OR from_ward_id = " . (int)$ward_id . ")";
        if($q = $conn->query($rej_sql)) $kpi['rejected_transfers'] = $q->fetch_assoc()['cnt'] ?? 0;

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

    // ==========================================
    // FETCH DEPENDENCIES
    // ==========================================
    if ($action === 'fetch_dependencies') {
        $wards = [];
        $qw = $conn->query("SELECT id, ward_name FROM ipd_wards WHERE is_active=1 ORDER BY ward_name ASC");
        while($w = $qw->fetch_assoc()) $wards[] = $w;

        $active_patients = [];
        $qp = $conn->query("SELECT e.id as episode_id, e.visit_master_id, e.patient_no, p.first_name, p.last_name, w.ward_name, b.bed_number, e.ward_id, e.bed_id 
                            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 
                            WHERE e.status IN ('Admitted', 'In Theatre')");
        while($p = $qp->fetch_assoc()) {
            $p['patient_name'] = trim($p['first_name'] . ' ' . $p['last_name']);
            $active_patients[] = $p;
        }

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

    // ==========================================
    // FETCH VACANT BEDS
    // ==========================================
    if ($action === 'fetch_vacant_beds') {
        $ward_id = (int)$_POST['ward_id'];
        $beds = [];
        $qb = $conn->query("SELECT b.id, b.bed_number, r.room_number_or_name 
                            FROM ipd_beds b 
                            LEFT JOIN ipd_rooms r ON b.room_id = r.id 
                            WHERE b.ward_id = $ward_id AND b.is_active=1 AND b.bed_status_id = 1 AND b.occupancy_status = 'Vacant' 
                            ORDER BY b.bed_number ASC");
        if($qb) {
            while($b = $qb->fetch_assoc()) {
                $b['display_name'] = ($b['room_number_or_name'] ? $b['room_number_or_name'] . ' - ' : '') . 'Bed ' . $b['bed_number'];
                $beds[] = $b;
            }
        }
        ob_end_clean(); echo json_encode(['status' => 'success', 'data' => $beds]); exit;
    }

    // ==========================================
    // FETCH CLINICAL TRANSFER SUMMARY
    // ==========================================
    if ($action === 'fetch_transfer_summary') {
        $visit_id = (int)$_POST['visit_id'];
        
        $vitals = null;
        $qV = $conn->query("SELECT * FROM patient_vitals WHERE visit_id = $visit_id ORDER BY id DESC LIMIT 1");
        if($qV && $v = $qV->fetch_assoc()) $vitals = $v;

        $labs = [];
        $qL = $conn->query("SELECT test_name, status FROM clinical_lab_requests WHERE visit_id = $visit_id ORDER BY id DESC LIMIT 4");
        if($qL) while($l = $qL->fetch_assoc()) $labs[] = $l;

        $meds = [];
        $qM = $conn->query("SELECT drug_name, status FROM clinical_prescriptions WHERE visit_id = $visit_id ORDER BY id DESC LIMIT 4");
        if($qM) while($m = $qM->fetch_assoc()) $meds[] = $m;

        $notes = [];
        $qN = $conn->query("SELECT field_name, field_value, recorded_at FROM ipd_dynamic_responses WHERE visit_id = $visit_id AND is_deleted=0 ORDER BY recorded_at DESC LIMIT 4");
        if($qN) {
            while($n = $qN->fetch_assoc()) {
                $n['time_fmt'] = date('d M, H:i', strtotime($n['recorded_at']));
                $n['field_value'] = strip_tags($n['field_value']); // Strip HTML for clean display
                $notes[] = $n;
            }
        }

        ob_end_clean();
        echo json_encode(['status' => 'success', 'vitals' => $vitals, 'labs' => $labs, 'meds' => $meds, 'notes' => $notes]);
        exit;
    }

    // ==========================================
    // FETCH TRANSFER QUEUE
    // ==========================================
    if ($action === 'fetch_transfer_queue') {
        $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['date_from']) ? $_POST['date_from'] : date('Y-m-d');
        $date_to = !empty($_POST['date_to']) ? $_POST['date_to'] : date('Y-m-d');
        $ward_id = $_POST['ward_id'] ?? 'ALL';
        $direction = $_POST['direction'] ?? 'ALL';
        $status_filter = $_POST['status_filter'] ?? 'Pending';

        $all_requests = [];

        $sql1 = "SELECT c.id, c.visit_master_id, c.created_at, c.status, c.transfer_type, 
                 c.from_ward_id, c.target_ward_id, fw.ward_name as from_location, tw.ward_name as target_location,
                 p.first_name, p.last_name, p.patient_no, g.gender_name, c.treatment_plan as notes,
                 CONCAT(s.first_name, ' ', s.last_name) as req_doctor, c.rejection_reason
                 FROM clinical_admission_requests c
                 JOIN patient p ON c.patient_no = p.patient_no
                 LEFT JOIN gender g ON p.gender_id = g.id
                 LEFT JOIN ipd_wards fw ON c.from_ward_id = fw.id
                 LEFT JOIN ipd_wards tw ON c.target_ward_id = tw.id
                 LEFT JOIN staff s ON c.requested_by = s.staff_id
                 WHERE c.transfer_type IN ('Ward Transfer') 
                 AND DATE(c.created_at) BETWEEN '$date_from' AND '$date_to'";
        $res1 = $conn->query($sql1);
        if($res1) while($row = $res1->fetch_assoc()) $all_requests[] = $row;

        $sql2 = "SELECT t.id, t.visit_id as visit_master_id, t.created_at, t.status as raw_status, 'Theatre Transfer' as transfer_type,
                 w.id as from_ward_id, NULL as target_ward_id, w.ward_name as from_location, tr.room_name as target_location,
                 p.first_name, p.last_name, p.patient_no, g.gender_name, t.remarks as notes,
                 CONCAT(s.first_name, ' ', s.last_name) as req_doctor, '' as rejection_reason
                 FROM ipd_theatre_requests t
                 JOIN visit_master vm ON t.visit_id = vm.id
                 JOIN patient p ON vm.patient_no = p.patient_no
                 LEFT JOIN gender g ON p.gender_id = g.id
                 LEFT JOIN ipd_admission_episodes e ON t.origin_episode_id = e.id
                 LEFT JOIN ipd_wards w ON e.ward_id = w.id
                 LEFT JOIN ipd_setup_theatre_rooms tr ON t.room_id = tr.id
                 LEFT JOIN staff s ON t.requested_by = s.staff_id
                 WHERE DATE(t.created_at) BETWEEN '$date_from' AND '$date_to'";
        $res2 = $conn->query($sql2);
        if($res2) while($row = $res2->fetch_assoc()) $all_requests[] = $row;

        $filtered_data = [];
        foreach ($all_requests as $r) {
            $mapped_status = $r['status'] ?? $r['raw_status'];
            
            if ($r['transfer_type'] === 'Theatre Transfer') {
                if ($mapped_status === 'Scheduled') $mapped_status = 'Pending';
                elseif (in_array($mapped_status, ['In Progress', 'Completed'])) $mapped_status = 'Admitted';
                elseif ($mapped_status === 'Cancelled') $mapped_status = 'Rejected';
            }

            if ($status_filter === 'Pending' && $mapped_status !== 'Pending') continue;
            if ($status_filter === 'Completed' && $mapped_status !== 'Admitted') continue;
            if ($status_filter === 'Rejected' && $mapped_status !== 'Rejected') continue;

            if ($ward_id !== 'ALL') {
                $w_id = (int)$ward_id;
                $is_incoming = ($r['target_ward_id'] == $w_id);
                $is_outgoing = ($r['from_ward_id'] == $w_id);

                if ($direction === 'Incoming' && !$is_incoming) continue;
                if ($direction === 'Outgoing' && !$is_outgoing) continue;
                if ($direction === 'ALL' && !$is_incoming && !$is_outgoing) continue;
            }

            $r['mapped_status'] = $mapped_status;
            $r['patient_name'] = trim($r['first_name'] . ' ' . $r['last_name']);
            $r['req_date_fmt'] = date($global_date_format, strtotime($r['created_at']));
            $filtered_data[] = $r;
        }

        usort($filtered_data, function($a, $b) { return strtotime($b['created_at']) - strtotime($a['created_at']); });
        ob_end_clean(); echo json_encode(['status' => 'success', 'data' => $filtered_data]); exit;
    }

    // ==========================================
    // INITIATE NEW TRANSFER
    // ==========================================
    if ($action === 'initiate_transfer') {
        $visit_id = (int)$_POST['visit_id'];
        $target_ward_id = (int)$_POST['target_ward_id'];
        $target_bed_id = !empty($_POST['target_bed_id']) ? (int)$_POST['target_bed_id'] : null;
        $notes = trim($_POST['transfer_notes'] ?? 'Routine Ward Transfer');
        
        $conn->begin_transaction();

        $qEp = $conn->query("SELECT id, patient_no, ward_id, bed_id, room_id, status FROM ipd_admission_episodes WHERE visit_master_id = $visit_id LIMIT 1");
        $ep = $qEp->fetch_assoc();
        if(!$ep) throw new Exception("Active admission episode not found for this patient.");
        if ((int)$ep['ward_id'] === $target_ward_id) throw new Exception("Patient is already admitted to the selected target ward. Please select a different destination.");

        $qPend = $conn->query("SELECT id FROM clinical_admission_requests WHERE visit_master_id = $visit_id AND status = 'Pending' AND transfer_type IN ('Ward Transfer')");
        if ($qPend && $qPend->num_rows > 0) throw new Exception("Patient already has a Pending Transfer in the queue.");

        $target_ward_name = $conn->query("SELECT ward_name FROM ipd_wards WHERE id = $target_ward_id")->fetch_assoc()['ward_name'] ?? 'Target Ward';
        $transfer_type = 'Ward Transfer';
        $anchor_time = date('Y-m-d H:i:s');

        if ($target_bed_id) {
            // DIRECT TRANSFER
            $conn->query("UPDATE ipd_beds SET bed_status_id = 4, bed_status = 'Pending Cleaning', occupancy_status = 'Vacant', current_admission_episode_id = NULL WHERE id = {$ep['bed_id']}");
            
            $target_room_id = $conn->query("SELECT room_id FROM ipd_beds WHERE id = $target_bed_id")->fetch_assoc()['room_id'] ?? 'NULL';
            $room_val = $target_room_id === 'NULL' ? "NULL" : $target_room_id;

            $conn->query("UPDATE ipd_beds SET bed_status_id = 2, bed_status = 'Occupied', occupancy_status = 'Occupied', current_admission_episode_id = {$ep['id']} WHERE id = $target_bed_id");
            $conn->query("UPDATE ipd_admission_episodes SET status = 'Transferred', ward_id = $target_ward_id, room_id = $room_val, bed_id = $target_bed_id WHERE id = {$ep['id']}");

            // Parameter matching strict fix: 10 parameters supplied for 10 placeholders
            $stmt = $conn->prepare("INSERT INTO clinical_admission_requests (visit_master_id, patient_no, transfer_type, target_ward_id, from_ward_id, from_bed_id, requested_ward, admission_diagnosis, treatment_plan, status, requested_by, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, 'Direct Transfer Executed', ?, 'Admitted', ?, ?)");
            $stmt->bind_param("issiiissis", $visit_id, $ep['patient_no'], $transfer_type, $target_ward_id, $ep['ward_id'], $ep['bed_id'], $target_ward_name, $notes, $staff_id, $anchor_time);
            $stmt->execute();

            $msg = "Patient transferred directly and bed assigned successfully.";
        } else {
            // PENDING TRANSFER QUEUE
            $stmt = $conn->prepare("INSERT INTO clinical_admission_requests (visit_master_id, patient_no, transfer_type, target_ward_id, from_ward_id, from_bed_id, requested_ward, admission_diagnosis, treatment_plan, status, requested_by, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, 'Internal Ward Transfer', ?, 'Pending', ?, ?)");
            $stmt->bind_param("issiiissis", $visit_id, $ep['patient_no'], $transfer_type, $target_ward_id, $ep['ward_id'], $ep['bed_id'], $target_ward_name, $notes, $staff_id, $anchor_time);
            $stmt->execute();

            $msg = "Transfer request sent. Waiting for destination ward to accept and assign bed.";
        }

        $conn->commit();
        ob_end_clean(); echo json_encode(['status' => 'success', 'message' => $msg]); exit;
    }

    // ==========================================
    // ACCEPT TRANSFER
    // ==========================================
    if ($action === 'accept_transfer') {
        $req_id = (int)$_POST['request_id'];
        $transfer_type = $_POST['transfer_type'];
        $target_bed_id = !empty($_POST['target_bed_id']) ? (int)$_POST['target_bed_id'] : null;

        $conn->begin_transaction();

        if ($transfer_type === 'Theatre Transfer') {
            $qReq = $conn->query("SELECT visit_id FROM ipd_theatre_requests WHERE id = $req_id AND status = 'Scheduled'");
            if($qReq->num_rows === 0) throw new Exception("Theatre Request not found or already in progress.");
            $conn->query("UPDATE ipd_theatre_requests SET status = 'In Progress' WHERE id = $req_id");
            $msg = "Patient successfully accepted into the Operating Theatre.";
        } 
        else {
            $qReq = $conn->query("SELECT * FROM clinical_admission_requests WHERE id = $req_id AND status = 'Pending'");
            $req = $qReq->fetch_assoc();
            if(!$req) throw new Exception("Transfer Request not found or has already been processed by another staff member.");

            $visit_id = $req['visit_master_id'];
            $target_ward_id = $req['target_ward_id'];

            $qChkBed = $conn->query("SELECT bed_status_id, occupancy_status FROM ipd_beds WHERE id = $target_bed_id");
            $chkBed = $qChkBed->fetch_assoc();
            if(!$chkBed || $chkBed['occupancy_status'] !== 'Vacant') throw new Exception("The selected bed is no longer vacant. Please select a different bed.");

            $qEp = $conn->query("SELECT id, bed_id FROM ipd_admission_episodes WHERE visit_master_id = $visit_id LIMIT 1");
            $ep = $qEp->fetch_assoc();
            
            if($ep['bed_id']) {
                $conn->query("UPDATE ipd_beds SET bed_status_id = 4, bed_status = 'Pending Cleaning', occupancy_status = 'Vacant', current_admission_episode_id = NULL WHERE id = {$ep['bed_id']}");
            }

            $target_room_id = $conn->query("SELECT room_id FROM ipd_beds WHERE id = $target_bed_id")->fetch_assoc()['room_id'] ?? 'NULL';
            $room_val = $target_room_id === 'NULL' ? "NULL" : $target_room_id;

            $conn->query("UPDATE ipd_beds SET bed_status_id = 2, bed_status = 'Occupied', occupancy_status = 'Occupied', current_admission_episode_id = {$ep['id']} WHERE id = $target_bed_id");
            $conn->query("UPDATE ipd_admission_episodes SET status = 'Transferred', ward_id = $target_ward_id, room_id = $room_val, bed_id = $target_bed_id WHERE id = {$ep['id']}");
            $conn->query("UPDATE clinical_admission_requests SET status = 'Admitted' WHERE id = $req_id");
            
            $msg = "Ward transfer accepted and new bed assigned successfully.";
        }

        $conn->commit();
        ob_end_clean(); echo json_encode(['status' => 'success', 'message' => $msg]); exit;
    }

    // ==========================================
    // REJECT TRANSFER
    // ==========================================
    if ($action === 'reject_transfer') {
        $req_id = (int)$_POST['request_id'];
        $transfer_type = $_POST['transfer_type'];
        $reason = trim($_POST['rejection_reason']);

        $conn->begin_transaction();

        if ($transfer_type === 'Theatre Transfer') {
            $qReq = $conn->query("SELECT visit_id, origin_bed_id FROM ipd_theatre_requests WHERE id = $req_id");
            $req = $qReq->fetch_assoc();
            if(!$req) throw new Exception("Theatre request not found.");
            
            $visit_id = $req['visit_id'];
            $origin_bed_id = $req['origin_bed_id'];

            $conn->query("UPDATE ipd_theatre_requests SET status = 'Cancelled', remarks = CONCAT(remarks, ' | Rejected: ', '".$conn->real_escape_string($reason)."') WHERE id = $req_id");
            $conn->query("UPDATE ipd_admission_episodes SET status = 'Admitted' WHERE visit_master_id = $visit_id AND status = 'In Theatre'");
            
            if($origin_bed_id) {
                $conn->query("UPDATE ipd_beds SET bed_status_id = 2, bed_status = 'Occupied', occupancy_status = 'Occupied' WHERE id = $origin_bed_id");
            }
            $msg = "Theatre transfer rejected. Patient has been securely returned to their original Ward Bed.";
        } else {
            $qReq = $conn->query("SELECT * FROM clinical_admission_requests WHERE id = $req_id AND status = 'Pending'");
            if($qReq->num_rows === 0) throw new Exception("Ward request not found or already processed.");

            $stmt = $conn->prepare("UPDATE clinical_admission_requests SET status = 'Rejected', rejection_reason = ? WHERE id = ?");
            $stmt->bind_param("si", $reason, $req_id);
            $stmt->execute();
            $msg = "Ward transfer rejected. Patient remains securely in their current bed.";
        }

        $conn->commit();
        ob_end_clean(); echo json_encode(['status' => 'success', 'message' => $msg]); exit;
    }

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