<?php
declare(strict_types=1);
require_once __DIR__ . '/../helpers.php';
require_post();
$adminUserId = as_int(get_post('admin_user_id'));
$admin = require_admin($adminUserId);
$saleId = as_int(get_post('sale_id'));
$reason = get_post('reason');
if ($saleId <= 0) {
    respond(['success' => false, 'message' => 'Sale ID is required.'], 400);
}
if ($reason === '') {
    respond(['success' => false, 'message' => 'Void reason is required.'], 400);
}
$conn = db();
ensure_void_request_table();
$conn->begin_transaction();
try {
    $saleStmt = $conn->prepare('SELECT id, receipt_no, total_amount, notes, ' . sales_status_select_sql('sales') . ' AS sale_status' . (table_has_column('sales', 'status_reason') ? ', status_reason' : '') . ' FROM sales WHERE id = ? FOR UPDATE');
    $saleStmt->bind_param('i', $saleId);
    $saleStmt->execute();
    $sale = $saleStmt->get_result()->fetch_assoc();
    if (!$sale) {
        throw new Exception('Receipt not found.');
    }
    $statusPayload = sale_status_payload_from_row($sale);
    if (($statusPayload['sale_status'] ?? 'active') !== 'active') {
        throw new Exception('Only active purchases can be voided.');
    }

    $itemsStmt = $conn->prepare('SELECT item_id, item_name, quantity FROM sale_items WHERE sale_id = ? FOR UPDATE');
    $itemsStmt->bind_param('i', $saleId);
    $itemsStmt->execute();
    $itemsResult = $itemsStmt->get_result();
    $totalQty = 0;
    while ($row = $itemsResult->fetch_assoc()) {
        $itemId = (int)$row['item_id'];
        $qty = (int)$row['quantity'];
        $totalQty += $qty;
        $stockStmt = $conn->prepare('UPDATE items SET quantity = quantity + ?, updated_at = NOW() WHERE id = ?');
        $stockStmt->bind_param('ii', $qty, $itemId);
        $stockStmt->execute();
    }

    if (table_has_column('sales', 'sale_status')) {
        $update = $conn->prepare(build_sales_status_update_sql('voided'));
        bind_sales_status_update($update, $reason, $adminUserId, $saleId);
        $update->execute();
        if ($update->affected_rows < 1) {
            throw new Exception('Purchase was not voided.');
        }
    } else {
        $statusNote = build_sale_status_note('voided', $reason, $sale['notes'] ?? null);
        $update = $conn->prepare('UPDATE sales SET notes = ? WHERE id = ?');
        $update->bind_param('si', $statusNote, $saleId);
        $update->execute();
        if ($update->affected_rows < 1) {
            throw new Exception('Purchase was not voided.');
        }
    }

    $resolve = $conn->prepare("UPDATE sale_void_requests SET request_status = 'approved', admin_note = CONCAT(COALESCE(admin_note,''), CASE WHEN COALESCE(admin_note,'') = '' THEN '' ELSE ' | ' END, 'Resolved via direct admin action'), processed_by = ?, processed_at = NOW() WHERE sale_id = ? AND request_status = 'pending'");
    $resolve->bind_param('ii', $adminUserId, $saleId);
    $resolve->execute();

    $conn->commit();
    $amount = number_format((float)$sale['total_amount'], 2, '.', '');
    log_activity($adminUserId, 'VOID_SALE', "Admin {$admin['full_name']} voided receipt {$sale['receipt_no']} | reason: {$reason} | reverted qty: {$totalQty} | reverted amount: {$amount}");
    respond(['success' => true, 'message' => 'Purchase voided. Stock and sales totals were reverted.']);
} catch (Throwable $e) {
    $conn->rollback();
    respond(['success' => false, 'message' => $e->getMessage()], 400);
}
