<?php
require_once __DIR__ . '/../helpers/auth.php';
require_once __DIR__ . '/../helpers/audit.php';
require_once __DIR__ . '/../helpers/inventory.php';
require_role(['admin', 'staff']);

$pdo = db();
$title = 'Adjust Stock - IMS';
$user = current_user();

function h(?string $value): string
{
    return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
}

function post_str(string $key): string
{
    return trim((string)($_POST[$key] ?? ''));
}

function post_int(string $key): int
{
    return (int)($_POST[$key] ?? 0);
}

if (isset($_GET['ajax']) && $_GET['ajax'] === 'lookup') {
    header('Content-Type: application/json');
    try {
        $code = trim((string)($_GET['code'] ?? ''));
        $product = inventory_find_product_by_code($pdo, $code, true);
        if (!$product) {
            http_response_code(404);
            echo json_encode(['ok' => false, 'error' => 'Product not found']);
            exit;
        }
        echo json_encode([
            'ok' => true,
            'product' => [
                'id' => (int)$product['id'],
                'sku' => (string)$product['sku'],
                'name' => (string)$product['name'],
                'unit' => (string)($product['unit'] ?? ''),
                'barcode_value' => $product['barcode_value'] ?? null,
                'current_stock' => (int)($product['current_stock'] ?? 0),
            ],
        ]);
    } catch (Throwable $e) {
        http_response_code(500);
        echo json_encode(['ok' => false, 'error' => $e->getMessage()]);
    }
    exit;
}

$error = '';
$success = '';
$selectedProduct = null;

$products = $pdo->query("\n    SELECT\n        p.id, p.sku, p.name, p.barcode_value,\n        COALESCE(stock_summary.current_stock, p.quantity_on_hand, 0) AS current_stock\n    FROM products p\n    LEFT JOIN (\n        SELECT m.product_id, " . inventory_stock_expression('m') . " AS current_stock\n        FROM inventory_movements m\n        GROUP BY m.product_id\n    ) stock_summary ON stock_summary.product_id = p.id\n    WHERE p.is_active = 1\n    ORDER BY p.name ASC\n")->fetchAll(PDO::FETCH_ASSOC);

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $productId = post_int('product_id');
    $scanCode = post_str('scan_code');
    $quantity = (int)($_POST['quantity'] ?? 0);
    $notes = post_str('notes');

    if ($productId <= 0 && $scanCode !== '') {
        $selectedProduct = inventory_find_product_by_code($pdo, $scanCode, true);
        $productId = (int)($selectedProduct['id'] ?? 0);
    }

    if ($productId <= 0) {
        $error = 'Select or scan a product first.';
    } elseif ($quantity === 0) {
        $error = 'Quantity cannot be zero for an adjustment.';
    } elseif ($notes === '') {
        $error = 'Please enter a reason for this stock adjustment.';
    } else {
        try {
            $selectedProduct = inventory_get_product($pdo, $productId);
            inventory_create_movement(
                $pdo,
                $productId,
                'ADJUST',
                $quantity,
                null,
                'MANUAL',
                null,
                $notes,
                (int)($user['id'] ?? 0),
                true
            );
            audit_log('ADJUST_STOCK', 'inventory_movements', (string)$productId, json_encode([
                'product_id' => $productId,
                'quantity' => $quantity,
                'notes' => $notes,
            ], JSON_UNESCAPED_SLASHES));
            $success = 'Stock adjusted successfully for ' . ($selectedProduct['name'] ?? ('product #' . $productId)) . '.';
        } catch (Throwable $e) {
            $error = $e->getMessage();
        }
    }
}

$recent = $pdo->query("\n    SELECT m.id, m.created_at, m.quantity, m.notes, p.sku, p.name, p.barcode_value\n    FROM inventory_movements m\n    INNER JOIN products p ON p.id = m.product_id\n    WHERE m.movement_type = 'ADJUST'\n    ORDER BY m.created_at DESC, m.id DESC\n    LIMIT 25\n")->fetchAll(PDO::FETCH_ASSOC);

