<?php
// FILE: public/deliveries.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 = 'Deliveries - 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);
}

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

function normalize_optional_datetime(string $input): ?string
{
    $value = trim($input);
    if ($value === '') {
        return null;
    }

    $value = str_replace('T', ' ', $value);
    if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/', $value)) {
        return $value . ':00';
    }
    if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $value)) {
        return $value;
    }
    return null;
}

function status_badge(string $status): string
{
    $safe = preg_replace('/[^A-Z_]+/', '', strtoupper($status)) ?: 'PENDING';
    return '<span class="status-pill status-' . h($safe) . '">' . h(str_replace('_', ' ', $safe)) . '</span>';
}

$error = '';
$success = '';

$drivers = $pdo->query("
    SELECT u.id, u.full_name
    FROM users u
    INNER JOIN roles r ON r.id = u.role_id
    WHERE r.name = 'driver' AND u.is_active = 1
    ORDER BY u.full_name ASC
")->fetchAll(PDO::FETCH_ASSOC);

$customers = $pdo->query("
    SELECT id, name, phone, address
    FROM customers
    ORDER BY name ASC
")->fetchAll(PDO::FETCH_ASSOC);

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

if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'create_delivery') {
    $customerId = post_int('customer_id') ?: null;
    $driverId = post_int('assigned_driver_id') ?: null;
    $scheduledAt = normalize_optional_datetime(post_str('scheduled_at'));
    $notes = post_str('notes');

    $pickupAddress = post_str('pickup_address');
    $dropoffAddress = post_str('dropoff_address');

    $pickupLat = post_str('pickup_lat');
    $pickupLng = post_str('pickup_lng');
    $dropoffLat = post_str('dropoff_lat');
    $dropoffLng = post_str('dropoff_lng');

    $itemProductIds = $_POST['item_product_id'] ?? [];
    $itemQuantities = $_POST['item_quantity'] ?? [];

    if ($pickupAddress === '' || $dropoffAddress === '') {
        $error = 'Pickup and dropoff address are required.';
    } elseif ($pickupLat === '' || $pickupLng === '' || $dropoffLat === '' || $dropoffLng === '') {
        $error = 'Please pin both pickup and dropoff addresses on the map first.';
    } else {
        $deliveryItems = [];
        if (is_array($itemProductIds) && is_array($itemQuantities)) {
            $count = min(count($itemProductIds), count($itemQuantities));
            for ($i = 0; $i < $count; $i++) {
                $productId = (int)$itemProductIds[$i];
                $qty = (int)$itemQuantities[$i];
                if ($productId > 0 && $qty > 0) {
                    if (!isset($deliveryItems[$productId])) {
                        $deliveryItems[$productId] = 0;
                    }
                    $deliveryItems[$productId] += $qty;
                }
            }
        }

        if (!$deliveryItems) {
            $error = 'Add at least one delivery item with quantity greater than zero.';
        } else {
            try {
                $pdo->beginTransaction();

                do {
                    $deliveryCode = 'DLV-' . date('Ymd') . '-' . random_int(100000, 999999);
                    $check = $pdo->prepare('SELECT id FROM deliveries WHERE delivery_code = :code LIMIT 1');
                    $check->execute([':code' => $deliveryCode]);
                } while ($check->fetch(PDO::FETCH_ASSOC));

                $status = $driverId ? 'ASSIGNED' : 'PENDING';

                $stmt = $pdo->prepare("
                    INSERT INTO deliveries
                        (
                            delivery_code,
                            customer_id,
                            assigned_driver_id,
                            status,
                            pickup_address,
                            dropoff_address,
                            pickup_lat,
                            pickup_lng,
                            dropoff_lat,
                            dropoff_lng,
                            notes,
                            scheduled_at,
                            created_by
                        )
                    VALUES
                        (
                            :delivery_code,
                            :customer_id,
                            :assigned_driver_id,
                            :status,
                            :pickup_address,
                            :dropoff_address,
                            :pickup_lat,
                            :pickup_lng,
                            :dropoff_lat,
                            :dropoff_lng,
                            :notes,
                            :scheduled_at,
                            :created_by
                        )
                ");
                $stmt->execute([
                    ':delivery_code' => $deliveryCode,
                    ':customer_id' => $customerId,
                    ':assigned_driver_id' => $driverId,
                    ':status' => $status,
                    ':pickup_address' => $pickupAddress,
                    ':dropoff_address' => $dropoffAddress,
                    ':pickup_lat' => (float)$pickupLat,
                    ':pickup_lng' => (float)$pickupLng,
                    ':dropoff_lat' => (float)$dropoffLat,
                    ':dropoff_lng' => (float)$dropoffLng,
                    ':notes' => $notes !== '' ? $notes : null,
                    ':scheduled_at' => $scheduledAt,
                    ':created_by' => (int)($user['id'] ?? 0),
                ]);
                $deliveryId = (int)$pdo->lastInsertId();

                $itemStmt = $pdo->prepare("
                    INSERT INTO delivery_items (delivery_id, product_id, quantity)
                    VALUES (:delivery_id, :product_id, :quantity)
                    ON DUPLICATE KEY UPDATE quantity = quantity + VALUES(quantity)
                ");
                foreach ($deliveryItems as $productId => $qty) {
                    $itemStmt->execute([
                        ':delivery_id' => $deliveryId,
                        ':product_id' => (int)$productId,
                        ':quantity' => (int)$qty,
                    ]);
                }

                $pdo->commit();

                audit_log(
                    'CREATE_DELIVERY',
                    'deliveries',
                    (string)$deliveryId,
                    json_encode([
                        'delivery_code' => $deliveryCode,
                        'status' => $status,
                        'assigned_driver_id' => $driverId,
                        'pickup_address' => $pickupAddress,
                        'dropoff_address' => $dropoffAddress,
                        'item_count' => count($deliveryItems),
                    ], JSON_UNESCAPED_SLASHES)
                );

                $success = 'Delivery created successfully as ' . $deliveryCode . '.';
            } catch (Throwable $e) {
                if ($pdo->inTransaction()) {
                    $pdo->rollBack();
                }
                $error = 'Failed to create delivery: ' . $e->getMessage();
            }
        }
    }
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'update_status') {
    $deliveryId = post_int('delivery_id');
    $status = strtoupper(post_str('status'));

    if ($deliveryId <= 0 || $status === '') {
        $error = 'Choose a delivery and status.';
    } else {
        try {
            $result = delivery_update_status($pdo, $deliveryId, $status, (int)($user['id'] ?? 0));
            $delivery = $result['delivery'] ?? null;

            audit_log(
                'UPDATE_DELIVERY_STATUS',
                'deliveries',
                (string)$deliveryId,
                json_encode([
                    'status' => $status,
                    'stock_deducted' => !empty($result['stock_deducted']),
                ], JSON_UNESCAPED_SLASHES)
            );

            $success = 'Delivery ' . (string)($delivery['delivery_code'] ?? ('#' . $deliveryId)) . ' updated to ' . $status . (!empty($result['stock_deducted']) ? ' and stock was released.' : '.');
        } catch (Throwable $e) {
            $error = $e->getMessage();
        }
    }
}

$filterStatus = strtoupper(get_str('status'));
$filterQ = get_str('q');
$allowedStatusFilters = ['', 'PENDING', 'ASSIGNED', 'PICKED_UP', 'IN_TRANSIT', 'DELIVERED', 'CANCELLED'];
if (!in_array($filterStatus, $allowedStatusFilters, true)) {
    $filterStatus = '';
}

$stats = $pdo->query("
    SELECT
        COUNT(*) AS total_deliveries,
        SUM(CASE WHEN status IN ('PENDING', 'ASSIGNED') THEN 1 ELSE 0 END) AS queued_deliveries,
        SUM(CASE WHEN status IN ('PICKED_UP', 'IN_TRANSIT') THEN 1 ELSE 0 END) AS active_routes,
        SUM(CASE WHEN DATE(COALESCE(delivered_at, created_at)) = CURDATE() AND status = 'DELIVERED' THEN 1 ELSE 0 END) AS delivered_today
    FROM deliveries
")->fetch(PDO::FETCH_ASSOC) ?: [];

$liveTracking = $pdo->query("
    SELECT COUNT(*)
    FROM (
        SELECT delivery_id, MAX(recorded_at) AS last_recorded_at
        FROM delivery_locations
        GROUP BY delivery_id
    ) t
    INNER JOIN deliveries d ON d.id = t.delivery_id
    WHERE d.status IN ('PICKED_UP', 'IN_TRANSIT')
      AND t.last_recorded_at >= (NOW() - INTERVAL 15 MINUTE)
")->fetchColumn();

$sql = "
    SELECT
        d.id,
        d.delivery_code,
        d.status,
        d.pickup_address,
        d.dropoff_address,
        d.scheduled_at,
        d.created_at,
        d.delivered_at,
        c.name AS customer_name,
        u.full_name AS driver_name,
        COALESCE(item_summary.item_count, 0) AS item_count,
        COALESCE(item_summary.total_qty, 0) AS total_qty,
        COALESCE(track_summary.point_count, 0) AS point_count,
        track_summary.last_recorded_at
    FROM deliveries d
    LEFT JOIN customers c ON c.id = d.customer_id
    LEFT JOIN users u ON u.id = d.assigned_driver_id
    LEFT JOIN (
        SELECT delivery_id, COUNT(*) AS item_count, SUM(quantity) AS total_qty
        FROM delivery_items
        GROUP BY delivery_id
    ) item_summary ON item_summary.delivery_id = d.id
    LEFT JOIN (
        SELECT delivery_id, COUNT(*) AS point_count, MAX(recorded_at) AS last_recorded_at
        FROM delivery_locations
        GROUP BY delivery_id
    ) track_summary ON track_summary.delivery_id = d.id
    WHERE 1 = 1
";
$params = [];
if ($filterStatus !== '') {
    $sql .= ' AND d.status = :status';
    $params[':status'] = $filterStatus;
}
if ($filterQ !== '') {
    $sql .= ' AND (d.delivery_code LIKE :q OR d.pickup_address LIKE :q OR d.dropoff_address LIKE :q OR c.name LIKE :q OR u.full_name LIKE :q)';
    $params[':q'] = '%' . $filterQ . '%';
}
$sql .= ' ORDER BY COALESCE(d.scheduled_at, d.created_at) DESC, d.id DESC LIMIT 200';
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$deliveries = $stmt->fetchAll(PDO::FETCH_ASSOC);

$statusChoices = ['PENDING', 'ASSIGNED', 'PICKED_UP', 'IN_TRANSIT', 'DELIVERED', 'CANCELLED'];

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">Delivery operations</div>
      <h1 class="page-title">Deliveries and live tracking</h1>
      <p class="page-subtitle">Enter complete pickup and dropoff addresses, automatically pin both locations on the map, and show the actual road path between them.</p>
    </div>
    <div class="d-flex flex-wrap gap-2">
      <a class="btn btn-outline-secondary" href="customers.php">Manage customers</a>
      <a class="btn btn-dark" href="live_map.php">Open live map</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 mb-3">
    <div class="col-12 col-md-6 col-xl-3">
      <div class="stat-card">
        <div class="stat-label">Total deliveries</div>
        <div class="stat-value"><?= (int)($stats['total_deliveries'] ?? 0) ?></div>
        <div class="stat-sub">All recorded routes</div>
      </div>
    </div>
    <div class="col-12 col-md-6 col-xl-3">
      <div class="stat-card">
        <div class="stat-label">Queued</div>
        <div class="stat-value"><?= (int)($stats['queued_deliveries'] ?? 0) ?></div>
        <div class="stat-sub">Pending or assigned</div>
      </div>
    </div>
    <div class="col-12 col-md-6 col-xl-3">
      <div class="stat-card">
        <div class="stat-label">Active routes</div>
        <div class="stat-value"><?= (int)($stats['active_routes'] ?? 0) ?></div>
        <div class="stat-sub"><?= (int)$liveTracking ?> with fresh GPS in the last 15 minutes</div>
      </div>
    </div>
    <div class="col-12 col-md-6 col-xl-3">
      <div class="stat-card">
        <div class="stat-label">Delivered today</div>
        <div class="stat-value"><?= (int)($stats['delivered_today'] ?? 0) ?></div>
        <div class="stat-sub">Completed deliveries today</div>
      </div>
    </div>
  </div>

  <div class="row g-3">
    <div class="col-12 col-xl-6">
      <div class="card">
        <div class="card-body p-4">
          <div class="d-flex justify-content-between align-items-start mb-3">
            <div>
              <h5 class="mb-1">Create delivery</h5>
              <div class="text-muted small">Use full address fields. The system geocodes, pins both points, and draws the road route automatically.</div>
            </div>
            <a class="btn btn-sm btn-outline-secondary" href="customers.php">Add customer</a>
          </div>

          <form method="post" id="deliveryCreateForm" novalidate>
            <input type="hidden" name="action" value="create_delivery">

            <div class="row g-3">
              <div class="col-12 col-md-6">
                <label class="form-label">Customer</label>
                <select class="form-select" name="customer_id">
                  <option value="0">Walk-in / not set</option>
                  <?php foreach ($customers as $customer): ?>
                    <option value="<?= (int)$customer['id'] ?>"><?= h($customer['name']) ?></option>
                  <?php endforeach; ?>
                </select>
              </div>

              <div class="col-12 col-md-6">
                <label class="form-label">Assigned driver</label>
                <select class="form-select" name="assigned_driver_id">
                  <option value="0">Assign later</option>
                  <?php foreach ($drivers as $driver): ?>
                    <option value="<?= (int)$driver['id'] ?>"><?= h($driver['full_name']) ?></option>
                  <?php endforeach; ?>
                </select>
              </div>
            </div>

            <div class="soft-panel mt-3">
              <div class="fw-semibold mb-3">Pickup address</div>
              <div class="row g-3 address-block" data-prefix="pickup">
                <div class="col-12">
                  <label class="form-label">Street / building / unit</label>
                  <input class="form-control address-part" type="text" data-field="street" placeholder="Street, building, warehouse, unit, landmark">
                </div>
                <div class="col-12 col-md-6">
                  <label class="form-label">City</label>
                  <input class="form-control address-part" type="text" data-field="city" placeholder="City / municipality">
                </div>
                <div class="col-12 col-md-3">
                  <label class="form-label">Postal code</label>
                  <input class="form-control address-part" type="text" data-field="postal" placeholder="Postal code">
                </div>
                <div class="col-12 col-md-3">
                  <label class="form-label">Country</label>
                  <input class="form-control address-part" type="text" data-field="country" placeholder="Country">
                </div>
                <div class="col-12">
                  <label class="form-label">Complete address</label>
                  <textarea class="form-control" id="pickup_address_preview" rows="2" readonly placeholder="Generated complete address"></textarea>
                </div>
              </div>
            </div>

            <div class="soft-panel mt-3">
              <div class="fw-semibold mb-3">Dropoff address</div>
              <div class="row g-3 address-block" data-prefix="dropoff">
                <div class="col-12">
                  <label class="form-label">Street / building / unit</label>
                  <input class="form-control address-part" type="text" data-field="street" placeholder="Street, building, house, unit, landmark">
                </div>
                <div class="col-12 col-md-6">
                  <label class="form-label">City</label>
                  <input class="form-control address-part" type="text" data-field="city" placeholder="City / municipality">
                </div>
                <div class="col-12 col-md-3">
                  <label class="form-label">Postal code</label>
                  <input class="form-control address-part" type="text" data-field="postal" placeholder="Postal code">
                </div>
                <div class="col-12 col-md-3">
                  <label class="form-label">Country</label>
                  <input class="form-control address-part" type="text" data-field="country" placeholder="Country">
                </div>
                <div class="col-12">
                  <label class="form-label">Complete address</label>
                  <textarea class="form-control" id="dropoff_address_preview" rows="2" readonly placeholder="Generated complete address"></textarea>
                </div>
              </div>
            </div>

            <input type="hidden" name="pickup_address" id="pickup_address">
            <input type="hidden" name="dropoff_address" id="dropoff_address">
            <input type="hidden" name="pickup_lat" id="pickup_lat">
            <input type="hidden" name="pickup_lng" id="pickup_lng">
            <input type="hidden" name="dropoff_lat" id="dropoff_lat">
            <input type="hidden" name="dropoff_lng" id="dropoff_lng">

            <div class="row g-3 mt-1">
              <div class="col-12 col-md-6">
                <label class="form-label">Scheduled time</label>
                <input class="form-control" type="datetime-local" name="scheduled_at">
              </div>
              <div class="col-12 col-md-6">
                <label class="form-label">Notes</label>
                <input class="form-control" type="text" name="notes" maxlength="255" placeholder="Special handling or driver note">
              </div>
            </div>

            <div class="soft-panel mt-3">
              <div class="d-flex justify-content-between align-items-center mb-2">
                <div>
                  <div class="fw-semibold">Items</div>
                  <div class="text-muted small">Use one line per product. Quantities for the same product are merged automatically.</div>
                </div>
                <button class="btn btn-sm btn-outline-dark" type="button" id="btnAddItemRow">Add item</button>
              </div>
              <div id="deliveryItems"></div>
            </div>

            <div class="d-grid mt-3">
              <button class="btn btn-dark" type="submit" id="createDeliveryBtn">Create delivery</button>
            </div>
          </form>
        </div>
      </div>
    </div>

    <div class="col-12 col-xl-6">
      <div class="card h-100">
        <div class="card-body p-4">
          <div class="d-flex justify-content-between align-items-start mb-3">
            <div>
              <h5 class="mb-1">Address map preview</h5>
              <div class="text-muted small">Markers are auto-created after address lookup. A road route path is also drawn between pickup and dropoff.</div>
            </div>
            <button class="btn btn-sm btn-outline-secondary" type="button" id="btnGeocodeBoth">Pin both addresses</button>
          </div>

          <div id="addressMap" style="height: 360px; border-radius: 14px;"></div>

          <div class="row g-3 mt-3">
            <div class="col-12 col-md-4">
              <div class="soft-panel h-100">
                <div class="fw-semibold mb-2">Pickup coordinates</div>
                <div class="small text-muted" id="pickupCoordText">Not pinned yet.</div>
              </div>
            </div>
            <div class="col-12 col-md-4">
              <div class="soft-panel h-100">
                <div class="fw-semibold mb-2">Dropoff coordinates</div>
                <div class="small text-muted" id="dropoffCoordText">Not pinned yet.</div>
              </div>
            </div>
            <div class="col-12 col-md-4">
              <div class="soft-panel h-100">
                <div class="fw-semibold mb-2">Route summary</div>
                <div class="small text-muted" id="routeSummaryText">No route yet.</div>
              </div>
            </div>
          </div>

          <div class="alert alert-info mt-3 mb-0 py-2">
            Tip: after both addresses are pinned, the system draws the road route automatically. You can still drag markers and the route will refresh.
          </div>
        </div>
      </div>

      <div class="card mt-3">
        <div class="card-body p-4">
          <div class="d-flex flex-wrap gap-2 justify-content-between align-items-start mb-3">
            <div>
              <h5 class="mb-1">Recent deliveries</h5>
              <div class="text-muted small">Quickly review route activity, GPS freshness, and status.</div>
            </div>
            <form class="d-flex flex-wrap gap-2" method="get">
              <input class="form-control" style="min-width: 220px;" type="search" name="q" value="<?= h($filterQ) ?>" placeholder="Search code, customer, address, driver">
              <select class="form-select" name="status" style="min-width: 180px;">
                <option value="">All statuses</option>
                <?php foreach ($statusChoices as $statusChoice): ?>
                  <option value="<?= h($statusChoice) ?>" <?= $filterStatus === $statusChoice ? 'selected' : '' ?>><?= h(str_replace('_', ' ', $statusChoice)) ?></option>
                <?php endforeach; ?>
              </select>
              <button class="btn btn-outline-secondary" type="submit">Filter</button>
            </form>
          </div>

          <div class="table-responsive">
            <table class="table align-middle">
              <thead>
                <tr>
                  <th>Delivery</th>
                  <th>Route</th>
                  <th>Tracking</th>
                  <th>Status</th>
                  <th class="text-end">Actions</th>
                </tr>
              </thead>
              <tbody>
                <?php if (!$deliveries): ?>
                  <tr>
                    <td colspan="5" class="text-muted">No deliveries matched your filters.</td>
                  </tr>
                <?php endif; ?>

                <?php foreach ($deliveries as $delivery): ?>
                  <?php
                    $lastPing = $delivery['last_recorded_at'] ?? null;
                    $isLive = $lastPing !== null && strtotime((string)$lastPing) >= (time() - 900);
                  ?>
                  <tr>
                    <td>
                      <div class="fw-semibold"><?= h($delivery['delivery_code']) ?></div>
                      <div class="small text-muted"><?= h($delivery['customer_name'] ?: 'No customer') ?></div>
                      <div class="small text-muted">Driver: <?= h($delivery['driver_name'] ?: 'Unassigned') ?></div>
                      <div class="small text-muted">Items: <?= (int)$delivery['item_count'] ?> / Qty: <?= (int)$delivery['total_qty'] ?></div>
                    </td>
                    <td>
                      <div class="small"><strong>Pickup:</strong> <?= h($delivery['pickup_address']) ?></div>
                      <div class="small"><strong>Dropoff:</strong> <?= h($delivery['dropoff_address']) ?></div>
                      <div class="small text-muted mt-1">
                        <?= $delivery['scheduled_at'] ? 'Scheduled ' . h($delivery['scheduled_at']) : 'Created ' . h($delivery['created_at']) ?>
                      </div>
                    </td>
                    <td>
                      <div class="small"><?= $isLive ? '<span class="status-pill status-ok">Live</span>' : '<span class="status-pill status-neutral">Idle</span>' ?></div>
                      <div class="small text-muted mt-2">Points: <?= (int)$delivery['point_count'] ?></div>
                      <div class="small text-muted">Last ping: <?= h($lastPing ?: 'No GPS yet') ?></div>
                    </td>
                    <td>
                      <div class="mb-2"><?= status_badge((string)$delivery['status']) ?></div>
                      <form method="post" class="d-flex gap-2 align-items-center">
                        <input type="hidden" name="action" value="update_status">
                        <input type="hidden" name="delivery_id" value="<?= (int)$delivery['id'] ?>">
                        <select class="form-select form-select-sm" name="status">
                          <?php foreach ($statusChoices as $statusChoice): ?>
                            <option value="<?= h($statusChoice) ?>" <?= strtoupper((string)$delivery['status']) === $statusChoice ? 'selected' : '' ?>><?= h(str_replace('_', ' ', $statusChoice)) ?></option>
                          <?php endforeach; ?>
                        </select>
                        <button class="btn btn-sm btn-outline-dark" type="submit">Save</button>
                      </form>
                    </td>
                    <td class="text-end">
                      <div class="d-flex flex-column gap-2 align-items-end">
                        <a class="btn btn-sm btn-outline-secondary" href="delivery_view.php?id=<?= (int)$delivery['id'] ?>">Open details</a>
                        <a class="btn btn-sm btn-dark" href="map_live.php?id=<?= (int)$delivery['id'] ?>">Live map</a>
                      </div>
                    </td>
                  </tr>
                <?php endforeach; ?>
              </tbody>
            </table>
          </div>

        </div>
      </div>
    </div>
  </div>
</main>

<template id="deliveryItemTemplate">
  <div class="row g-2 align-items-start delivery-item-row mb-2">
    <div class="col-12 col-md-8">
      <select class="form-select" name="item_product_id[]" required>
        <option value="0">Select product</option>
        <?php foreach ($products as $product): ?>
          <option
            value="<?= (int)$product['id'] ?>"
            data-stock="<?= (int)$product['current_stock'] ?>"
            data-sku="<?= h($product['sku']) ?>"
            data-barcode="<?= h($product['barcode_value'] ?? '') ?>"
            data-unit="<?= h($product['unit']) ?>"
          >
            <?= h($product['name']) ?> (<?= h($product['sku']) ?><?= !empty($product['barcode_value']) ? ' กค ' . h($product['barcode_value']) : '' ?>)
          </option>
        <?php endforeach; ?>
      </select>
      <div class="small text-muted item-hint mt-1">Select a product to see current stock.</div>
    </div>
    <div class="col-8 col-md-3">
      <input class="form-control" type="number" min="1" step="1" name="item_quantity[]" placeholder="Qty" required>
    </div>
    <div class="col-4 col-md-1 d-grid">
      <button class="btn btn-outline-danger remove-item-row" type="button">กม</button>
    </div>
  </div>
</template>

<?php require_once __DIR__ . '/../templates/footer.php'; ?>
<script>
(function () {
  const itemsContainer = document.getElementById('deliveryItems');
  const itemTemplate = document.getElementById('deliveryItemTemplate');
  const addItemButton = document.getElementById('btnAddItemRow');

  function refreshItemHint(row) {
    const select = row.querySelector('select[name="item_product_id[]"]');
    const hint = row.querySelector('.item-hint');
    const option = select.options[select.selectedIndex];

    if (!option || !option.value || option.value === '0') {
      hint.textContent = 'Select a product to see current stock.';
      return;
    }

    const stock = option.dataset.stock || '0';
    const sku = option.dataset.sku || '';
    const barcode = option.dataset.barcode || '';
    const unit = option.dataset.unit || '';
    hint.textContent = `On hand: ${stock} ${unit}. SKU ${sku}${barcode ? ' กค Barcode ' + barcode : ''}`;
  }

  function bindItemRow(row) {
    row.querySelector('.remove-item-row').addEventListener('click', () => {
      if (itemsContainer.children.length > 1) {
        row.remove();
      } else {
        row.querySelector('select[name="item_product_id[]"]').value = '0';
        row.querySelector('input[name="item_quantity[]"]').value = '';
        refreshItemHint(row);
      }
    });

    row.querySelector('select[name="item_product_id[]"]').addEventListener('change', () => refreshItemHint(row));
  }

  function addItemRow() {
    const fragment = itemTemplate.content.cloneNode(true);
    const row = fragment.querySelector('.delivery-item-row');
    bindItemRow(row);
    itemsContainer.appendChild(fragment);
  }

  addItemButton.addEventListener('click', addItemRow);
  addItemRow();

  const form = document.getElementById('deliveryCreateForm');
  const geocodeBtn = document.getElementById('btnGeocodeBoth');
  const createBtn = document.getElementById('createDeliveryBtn');

  const pickupAddressPreview = document.getElementById('pickup_address_preview');
  const dropoffAddressPreview = document.getElementById('dropoff_address_preview');

  const pickupAddressHidden = document.getElementById('pickup_address');
  const dropoffAddressHidden = document.getElementById('dropoff_address');

  const pickupLatInput = document.getElementById('pickup_lat');
  const pickupLngInput = document.getElementById('pickup_lng');
  const dropoffLatInput = document.getElementById('dropoff_lat');
  const dropoffLngInput = document.getElementById('dropoff_lng');

  const pickupCoordText = document.getElementById('pickupCoordText');
  const dropoffCoordText = document.getElementById('dropoffCoordText');
  const routeSummaryText = document.getElementById('routeSummaryText');

  if (typeof L === 'undefined') {
    console.error('Leaflet not loaded.');
    return;
  }

  const map = L.map('addressMap').setView([14.5995, 120.9842], 6);
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '&copy; OpenStreetMap contributors'
  }).addTo(map);

  let pickupMarker = null;
  let dropoffMarker = null;
  let routeLine = null;

  function addressParts(prefix) {
    const block = document.querySelector(`.address-block[data-prefix="${prefix}"]`);
    return {
      street: block.querySelector('[data-field="street"]').value.trim(),
      city: block.querySelector('[data-field="city"]').value.trim(),
      postal: block.querySelector('[data-field="postal"]').value.trim(),
      country: block.querySelector('[data-field="country"]').value.trim(),
    };
  }

  function buildAddress(prefix) {
    const parts = addressParts(prefix);
    const full = [parts.street, parts.city, parts.postal, parts.country]
      .map(v => String(v || '').trim())
      .filter(Boolean)
      .join(', ');

    if (prefix === 'pickup') {
      pickupAddressPreview.value = full;
      pickupAddressHidden.value = full;
    } else {
      dropoffAddressPreview.value = full;
      dropoffAddressHidden.value = full;
    }

    return full;
  }

  function setCoordText(prefix, lat, lng) {
    const has = lat !== null && lat !== '' && lng !== null && lng !== '';
    const text = has ? `${Number(lat).toFixed(7)}, ${Number(lng).toFixed(7)}` : 'Not pinned yet.';
    if (prefix === 'pickup') {
      pickupCoordText.textContent = text;
    } else {
      dropoffCoordText.textContent = text;
    }
  }

  function updateHiddenCoords(prefix, lat, lng) {
    if (prefix === 'pickup') {
      pickupLatInput.value = lat;
      pickupLngInput.value = lng;
    } else {
      dropoffLatInput.value = lat;
      dropoffLngInput.value = lng;
    }
    setCoordText(prefix, lat, lng);
  }

  function markerLabel(prefix) {
    return prefix === 'pickup' ? 'Pickup' : 'Dropoff';
  }

  function clearRoute() {
    if (routeLine) {
      map.removeLayer(routeLine);
      routeLine = null;
    }
    routeSummaryText.textContent = 'No route yet.';
  }

  function formatDistance(meters) {
    const km = meters / 1000;
    if (km < 1) {
      return `${Math.round(meters)} m`;
    }
    return `${km.toFixed(2)} km`;
  }

  function formatDuration(seconds) {
    const mins = Math.round(seconds / 60);
    if (mins < 60) {
      return `${mins} min`;
    }
    const hrs = Math.floor(mins / 60);
    const rem = mins % 60;
    return rem > 0 ? `${hrs} hr ${rem} min` : `${hrs} hr`;
  }

  async function drawRoute() {
    if (!pickupLatInput.value || !pickupLngInput.value || !dropoffLatInput.value || !dropoffLngInput.value) {
      clearRoute();
      return;
    }

    const startLng = Number(pickupLngInput.value);
    const startLat = Number(pickupLatInput.value);
    const endLng = Number(dropoffLngInput.value);
    const endLat = Number(dropoffLatInput.value);

    const url = `https://router.project-osrm.org/route/v1/driving/${startLng},${startLat};${endLng},${endLat}?overview=full&geometries=geojson`;

    try {
      const response = await fetch(url, {
        headers: { 'Accept': 'application/json' }
      });

      if (!response.ok) {
        throw new Error('Unable to fetch route.');
      }

      const data = await response.json();
      if (!data.routes || !data.routes.length) {
        throw new Error('No route found.');
      }

      const route = data.routes[0];
      const coords = route.geometry.coordinates.map(pair => [pair[1], pair[0]]);

      if (routeLine) {
        map.removeLayer(routeLine);
      }

      routeLine = L.polyline(coords, {
        weight: 5,
        opacity: 0.85
      }).addTo(map);

      const group = [];
      if (pickupMarker) group.push(pickupMarker.getLatLng());
      if (dropoffMarker) group.push(dropoffMarker.getLatLng());
      coords.forEach(c => group.push(L.latLng(c[0], c[1])));
      map.fitBounds(L.latLngBounds(group), { padding: [35, 35] });

      routeSummaryText.textContent = `${formatDistance(route.distance)} กค approx ${formatDuration(route.duration)}`;
    } catch (error) {
      clearRoute();
      routeSummaryText.textContent = 'Route unavailable.';
    }
  }

  function ensureMarker(prefix, lat, lng) {
    const latlng = [Number(lat), Number(lng)];
    let marker = prefix === 'pickup' ? pickupMarker : dropoffMarker;

    if (!marker) {
      marker = L.marker(latlng, { draggable: true }).addTo(map).bindPopup(markerLabel(prefix));
      marker.on('dragend', async function () {
        const pos = marker.getLatLng();
        updateHiddenCoords(prefix, pos.lat.toFixed(7), pos.lng.toFixed(7));
        await drawRoute();
      });

      if (prefix === 'pickup') {
        pickupMarker = marker;
      } else {
        dropoffMarker = marker;
      }
    } else {
      marker.setLatLng(latlng);
    }

    fitMarkers();
  }

  function fitMarkers() {
    const bounds = [];
    if (pickupMarker) bounds.push(pickupMarker.getLatLng());
    if (dropoffMarker) bounds.push(dropoffMarker.getLatLng());

    if (bounds.length === 1) {
      map.setView(bounds[0], 15);
    } else if (bounds.length >= 2) {
      map.fitBounds(L.latLngBounds(bounds), { padding: [40, 40] });
    }
  }

  async function geocodeAddress(address) {
    const url = 'https://nominatim.openstreetmap.org/search?format=jsonv2&limit=1&q=' + encodeURIComponent(address);
    const response = await fetch(url, {
      headers: {
        'Accept': 'application/json'
      }
    });

    if (!response.ok) {
      throw new Error('Geocoding failed.');
    }

    const data = await response.json();
    if (!Array.isArray(data) || !data.length) {
      throw new Error('Address not found on map.');
    }

    return {
      lat: Number(data[0].lat),
      lng: Number(data[0].lon)
    };
  }

  async function geocodeOne(prefix) {
    const address = buildAddress(prefix);
    if (!address) {
      throw new Error((prefix === 'pickup' ? 'Pickup' : 'Dropoff') + ' address is incomplete.');
    }

    const result = await geocodeAddress(address);
    updateHiddenCoords(prefix, result.lat.toFixed(7), result.lng.toFixed(7));
    ensureMarker(prefix, result.lat, result.lng);
  }

  async function geocodeBoth() {
    geocodeBtn.disabled = true;
    createBtn.disabled = true;

    try {
      await geocodeOne('pickup');
      await geocodeOne('dropoff');
      await drawRoute();
    } finally {
      geocodeBtn.disabled = false;
      createBtn.disabled = false;
    }
  }

  document.querySelectorAll('.address-part').forEach((input) => {
    input.addEventListener('input', function () {
      const block = input.closest('.address-block');
      const prefix = block.dataset.prefix;
      buildAddress(prefix);

      if (prefix === 'pickup') {
        updateHiddenCoords('pickup', '', '');
        if (pickupMarker) {
          map.removeLayer(pickupMarker);
          pickupMarker = null;
        }
      } else {
        updateHiddenCoords('dropoff', '', '');
        if (dropoffMarker) {
          map.removeLayer(dropoffMarker);
          dropoffMarker = null;
        }
      }

      clearRoute();
    });

    input.addEventListener('blur', async function () {
      const block = input.closest('.address-block');
      const prefix = block.dataset.prefix;
      const parts = addressParts(prefix);
      buildAddress(prefix);

      if (!parts.street || !parts.city || !parts.country) {
        return;
      }

      try {
        await geocodeOne(prefix);
        await drawRoute();
      } catch (error) {
      }
    });
  });

  geocodeBtn.addEventListener('click', async function () {
    try {
      await geocodeBoth();
    } catch (error) {
      alert(error.message || 'Unable to pin addresses on the map.');
    }
  });

  form.addEventListener('submit', async function (event) {
    buildAddress('pickup');
    buildAddress('dropoff');

    if (!pickupAddressHidden.value || !dropoffAddressHidden.value) {
      event.preventDefault();
      alert('Please complete both pickup and dropoff addresses.');
      return;
    }

    if (!pickupLatInput.value || !pickupLngInput.value || !dropoffLatInput.value || !dropoffLngInput.value) {
      event.preventDefault();
      try {
        await geocodeBoth();
      } catch (error) {
        alert(error.message || 'Please pin both addresses on the map before saving.');
        return;
      }
      form.submit();
    }
  });
})();
</script>