<?php
declare(strict_types=1);
require __DIR__ . '/../_bootstrap.php';

$dev = requireDeviceAuth();
$body = readJsonBody();

$fw   = (string)($body['fw_version'] ?? '');
$slot = (string)($body['ota_slot'] ?? '');
$rssi = isset($body['rssi']) ? (int)$body['rssi'] : null;
$unsynced = isset($body['unsynced']) ? (int)$body['unsynced'] : null;

$tenantId = (int)($dev['tenant_id'] ?? 0);
if ($tenantId <= 0) $tenantId = 1;

$ip = $_SERVER['REMOTE_ADDR'] ?? null;

$u = db()->prepare("
  UPDATE devices
  SET fw_version = COALESCE(NULLIF(?, ''), fw_version),
      ota_slot   = COALESCE(NULLIF(?, ''), ota_slot),
      last_seen_at = NOW(),
      last_ip = ?,
      last_rssi = ?
  WHERE device_uid = ?
");
$u->execute([$fw, $slot, $ip, $rssi, $dev['device_uid']]);

// Process ACKs
$acks = $body['acks'] ?? [];
if (is_array($acks) && count($acks)) {
  $upd = db()->prepare("UPDATE device_commands SET status=?, ack_at=NOW(), ack_json=? WHERE id=? AND device_uid=?");
  foreach ($acks as $a) {
    if (!is_array($a)) continue;
    $cmdId = (int)($a['cmd_id'] ?? 0);
    if ($cmdId <= 0) continue;
    $st = ((string)($a['status'] ?? 'ok')) === 'error' ? 'ack_err' : 'ack_ok';
    $upd->execute([$st, json_encode($a, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES), $cmdId, $dev['device_uid']]);
  }
}

// Fetch queued commands
$q = db()->prepare("
  SELECT id, cmd_type, payload_json
  FROM device_commands
  WHERE device_uid=? AND status='queued'
    AND (not_before_at IS NULL OR not_before_at <= NOW())
    AND (expires_at IS NULL OR expires_at > NOW())
  ORDER BY priority ASC, id ASC
  LIMIT 10
");
$q->execute([$dev['device_uid']]);
$rows = $q->fetchAll();

// Mark as sent
if ($rows) {
  $ids = array_map(fn($r)=>(int)$r['id'], $rows);
  $in  = implode(',', array_fill(0, count($ids), '?'));
  $m = db()->prepare("UPDATE device_commands SET status='sent', sent_at=NOW() WHERE device_uid=? AND id IN ($in)");
  $m->execute(array_merge([$dev['device_uid']], $ids));
}

$cmds = [];
foreach ($rows as $r) {
  $cmds[] = [
    'cmd_id' => (int)$r['id'],
    'cmd'    => (string)$r['cmd_type'],
    'payload'=> json_decode((string)$r['payload_json'], true) ?: new stdClass(),
  ];
}

// NEW: cmd_idx
$cmdIdxSt = db()->prepare("SELECT COALESCE(MAX(id),0) FROM device_commands WHERE device_uid=?");
$cmdIdxSt->execute([$dev['device_uid']]);
$cmd_idx = (int)$cmdIdxSt->fetchColumn();

// NEW: desired config pending rev + hash
$desired_cfg_rev = 0;
$desired_cfg_hash = '';
try {
  $d = db()->prepare("
    SELECT desired_rev, payload_hash
    FROM device_config_desired
    WHERE tenant_id=? AND device_uid=? AND status='pending'
    LIMIT 1
  ");
  $d->execute([$tenantId, $dev['device_uid']]);
  $row = $d->fetch();
  if ($row) {
    $desired_cfg_rev = (int)$row['desired_rev'];
    $desired_cfg_hash = bin2hex((string)$row['payload_hash']);
  }
} catch (Throwable $e) {
  // table may not exist yet
}

jexit(200, [
  'ok' => true,
  'server_time' => gmdate('c'),
  'poll_after_sec' => ($unsynced && $unsynced > 0) ? 20 : 60,

  // NEW
  'cmd_idx' => $cmd_idx,
  'desired_cfg_rev' => $desired_cfg_rev,
  'desired_cfg_hash' => $desired_cfg_hash,

  // Existing
  'commands' => $cmds,
]);