<?php
/**
 * ajax/get_visit_services.php
 */

session_start();
include '../layouts/dbconn.php';
include '../layouts/session.php';

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

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

$allowed_roles = ['SUPER_ADMIN', 'HOSPITAL_ADMIN', 'BILLING_CLERK', 'ACCOUNTANT', 'FRONT_OFFICE'];
if (!in_array($_SESSION['role_code'], $allowed_roles)) {
    echo json_encode(['success' => false, 'message' => 'Access denied']);
    exit();
}

$visit_id = isset($_POST['visit_id']) ? intval($_POST['visit_id']) : 0;

if ($visit_id <= 0) {
    echo json_encode(['success' => false, 'message' => 'Invalid visit ID']);
    exit();
}

$services = [];

// ════════════════════════════════════════════════════════════════════════════
// 1. PROCEDURES FROM patient_procedures TABLE
//    Table: ent_procedure_types  |  PK: procedure_type_id  |  Name: procedure_name
// ════════════════════════════════════════════════════════════════════════════
$proc_sql = "
    SELECT
        pp.procedure_id,
        ept.procedure_name  AS description,
        pp.cost             AS unit_price,
        1                   AS quantity
    FROM patient_procedures pp
    INNER JOIN ent_procedure_types ept ON pp.procedure_type_id = ept.procedure_type_id
    WHERE pp.visit_id = ?
      AND pp.status NOT IN ('CANCELLED', 'POSTPONED')
      AND NOT EXISTS (
          SELECT 1
          FROM   invoice_items ii
          INNER  JOIN invoices i ON ii.invoice_id = i.invoice_id
                               AND i.status      != 'CANCELLED'
          WHERE  ii.reference_id = pp.procedure_id
            AND  ii.item_type   = 'PROCEDURE'
      )
    ORDER BY pp.procedure_date, pp.procedure_id";

$stmt = $conn->prepare($proc_sql);
$stmt->bind_param("i", $visit_id);
$stmt->execute();
$proc_result = $stmt->get_result();
while ($row = $proc_result->fetch_assoc()) {
    $services[] = [
        'item_type'    => 'PROCEDURE',
        'reference_id' => (int)$row['procedure_id'],
        'description'  => $row['description'],
        'quantity'     => 1,
        'unit_price'   => (float)$row['unit_price'],
    ];
}
$stmt->close();

// ════════════════════════════════════════════════════════════════════════════
// 2. LAB TESTS
//    Cost priority: lot.test_cost → sp.base_price → ett.cost
//    NOTE: service_pricing uses 'base_price', NOT 'price'
// ════════════════════════════════════════════════════════════════════════════
$test_sql = "
    SELECT
        lot.order_test_id,
        ett.test_name                           AS description,
        COALESCE(
            NULLIF(lot.test_cost, 0),
            NULLIF(sp.base_price, 0),
            ett.cost,
            0
        )                                       AS unit_price,
        1                                       AS quantity
    FROM lab_orders lo
    INNER JOIN lab_order_tests lot ON lo.order_id      = lot.order_id
    INNER JOIN ent_test_types  ett ON lot.test_type_id = ett.test_type_id
    LEFT  JOIN service_pricing sp  ON sp.service_type  = 'TEST'
                                  AND sp.service_id    = ett.test_type_id
                                  AND sp.is_active     = 1
    WHERE lo.visit_id = ?
      AND lo.status  NOT IN ('CANCELLED')
      AND lot.status NOT IN ('CANCELLED')
      AND NOT EXISTS (
          SELECT 1
          FROM   invoice_items ii
          INNER  JOIN invoices i ON ii.invoice_id = i.invoice_id
                               AND i.status      != 'CANCELLED'
          WHERE  ii.reference_id = lot.order_test_id
            AND  ii.item_type   = 'TEST'
      )
    ORDER BY lo.order_date, lot.order_test_id";

$stmt = $conn->prepare($test_sql);
$stmt->bind_param("i", $visit_id);
$stmt->execute();
$test_result = $stmt->get_result();
while ($row = $test_result->fetch_assoc()) {
    $services[] = [
        'item_type'    => 'TEST',
        'reference_id' => (int)$row['order_test_id'],
        'description'  => $row['description'],
        'quantity'     => 1,
        'unit_price'   => (float)$row['unit_price'],
    ];
}
$stmt->close();

