<?php
require_once __DIR__ . '/../helpers/auth.php';
require_role(['driver']);
require_once __DIR__ . '/../helpers/audit.php';

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

try {
    $pdo = db();
    $user = current_user();

    $data = json_decode(file_get_contents('php://input'), true);
    if (!is_array($data)) {
        http_response_code(400);
        echo json_encode(['ok' => false, 'error' => 'Invalid JSON']);
        exit;
    }

    $delivery_id = (int)($data['delivery_id'] ?? 0);
    $status = trim((string)($data['status'] ?? ''));
    $allowed = ['PICKED_UP', 'IN_TRANSIT', 'DELIVERED'];

    if ($delivery_id <= 0 || !in_array($status, $allowed, true)) {
        http_response_code(400);
        echo json_encode(['ok' => false, 'error' => 'Invalid delivery_id or status']);
        exit;
    }

    $stmt = $pdo->prepare("\n        SELECT id, delivery_code, status, created_by\n        FROM deliveries\n        WHERE id = :id AND assigned_driver_id = :uid\n        LIMIT 1\n    ");
    $stmt->execute([
        ':id' => $delivery_id,
        ':uid' => (int)$user['id'],
    ]);
    $delivery = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$delivery) {
        http_response_code(404);
        echo json_encode(['ok' => false, 'error' => 'Delivery not found or not assigned to you']);
        exit;
    }

    $pdo->beginTransaction();

    if ($status === 'PICKED_UP') {
        $upd = $pdo->prepare("\n            UPDATE deliveries\n            SET status = 'PICKED_UP',\n                picked_up_at = COALESCE(picked_up_at, NOW())\n            WHERE id = :id\n        ");
        $upd->execute([':id' => $delivery_id]);
    }

    if ($status === 'IN_TRANSIT') {
        $upd = $pdo->prepare("\n            UPDATE deliveries\n            SET status = 'IN_TRANSIT'\n            WHERE id = :id\n        ");
        $upd->execute([':id' => $delivery_id]);
    }

    if ($status === 'DELIVERED') {
        $itemsStmt = $pdo->prepare("\n            SELECT di.product_id, di.quantity, p.name\n            FROM delivery_items di\n            JOIN products p ON p.id = di.product_id\n            WHERE di.delivery_id = :did\n            ORDER BY di.id ASC\n        ");
        $itemsStmt->execute([':did' => $delivery_id]);
        $items = $itemsStmt->fetchAll(PDO::FETCH_ASSOC);

        if (!$items) {
            $pdo->rollBack();
            http_response_code(400);
            echo json_encode(['ok' => false, 'error' => 'This delivery has no products/items yet.']);
            exit;
        }

        $chk = $pdo->prepare("\n            SELECT COUNT(*) AS cnt\n            FROM inventory_movements\n            WHERE reference_type = 'DELIVERY'\n              AND reference_id = :rid\n              AND movement_type = 'OUT'\n        ");
        $chk->execute([':rid' => $delivery_id]);
        $alreadyDeducted = (int)($chk->fetch(PDO::FETCH_ASSOC)['cnt'] ?? 0) > 0;

        if (!$alreadyDeducted) {
            $stockStmt = $pdo->prepare("\n                SELECT\n                    COALESCE(SUM(CASE WHEN movement_type = 'IN' THEN quantity ELSE 0 END), 0)\n                  - COALESCE(SUM(CASE WHEN movement_type = 'OUT' THEN quantity ELSE 0 END), 0)\n                  + COALESCE(SUM(CASE WHEN movement_type = 'ADJUST' THEN quantity ELSE 0 END), 0) AS stock\n                FROM inventory_movements\n                WHERE product_id = :pid\n            ");

            foreach ($items as $item) {
                $stockStmt->execute([':pid' => (int)$item['product_id']]);
                $available = (int)($stockStmt->fetch(PDO::FETCH_ASSOC)['stock'] ?? 0);
                $needed = (int)$item['quantity'];
                if ($needed > $available) {
                    $pdo->rollBack();
                    http_response_code(400);
                    echo json_encode([
                        'ok' => false,
                        'error' => 'Not enough stock for ' . $item['name'] . ' (need ' . $needed . ', have ' . $available . ')',
                    ]);
                    exit;
                }
            }

            $ins = $pdo->prepare("\n                INSERT INTO inventory_movements\n                    (product_id, movement_type, quantity, unit_cost, reference_type, reference_id, notes, created_by)\n                VALUES\n                    (:pid, 'OUT', :qty, NULL, 'DELIVERY', :rid, :notes, :uid)\n            ");

            foreach ($items as $item) {
                $ins->execute([
                    ':pid' => (int)$item['product_id'],
                    ':qty' => (int)$item['quantity'],
                    ':rid' => $delivery_id,
                    ':notes' => 'Delivered via ' . ($delivery['delivery_code'] ?? ('delivery #' . $delivery_id)),
                    ':uid' => (int)($delivery['created_by'] ?? 0),
                ]);
            }
        }

        $upd = $pdo->prepare("\n            UPDATE deliveries\n            SET status = 'DELIVERED',\n                delivered_at = COALESCE(delivered_at, NOW())\n            WHERE id = :id\n        ");
        $upd->execute([':id' => $delivery_id]);
    }

    $pdo->commit();

    audit_log(
        'DRIVER_UPDATE_STATUS',
        'deliveries',
        (string)$delivery_id,
        json_encode([
            'driver_id' => (int)$user['id'],
            'status' => $status,
        ], JSON_UNESCAPED_SLASHES)
    );

    $out = $pdo->prepare("\n        SELECT status, picked_up_at, delivered_at\n        FROM deliveries\n        WHERE id = :id\n        LIMIT 1\n    ");
    $out->execute([':id' => $delivery_id]);
    $row = $out->fetch(PDO::FETCH_ASSOC);

    echo json_encode([
        'ok' => true,
        'status' => $row['status'] ?? $status,
        'picked_up_at' => $row['picked_up_at'] ?? null,
        'delivered_at' => $row['delivered_at'] ?? null,
        'updated_at' => date('Y-m-d H:i:s'),
    ]);
    exit;

} catch (Throwable $e) {
    if (isset($pdo) && $pdo instanceof PDO && $pdo->inTransaction()) {
        $pdo->rollBack();
    }
    http_response_code(500);
    echo json_encode(['ok' => false, 'error' => $e->getMessage()]);
    exit;
}
