<?php
/**
 * Route patient to another department after consultation completion
 * or complete visit and route to billing
 */
ob_start();
session_start();
include '../layouts/dbconn.php';

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

if (!isset($_SESSION['user_id'])) {
    echo json_encode(['success' => false, 'message' => 'Unauthorized']);
    exit();
}

$user_id = $_SESSION['user_id'];
$visit_id = isset($_POST['visit_id']) ? intval($_POST['visit_id']) : 0;
$patient_id = isset($_POST['patient_id']) ? intval($_POST['patient_id']) : 0;
$target_department_id = isset($_POST['target_department_id']) ? intval($_POST['target_department_id']) : 0;
$action = isset($_POST['action']) ? trim($_POST['action']) : ''; // 'route' or 'complete_visit'
$routing_notes = isset($_POST['routing_notes']) ? trim($_POST['routing_notes']) : '';

if (!$visit_id || !$patient_id) {
    echo json_encode(['success' => false, 'message' => 'Missing visit_id or patient_id']);
    exit();
}

try {
    $conn->begin_transaction();

    // Get current queue entry for this visit (if exists)
    $queue_sql = "SELECT * FROM patient_queue 
                  WHERE visit_id = ? 
                  AND queue_status IN ('WAITING', 'IN_SERVICE', 'ROUTED')
                  ORDER BY queue_entry_time DESC 
                  LIMIT 1";
    $stmt = $conn->prepare($queue_sql);
    $stmt->bind_param("i", $visit_id);
    $stmt->execute();
    $queue_result = $stmt->get_result();
    $current_queue = $queue_result->num_rows > 0 ? $queue_result->fetch_assoc() : null;
    $stmt->close();

    // Get patient details
    $patient_sql = "SELECT p.*, u.full_name, u.phone_primary, u.date_of_birth, u.gender 
                    FROM patients p 
                    JOIN users u ON p.user_id = u.user_id 
                    WHERE p.patient_id = ?";
    $stmt = $conn->prepare($patient_sql);
    $stmt->bind_param("i", $patient_id);
    $stmt->execute();
    $patient_data = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    if (!$patient_data) {
        throw new Exception("Patient not found");
    }

    if ($action === 'complete_visit') {
        // Just complete the visit, no routing
        $update_visit = "UPDATE patient_visits SET status = 'COMPLETED' WHERE visit_id = ?";
        $stmt = $conn->prepare($update_visit);
        $stmt->bind_param("i", $visit_id);
        $stmt->execute();
        $stmt->close();

        // If there's a current queue entry, mark it as COMPLETED
        if ($current_queue) {
            $update_queue = "UPDATE patient_queue 
                            SET queue_status = 'COMPLETED',
                                service_end_time = NOW(),
                                total_service_minutes = TIMESTAMPDIFF(MINUTE, COALESCE(service_start_time, queue_entry_time), NOW()),
                                updated_by = ?,
                                updated_at = NOW()
                            WHERE queue_id = ?";
            $stmt = $conn->prepare($update_queue);
            $stmt->bind_param("ii", $user_id, $current_queue['queue_id']);
            $stmt->execute();
            $stmt->close();
        }

        $conn->commit();
        @ob_end_clean();
        echo json_encode([
            'success' => true,
            'message' => 'Visit completed successfully'
        ]);
        exit();
    }

    // Route to department (or billing)
    if ($target_department_id <= 0) {
        throw new Exception("Target department is required");
    }

    // Get target department
    $dept_sql = "SELECT department_id, department_name, department_code FROM departments WHERE department_id = ? AND is_active = 1";
    $stmt = $conn->prepare($dept_sql);
    $stmt->bind_param("i", $target_department_id);
    $stmt->execute();
    $target_dept = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    if (!$target_dept) {
        throw new Exception("Target department not found");
    }

    // If routing to billing, also complete the visit
    $is_billing = (strtoupper($target_dept['department_code']) === 'BILLING');
    if ($is_billing) {
        $update_visit = "UPDATE patient_visits SET status = 'COMPLETED' WHERE visit_id = ?";
        $stmt = $conn->prepare($update_visit);
        $stmt->bind_param("i", $visit_id);
        $stmt->execute();
        $stmt->close();
    }

    // Mark current queue as COMPLETED or TRANSFERRED
    if ($current_queue) {
        $update_current = "UPDATE patient_queue 
                          SET queue_status = ?,
                              service_end_time = NOW(),
                              total_service_minutes = TIMESTAMPDIFF(MINUTE, COALESCE(service_start_time, queue_entry_time), NOW()),
                              updated_by = ?,
                              updated_at = NOW()
                          WHERE queue_id = ?";
        $new_status = $is_billing ? 'COMPLETED' : 'TRANSFERRED';
        $stmt = $conn->prepare($update_current);
        $stmt->bind_param("sii", $new_status, $user_id, $current_queue['queue_id']);
        $stmt->execute();
        $stmt->close();
    }

    // Check if patient already in target department queue today
    $check_dup = "SELECT queue_id FROM patient_queue 
                  WHERE patient_id = ? 
                  AND department_id = ? 
                  AND queue_status IN ('WAITING', 'IN_SERVICE')
                  AND DATE(queue_entry_time) = CURDATE()";
    $stmt = $conn->prepare($check_dup);
    $stmt->bind_param("ii", $patient_id, $target_department_id);
    $stmt->execute();
    $dup_result = $stmt->get_result();
    $stmt->close();

    if ($dup_result->num_rows > 0) {
        // Already in queue, just return success
        $conn->commit();
        @ob_end_clean();
        echo json_encode([
            'success' => true,
            'message' => 'Patient already in ' . $target_dept['department_name'] . ' queue',
            'already_in_queue' => true
        ]);
        exit();
    }

    // Generate new queue number
    $date_str = date('Ymd');
    $seq_sql = "SELECT COUNT(*) + 1 as count FROM patient_queue 
                WHERE department_id = ? 
                AND DATE(queue_entry_time) = CURDATE()";
    $stmt = $conn->prepare($seq_sql);
    $stmt->bind_param("i", $target_department_id);
    $stmt->execute();
    $sequence = str_pad($stmt->get_result()->fetch_assoc()['count'], 3, '0', STR_PAD_LEFT);
    $stmt->close();

    $new_queue_number = $target_dept['department_code'] . '-' . $date_str . '-' . $sequence;

    // Calculate position and wait time
    $pos_sql = "SELECT COUNT(*) + 1 as pos FROM patient_queue 
                WHERE department_id = ? 
                AND queue_status = 'WAITING' 
                AND DATE(queue_entry_time) = CURDATE()";
    $stmt = $conn->prepare($pos_sql);
    $stmt->bind_param("i", $target_department_id);
    $stmt->execute();
    $position = (int)$stmt->get_result()->fetch_assoc()['pos'];
    $stmt->close();

    $estimated_wait = ($position - 1) * 15;

    // Calculate age
    $age = 0;
    if (!empty($patient_data['date_of_birth'])) {
        try {
            $dob = new DateTime($patient_data['date_of_birth']);
            $age = $dob->diff(new DateTime())->y;
        } catch (Exception $e) {}
    }

    // Normalize gender
    $raw_gender = $patient_data['gender'] ?? null;
    $gender = null;
    if ($raw_gender !== null && trim($raw_gender) !== '') {
        $g = strtoupper(trim($raw_gender));
        $gender_map = ['M' => 'MALE', 'F' => 'FEMALE', 'MALE' => 'MALE', 'FEMALE' => 'FEMALE', 'OTHER' => 'OTHER'];
        $gender = $gender_map[$g] ?? (in_array($g, ['MALE', 'FEMALE', 'OTHER'], true) ? $g : null);
    }

    // Normalize registration_type
    $reg_type = $patient_data['registration_type'] ? strtoupper(trim($patient_data['registration_type'])) : 'WALK_IN';
    if (!in_array($reg_type, ['WALK_IN', 'INSURANCE', 'PRO_BONO'], true)) {
        $reg_type = 'WALK_IN';
    }

    // Determine priority (use from current queue if available, else NORMAL)
    $priority = $current_queue['priority'] ?? 'NORMAL';

    // Insert into target department queue (columns aligned with transfer_patient.php)
    $service_type = $is_billing ? 'BILLING' : 'CONSULTATION_FOLLOWUP';
    $chief_complaint = $current_queue['chief_complaint'] ?? 'Follow-up from consultation';
    $previous_dept_id = $current_queue['department_id'] ?? null;
    $vitals_taken = (int)($current_queue['vitals_taken'] ?? 0);
    $phone = $patient_data['phone_primary'] ?? '';
    $patient_number = $patient_data['patient_number'] ?? '';
    $triage_category = $current_queue['triage_category'] ?? null;
    $special_needs = $current_queue['special_needs'] ?? null;
    $has_appointment = (int)($current_queue['has_appointment'] ?? 0);
    $is_vip = (int)($current_queue['is_vip'] ?? 0);

    $insert_sql = "INSERT INTO patient_queue (
        queue_number,
        patient_id,
        visit_id,
        patient_name,
        patient_number,
        phone_number,
        age,
        gender,
        department_id,
        queue_status,
        priority,
        registration_type,
        position_in_queue,
        service_type,
        chief_complaint,
        triage_category,
        vitals_taken,
        has_appointment,
        is_vip,
        special_needs,
        previous_department_id,
        arrival_time,
        queue_entry_time,
        created_by,
        created_at
    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'WAITING', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW(), ?, NOW())";

    $stmt = $conn->prepare($insert_sql);
    if (!$stmt) {
        throw new Exception("Prepare failed: " . $conn->error);
    }

    $stmt->bind_param(
        "siisssssississsiiiiii",
        $new_queue_number,
        $patient_id,
        $visit_id,
        $patient_data['full_name'],
        $patient_number,
        $phone,
        $age,
        $gender,
        $target_department_id,
        $priority,
        $reg_type,
        $position,
        $service_type,
        $chief_complaint,
        $triage_category,
        $vitals_taken,
        $has_appointment,
        $is_vip,
        $special_needs,
        $previous_dept_id,
        $user_id
    );

    if (!$stmt->execute()) {
        throw new Exception("Failed to create queue entry: " . $stmt->error);
    }

    $new_queue_id = $conn->insert_id;
    $stmt->close();

    // Update queue positions
    @$conn->query("CALL UpdateQueuePositions($target_department_id)");
    @$conn->query("CALL UpdateQueueWaitTimes($target_department_id)");

    // Log activity
    try {
        $log_sql = "INSERT INTO activity_log 
                    (user_id, action, module, record_id, record_type, ip_address, logged_at)
                    VALUES (?, 'ROUTE', 'CONSULTATION', ?, 'QUEUE', ?, NOW())";
        $stmt_log = $conn->prepare($log_sql);
        $ip_address = $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN';
        $stmt_log->bind_param("iis", $user_id, $new_queue_id, $ip_address);
        $stmt_log->execute();
        $stmt_log->close();
    } catch (Exception $e) {
        error_log("Activity log error: " . $e->getMessage());
    }

    $conn->commit();

    @ob_end_clean();
    echo json_encode([
        'success' => true,
        'message' => $is_billing ? 'Visit completed and patient routed to billing' : 'Patient routed to ' . $target_dept['department_name'],
        'new_queue_number' => $new_queue_number,
        'target_department' => $target_dept['department_name'],
        'position' => $position
    ]);

} catch (Exception $e) {
    if (isset($conn) && $conn->in_transaction) {
        $conn->rollback();
    }
    error_log("Route after consultation error: " . $e->getMessage());
    @ob_end_clean();
    echo json_encode([
        'success' => false,
        'message' => $e->getMessage()
    ]);
}
?>