require_once __DIR__ . '/../templates/header.php';
require_once __DIR__ . '/../templates/sidebar.php';
?>

<main class="col-12 col-lg-10 app-content">
  <div class="page-head">
    <div>
      <div class="page-kicker">Manual stock corrections</div>
      <h1 class="page-title">Adjust stock</h1>
      <p class="page-subtitle">Use this for recounts, damages, or corrections. For normal receiving and releasing, use stock in or stock out with barcode scan.</p>
    </div>
    <div class="d-flex gap-2 flex-wrap">
      <a class="btn btn-outline-secondary" href="stock_summary.php">Stock summary</a>
      <a class="btn btn-dark" href="stock_in.php">Stock in</a>
    </div>
  </div>

  <?php if ($error !== ''): ?>
    <div class="alert alert-danger mb-3"><?= h($error) ?></div>
  <?php endif; ?>
  <?php if ($success !== ''): ?>
    <div class="alert alert-success mb-3"><?= h($success) ?></div>
  <?php endif; ?>

  <div class="row g-3">
    <div class="col-12 col-xl-5">
      <div class="card">
        <div class="card-body p-4">
          <h5 class="mb-3">Adjustment entry</h5>
          <form method="post" id="adjustForm">
            <div class="mb-3">
              <label class="form-label">Scan barcode or SKU</label>
              <div class="input-group">
                <input class="form-control" type="text" id="scan_code" name="scan_code" autocomplete="off" placeholder="Scan with a USB barcode scanner">
                <button class="btn btn-outline-secondary" type="button" id="btnLookup">Lookup</button>
              </div>
              <div class="form-text">You can still choose a product manually below.</div>
            </div>

            <div class="soft-panel mb-3" id="selectedProductBox">
              <div class="fw-semibold mb-1">Selected product</div>
              <div id="selectedProductName">No product selected.</div>
              <div class="text-muted small" id="selectedProductMeta">Scan a code or choose a product.</div>
            </div>

            <div class="mb-3">
              <label class="form-label">Product</label>
              <select class="form-select" id="product_id" name="product_id" required>
                <option value="0">Select product</option>
                <?php foreach ($products as $product): ?>
                  <option value="<?= (int)$product['id'] ?>" data-sku="<?= h($product['sku']) ?>" data-barcode="<?= h($product['barcode_value'] ?? '') ?>" data-stock="<?= (int)$product['current_stock'] ?>">
                    <?= h($product['name']) ?> (<?= h($product['sku']) ?><?= !empty($product['barcode_value']) ? ' �� ' . h($product['barcode_value']) : '' ?>)
                  </option>
                <?php endforeach; ?>
              </select>
            </div>

            <div class="mb-3">
              <label class="form-label">Adjustment quantity</label>
              <input class="form-control" type="number" step="1" name="quantity" required placeholder="Use positive to add, negative to subtract">
              <div class="form-text">Examples: <code>5</code> for recount gain, <code>-2</code> for damage loss.</div>
            </div>

            <div class="mb-3">
              <label class="form-label">Reason</label>
              <textarea class="form-control" name="notes" rows="3" maxlength="255" required placeholder="Explain why this adjustment is needed"></textarea>
            </div>

            <div class="d-grid">
              <button class="btn btn-dark" type="submit">Save adjustment</button>
            </div>
          </form>
        </div>
      </div>
    </div>

    <div class="col-12 col-xl-7">
      <div class="card">
        <div class="card-body p-4">
          <h5 class="mb-3">Recent adjustments</h5>
          <div class="table-responsive">
            <table class="table align-middle">
              <thead>
                <tr>
                  <th>Date</th>
                  <th>Product</th>
                  <th class="text-end">Qty</th>
                  <th>Reason</th>
                </tr>
              </thead>
              <tbody>
                <?php if (!$recent): ?>
                  <tr><td colspan="4" class="text-muted">No adjustment history yet.</td></tr>
                <?php endif; ?>
                <?php foreach ($recent as $row): ?>
                  <tr>
                    <td><?= h((string)$row['created_at']) ?></td>
                    <td>
                      <div class="fw-semibold"><?= h((string)$row['name']) ?></div>
                      <div class="small text-muted"><span class="code-chip"><?= h((string)$row['sku']) ?></span><?= !empty($row['barcode_value']) ? ' �� ' . h((string)$row['barcode_value']) : '' ?></div>
                    </td>
                    <td class="text-end fw-semibold <?= (int)$row['quantity'] >= 0 ? 'text-success' : 'text-danger' ?>"><?= (int)$row['quantity'] ?></td>
                    <td><?= h((string)($row['notes'] ?? '-')) ?></td>
                  </tr>
                <?php endforeach; ?>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  </div>
