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

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

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

$allowed_roles = ['SUPER_ADMIN', 'HOSPITAL_ADMIN', 'CHIEF_PHARMACIST'];
if (!in_array($_SESSION['role_code'], $allowed_roles)) {
    echo json_encode(['success' => false, 'message' => 'Access denied. Only Chief Pharmacist or Administrator can reverse a dispensing.']);
    exit();
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    echo json_encode(['success' => false, 'message' => 'Invalid request method']);
    exit();
}

$dispensing_id = (int)($_POST['dispensing_id'] ?? 0);
$reason        = trim($_POST['reason'] ?? '');
$user_id       = (int)$_SESSION['user_id'];

if (!$dispensing_id) {
    echo json_encode(['success' => false, 'message' => 'Invalid dispensing ID']);
    exit();
}
if (empty($reason)) {
    echo json_encode(['success' => false, 'message' => 'A reason is required to reverse a dispensing']);
    exit();
}

// ── Load dispensing record ────────────────────────────────────────────────────
$stmt = $conn->prepare(
    "SELECT dispensing_id, dispensing_number, patient_name, total_amount,
            is_reversed, prescription_id, visit_id, patient_id
     FROM pharmacy_dispensing
     WHERE dispensing_id = ?"
);
$stmt->bind_param('i', $dispensing_id);
$stmt->execute();
$disp = $stmt->get_result()->fetch_assoc();
$stmt->close();

if (!$disp) {
    echo json_encode(['success' => false, 'message' => 'Dispensing record not found']);
    exit();
}
if ($disp['is_reversed']) {
    echo json_encode(['success' => false, 'message' => 'This dispensing has already been reversed']);
    exit();
}

// ── Load dispensing items ─────────────────────────────────────────────────────
$items_stmt = $conn->prepare(
    "SELECT inventory_id, item_name, quantity
     FROM pharmacy_dispensing_items
     WHERE dispensing_id = ?"
);
$items_stmt->bind_param('i', $dispensing_id);
$items_stmt->execute();
$items = $items_stmt->get_result()->fetch_all(MYSQLI_ASSOC);
$items_stmt->close();

if (empty($items)) {
    echo json_encode(['success' => false, 'message' => 'No dispensing items found to reverse']);
    exit();
}

// ── Determine linked invoice (for removal of medication lines) ─────────────────
$linked_invoice_id = null;
if ($disp['visit_id']) {
    $inv_q = $conn->prepare(
        "SELECT invoice_id FROM invoices
         WHERE visit_id = ? AND status NOT IN ('CANCELLED','VOID')
         ORDER BY created_at DESC LIMIT 1"
    );
    $inv_q->bind_param('i', $disp['visit_id']);
    $inv_q->execute();
    $inv_row = $inv_q->get_result()->fetch_assoc();
    $inv_q->close();
    if ($inv_row) {
        $linked_invoice_id = (int)$inv_row['invoice_id'];
    }
}

// ── BEGIN TRANSACTION ─────────────────────────────────────────────────────────
$conn->begin_transaction();

try {

    // 1. Restore stock for each dispensed item
    $stock_stmt = $conn->prepare(
        "UPDATE pharmacy_inventory
         SET current_stock = current_stock + ?
         WHERE inventory_id = ?"
    );
    foreach ($items as $item) {
        $stock_stmt->bind_param('ii', $item['quantity'], $item['inventory_id']);
        $stock_stmt->execute();
        if ($stock_stmt->affected_rows < 1) {
            throw new Exception("Failed to restore stock for {$item['item_name']}");
        }
    }
    $stock_stmt->close();

    // 2. Remove medication invoice lines that reference this dispensing
    if ($linked_invoice_id) {
        $del_lines = $conn->prepare(
            "DELETE FROM invoice_items
             WHERE invoice_id = ? AND item_type = 'MEDICATION' AND reference_id = ?"
        );
        $del_lines->bind_param('ii', $linked_invoice_id, $dispensing_id);
        $del_lines->execute();
        $del_lines->close();

        // 3. Recalculate invoice totals
        $conn->query(
            "UPDATE invoices
             SET subtotal        = (SELECT COALESCE(SUM(total_price),0) FROM invoice_items WHERE invoice_id = $linked_invoice_id),
                 total_amount    = (SELECT COALESCE(SUM(total_price),0) FROM invoice_items WHERE invoice_id = $linked_invoice_id),
                 patient_portion = (SELECT COALESCE(SUM(total_price),0) FROM invoice_items WHERE invoice_id = $linked_invoice_id)
                                   - COALESCE(insurance_covered, 0),
                 balance         = (SELECT COALESCE(SUM(total_price),0) FROM invoice_items WHERE invoice_id = $linked_invoice_id)
                                   - COALESCE(amount_paid, 0),
                 updated_at      = NOW()
             WHERE invoice_id = $linked_invoice_id"
        );
    }

    // 4. Mark dispensing as reversed
    $rev_stmt = $conn->prepare(
        "UPDATE pharmacy_dispensing
         SET is_reversed     = 1,
             reversed_at     = NOW(),
             reversed_by     = ?,
             reversal_reason = ?
         WHERE dispensing_id = ?"
    );
    $rev_stmt->bind_param('isi', $user_id, $reason, $dispensing_id);
    $rev_stmt->execute();
    $rev_stmt->close();

    // 5. If linked to a prescription, revert it to ACTIVE so it can be re-dispensed
    if ($disp['prescription_id']) {
        $rx_stmt = $conn->prepare(
            "UPDATE prescriptions
             SET dispensed = 0, status = 'ACTIVE'
             WHERE prescription_id = ? AND status = 'COMPLETED'"
        );
        $rx_stmt->bind_param('i', $disp['prescription_id']);
        $rx_stmt->execute();
        $rx_stmt->close();
    }

    // 6. Audit log
    $disp_num = $disp['dispensing_number'];
    $pat_name = $disp['patient_name'];
    $log_desc = "Reversed dispensing {$disp_num} for '{$pat_name}' — "
              . count($items) . " item(s), KES " . number_format((float)$disp['total_amount'], 2)
              . ". Stock restored. Reason: {$reason}";
    $ip = $_SERVER['REMOTE_ADDR'] ?? '';
    $log_stmt = $conn->prepare(
        "INSERT INTO activity_logs
            (user_id, action, entity_type, entity_id, description, ip_address, status)
         VALUES (?, 'REVERSE', 'DISPENSING', ?, ?, ?, 'SUCCESS')"
    );
    $log_stmt->bind_param('iiss', $user_id, $dispensing_id, $log_desc, $ip);
    $log_stmt->execute();
    $log_stmt->close();

    $conn->commit();

    echo json_encode([
        'success'     => true,
        'message'     => "Dispensing {$disp_num} reversed. Stock restored for " . count($items) . " item(s).",
        'invoice_updated' => (bool)$linked_invoice_id,
    ]);

} catch (Exception $e) {
    $conn->rollback();
    error_log('Dispensing reversal error: ' . $e->getMessage());
    echo json_encode(['success' => false, 'message' => 'Error during reversal: ' . $e->getMessage()]);
}
