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

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

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

$deviceUid = (string)($dev['device_uid'] ?? '');
if ($deviceUid === '') jexit(401, ['ok'=>false, 'error'=>'missing_device_uid']);

$items = null;
if (isset($body['configs']) && is_array($body['configs'])) {
  $items = $body['configs'];
} else {
  $items = [$body];
}

$pdo = db();

$insHist = $pdo->prepare("
  INSERT INTO device_config_history
    (tenant_id, device_uid, cfg_rev, saved_at_utc, payload_hash, payload_json, meta_json)
  VALUES
    (?, ?, ?, ?, ?, ?, ?)
  ON DUPLICATE KEY UPDATE id=id
");

$upState = $pdo->prepare("
  INSERT INTO device_config_state
    (tenant_id, device_uid, cfg_rev, saved_at_utc, payload_hash, payload_json, meta_json)
  VALUES
    (?, ?, ?, ?, ?, ?, ?)
  ON DUPLICATE KEY UPDATE
    cfg_rev = IF(VALUES(cfg_rev) > cfg_rev, VALUES(cfg_rev), cfg_rev),
    saved_at_utc = IF(VALUES(cfg_rev) > cfg_rev, VALUES(saved_at_utc), saved_at_utc),
    payload_hash = IF(VALUES(cfg_rev) > cfg_rev, VALUES(payload_hash), payload_hash),
    payload_json = IF(VALUES(cfg_rev) > cfg_rev, VALUES(payload_json), payload_json),
    meta_json = IF(VALUES(cfg_rev) > cfg_rev, VALUES(meta_json), meta_json)
");

$markApplied = $pdo->prepare("
  UPDATE device_config_desired
  SET status='applied', last_error=NULL
  WHERE tenant_id=? AND device_uid=? AND desired_rev=? LIMIT 1
");

$accepted = 0;
$skipped  = 0;

try {
  $pdo->beginTransaction();

  foreach ($items as $it) {
    if (!is_array($it)) { $skipped++; continue; }

    $cfgRev = (int)($it['cfg_rev'] ?? 0);
    if ($cfgRev <= 0) { $skipped++; continue; }

    $savedAt = normalizeUtcDatetime($it['saved_at_utc'] ?? '');
    if ($savedAt === '') $savedAt = gmdate('Y-m-d H:i:s');

    $config = $it['config'] ?? null;
    if (!is_array($config)) { $skipped++; continue; }

    $meta = $it['meta'] ?? null;
    if (!is_array($meta)) $meta = [];

    $payloadJson = json_encode($config, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
    if ($payloadJson === false) { $skipped++; continue; }

    $metaJson = json_encode($meta, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
    if ($metaJson === false) $metaJson = null;

    $hashBin = hash('sha256', $payloadJson, true);

    $insHist->execute([$tenantId, $deviceUid, $cfgRev, $savedAt, $hashBin, $payloadJson, $metaJson]);
    $upState->execute([$tenantId, $deviceUid, $cfgRev, $savedAt, $hashBin, $payloadJson, $metaJson]);

    $appliedRev = (int)($meta['applied_desired_rev'] ?? 0);
    if ($appliedRev > 0) {
      try { $markApplied->execute([$tenantId, $deviceUid, $appliedRev]); } catch (Throwable $e) {}
    }

    $accepted++;
  }

  $pdo->commit();
} catch (Throwable $e) {
  if ($pdo->inTransaction()) $pdo->rollBack();
  jexit(500, ['ok'=>false, 'error'=>'db_error', 'detail'=>$e->getMessage()]);
}

jexit(200, ['ok'=>true, 'accepted'=>$accepted, 'skipped'=>$skipped]);

function normalizeUtcDatetime($v): string {
  if ($v === null) return '';
  if (is_int($v) || (is_string($v) && ctype_digit($v))) {
    $n = (int)$v;
    if ($n > 1000000000000) $n = (int)floor($n / 1000);
    if ($n <= 0) return '';
    return gmdate('Y-m-d H:i:s', $n);
  }
  $s = trim((string)$v);
  if ($s === '') return '';
  try { $dt = new DateTimeImmutable($s); }
  catch (Throwable $e) { return ''; }
  return $dt->setTimezone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s');
}