<?php
// POST /api/stock/return_jobcard.php
// Returns items previously booked out to a job card back into stock.
require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../config/auth.php';
$user = requireRole([1, 2, 3, 4, 5]);
$db   = getDB();

$jobCardId = (int)post('job_card_id', 0);
if (!$jobCardId) apiError('Job card ID required.', 422);

$rawLines = $_POST['lines'] ?? '';
if (is_string($rawLines) && strlen($rawLines) > 0) {
    $lines = json_decode($rawLines, true) ?: [];
} elseif (is_array($rawLines)) {
    $lines = $rawLines;
} else {
    $lines = [];
}
if (empty($lines)) apiError('No items provided.', 422);

$notes = post('notes', '');
$refNo = 'RTN-' . date('YmdHis');

// Get default location (same as bookin.php)
function getDefaultLocation($db): int {
    $loc = $db->query("SELECT id FROM stock_locations WHERE is_active=1 ORDER BY id LIMIT 1")->fetch();
    if (!$loc) {
        $db->exec("INSERT INTO stock_locations (name, description) VALUES ('Main Warehouse', 'Default storage location')");
        return (int)$db->lastInsertId();
    }
    return (int)$loc['id'];
}

try {
    $db->beginTransaction();
    $locId = getDefaultLocation($db);

    foreach ($lines as $line) {
        $itemId  = (int)($line['item_id'] ?? 0);
        $qtyReturn = (float)($line['qty'] ?? 0);
        if (!$itemId || $qtyReturn <= 0) continue;

        // How much was issued to this job card (net of any prior returns)
        $netStmt = $db->prepare("
            SELECT
                COALESCE(SUM(CASE WHEN transaction_type = 'issue_jobcard' THEN quantity ELSE 0 END), 0)
              - COALESCE(SUM(CASE WHEN transaction_type = 'return'         THEN quantity ELSE 0 END), 0)
              AS net_issued
            FROM stock_transactions
            WHERE job_card_id = ? AND stock_item_id = ?
              AND transaction_type IN ('issue_jobcard', 'return')
        ");
        $netStmt->execute([$jobCardId, $itemId]);
        $netIssued = (float)$netStmt->fetchColumn();

        if ($qtyReturn > $netIssued + 0.0001) {
            $nm = $db->query("SELECT name FROM stock_items WHERE id=$itemId")->fetchColumn();
            $db->rollBack();
            apiError("Cannot return more than issued for '$nm'. Max returnable: $netIssued.", 422);
        }

        // Get unit cost from original issue transaction
        $ucStmt = $db->prepare("
            SELECT unit_cost FROM stock_transactions
            WHERE job_card_id = ? AND stock_item_id = ? AND transaction_type = 'issue_jobcard'
            ORDER BY transaction_date DESC LIMIT 1
        ");
        $ucStmt->execute([$jobCardId, $itemId]);
        $unitCost = (float)($ucStmt->fetchColumn() ?? 0);

        // Record return transaction linked to the job card
        $db->prepare("
            INSERT INTO stock_transactions
                (stock_item_id, transaction_type, quantity, unit_cost, user_id, job_card_id, reference_no, notes, transaction_date)
            VALUES (?, 'return', ?, ?, ?, ?, ?, ?, NOW())
        ")->execute([$itemId, $qtyReturn, $unitCost, $user['id'], $jobCardId, $refNo, $notes]);

        // Add qty back to default location inventory
        $check = $db->prepare("SELECT id FROM stock_inventory WHERE stock_item_id=? AND location_id=?");
        $check->execute([$itemId, $locId]);
        if ($check->fetch()) {
            $db->prepare("UPDATE stock_inventory SET quantity = quantity + ? WHERE stock_item_id=? AND location_id=?")
               ->execute([$qtyReturn, $itemId, $locId]);
        } else {
            $db->prepare("INSERT INTO stock_inventory (stock_item_id, location_id, quantity) VALUES (?,?,?)")
               ->execute([$itemId, $locId, $qtyReturn]);
        }
    }

    $db->commit();
    apiSuccess(['reference' => $refNo], 'Items returned to stock.');

} catch (PDOException $e) {
    if ($db->inTransaction()) $db->rollBack();
    apiError('Database error: ' . $e->getMessage(), 500);
} catch (Exception $e) {
    if ($db->inTransaction()) $db->rollBack();
    apiError($e->getMessage(), 500);
}