// ════════════════════════════════════════════════════════════════════════════
// 3. MEDICATIONS (pharmacy dispensing)
// ════════════════════════════════════════════════════════════════════════════
$med_sql = "
    SELECT
        pdi.item_id,
        pdi.item_name   AS description,
        pdi.quantity,
        pdi.unit_price
    FROM pharmacy_dispensing pd
    INNER JOIN pharmacy_dispensing_items pdi ON pd.dispensing_id = pdi.dispensing_id
    WHERE pd.visit_id = ?
      AND NOT EXISTS (
          SELECT 1
          FROM   invoice_items ii
          INNER  JOIN invoices i ON ii.invoice_id = i.invoice_id
                               AND i.status      != 'CANCELLED'
          WHERE  ii.reference_id = pdi.item_id
            AND  ii.item_type   = 'MEDICATION'
      )
    ORDER BY pd.dispensing_date, pdi.item_id";

$stmt = $conn->prepare($med_sql);
$stmt->bind_param("i", $visit_id);
$stmt->execute();
$med_result = $stmt->get_result();
while ($row = $med_result->fetch_assoc()) {
    $services[] = [
        'item_type'    => 'MEDICATION',
        'reference_id' => (int)$row['item_id'],
        'description'  => $row['description'],
        'quantity'     => (int)$row['quantity'],
        'unit_price'   => (float)$row['unit_price'],
    ];
}
$stmt->close();

// ════════════════════════════════════════════════════════════════════════════
// 4. PROCEDURES FROM consultations.procedures_recommended (JSON)
//    These are added via new_consultation.php and stored as a JSON array
//    in the consultations table — NOT in patient_procedures.
//    We use pricing_id as reference_id for the duplicate-invoice guard.
// ════════════════════════════════════════════════════════════════════════════
$cons_sql = "
    SELECT consultation_id, procedures_recommended
    FROM   consultations
    WHERE  visit_id = ?
      AND  status  IN ('COMPLETED', 'IN_PROGRESS', 'DRAFT')
    ORDER  BY created_at DESC
    LIMIT  1";

$stmt = $conn->prepare($cons_sql);
$stmt->bind_param("i", $visit_id);
$stmt->execute();
$cons = $stmt->get_result()->fetch_assoc();
$stmt->close();

if ($cons && !empty($cons['procedures_recommended'])) {
    $procs = json_decode($cons['procedures_recommended'], true) ?: [];

    foreach ($procs as $p) {
        $pricing_id  = isset($p['pricing_id'])  ? (int)$p['pricing_id']   : 0;
        $name        = $p['procedure'] ?? $p['service_name'] ?? $p['name'] ?? 'Procedure';
        $price       = (float)($p['final_price'] ?? $p['standard_price']   ?? 0);
        $qty         = (int)($p['quantity'] ?? 1);

        if (empty($name) || $price <= 0) continue;

        // Duplicate-invoice guard: skip if this pricing_id is already on an
        // active invoice for this visit.
        if ($pricing_id > 0) {
            $dup = $conn->prepare("
                SELECT 1
                FROM   invoice_items ii
                INNER  JOIN invoices i ON ii.invoice_id = i.invoice_id
                                     AND i.status      != 'CANCELLED'
                WHERE  i.visit_id       = ?
                  AND  ii.reference_id  = ?
                  AND  ii.item_type     = 'PROCEDURE'
                LIMIT  1
            ");
            $dup->bind_param("ii", $visit_id, $pricing_id);
            $dup->execute();
            $already_billed = $dup->get_result()->num_rows > 0;
            $dup->close();

            if ($already_billed) continue;
        }

        $services[] = [
            'item_type'    => 'PROCEDURE',
            'reference_id' => $pricing_id ?: null,
            'description'  => $name,
            'quantity'     => $qty,
            'unit_price'   => $price,
        ];
    }
}

echo json_encode([
    'success'  => true,
    'services' => $services,
    'count'    => count($services),
]);