</main>

<script>
const scanInput = document.getElementById('scan_code');
const lookupButton = document.getElementById('btnLookup');
const productSelect = document.getElementById('product_id');
const selectedProductName = document.getElementById('selectedProductName');
const selectedProductMeta = document.getElementById('selectedProductMeta');

function refreshSelectedProduct() {
  const selected = productCatalogById.get(String(productSelect.value || ''));
  if (selected) {
    selectedProductName.textContent = selected.name || 'Selected product';
    selectedProductMeta.textContent = `On hand: ${selected.current_stock || 0}. SKU ${selected.sku || ''}${selected.barcode_value ? ' � Barcode ' + selected.barcode_value : ''}`;
    return;
  }

  const option = productSelect.options[productSelect.selectedIndex];
  if (!option || !option.value || option.value === '0') {
    selectedProductName.textContent = 'No product selected.';
    selectedProductMeta.textContent = 'Scan a code or choose a product.';
    return;
  }
  selectedProductName.textContent = option.textContent;
  selectedProductMeta.textContent = `On hand: ${option.dataset.stock || 0}. SKU ${option.dataset.sku || ''}${option.dataset.barcode ? ' � Barcode ' + option.dataset.barcode : ''}`;
}

async function lookupCode() {
  const code = scanInput.value.trim();
  if (!code) {
    scanInput.focus();
    return;
  }

  const localProduct = findLocalProduct(code);
  if (localProduct) {
    productSelect.value = String(localProduct.id);
    refreshSelectedProduct();
    return;
  }

  selectedProductName.textContent = 'Looking up product...';
  selectedProductMeta.textContent = 'Please wait.';
  try {
    const response = await fetch(`adjust_stock.php?ajax=lookup&code=${encodeURIComponent(code)}`, {
      headers: { 'Accept': 'application/json' },
      credentials: 'same-origin'
    });
    const contentType = String(response.headers.get('content-type') || '');
    if (!contentType.includes('application/json')) {
      throw new Error('Non-JSON lookup response');
    }
    const data = await response.json();
    if (!data.ok) {
      throw new Error(data.error || 'Product not found');
    }
    productSelect.value = String(data.product.id);
    refreshSelectedProduct();
  } catch (error) {
    selectedProductName.textContent = 'Product not found.';
    selectedProductMeta.textContent = error.message || 'Barcode or SKU not found on this page.';
  }
}

lookupButton.addEventListener('click', lookupCode);
let lookupTimer = null;

function scheduleLookup(delay = 250) {
  window.clearTimeout(lookupTimer);
  const code = String(scanInput.value || '').trim();
  if (!code) {
    selectedName.textContent = 'No product selected';
    selectedMeta.textContent = 'Scan a code or choose a product.';
    return;
  }
  lookupTimer = window.setTimeout(() => lookupCode(), delay);
}

scanInput.addEventListener('keydown', (event) => {
  if (event.key === 'Enter') {
    event.preventDefault();
    window.clearTimeout(lookupTimer);
    lookupCode();
  }
});
scanInput.addEventListener('input', () => scheduleLookup(250));
scanInput.addEventListener('change', () => scheduleLookup(0));
scanInput.addEventListener('blur', () => scheduleLookup(0));
scanInput.addEventListener('paste', () => window.setTimeout(() => scheduleLookup(0), 0));
productSelect.addEventListener('change', refreshSelectedProduct);
refreshSelectedProduct();
scanInput.focus();
</script>

<?php require_once __DIR__ . '/../templates/footer.php'; ?>
