<?php
declare(strict_types=1);
require_once __DIR__ . '/_inc/boot.php';
require_once __DIR__ . '/_inc/db.php';

$cfg = app_cfg();
$pdo = db();
auth_require_permission('use_crons');

$stBf = $pdo->prepare("SELECT v FROM settings_kv WHERE k='backfill_countries'");
$stBf->execute();
$backfillCountriesRaw = (string)($stBf->fetchColumn() ?: '');
$backfillCountries = [];
if ($backfillCountriesRaw !== '') {
  $parts = preg_split('/[\s,]+/', strtoupper($backfillCountriesRaw));
  foreach ($parts as $p0) { $p0 = trim((string)$p0); if ($p0!=='') $backfillCountries[] = $p0; }
  $backfillCountries = array_values(array_unique($backfillCountries));
}


$title = 'Crons';
$active = 'crons';

$cronKey = (string)($cfg['security']['cron_key'] ?? '');

$countries = $pdo->query("SELECT code,name FROM countries WHERE enabled=1 ORDER BY code")->fetchAll();

// Countries for Backfill dropdown: use backfill_countries setting if present; otherwise enabled countries
if (count($backfillCountries) > 0) {
  $in = implode(',', array_fill(0, count($backfillCountries), '?'));
  $stC = $pdo->prepare("SELECT code,name FROM countries WHERE code IN ($in) ORDER BY code");
  $stC->execute($backfillCountries);
  $countriesBackfill = $stC->fetchAll();
} else {
  $countriesBackfill = $countries;
}


$jobs = [
  ['id'=>'sync_leads','name'=>'Sync leads list','desc'=>'Fetch /api/leads?country=... pages and upsert basic lead rows.'],
  ['id'=>'sync_details','name'=>'Sync lead details','desc'=>'Fetch /api/leads/details and store items + tracking + courier.'],
  ['id'=>'watch_tracking','name'=>'Watch missing tracking','desc'=>'Refetch details for leads created in the last 48h where tracking is still missing.'],
  ['id'=>'refresh_statuses','name'=>'Refresh statuses','desc'=>'Fetch /api/leads/history, store history, compute derived timestamps, freeze final statuses.'],
  ['id'=>'sync_stock','name'=>'Sync stock','desc'=>'Refresh active card stock by provider: EFC /api/products/get-stock/{sku}, Pick&Pack /product/quantity, QCargo manual stock.'],
];

$lastRuns = [];
$st = $pdo->query("SELECT job, status, started_at, finished_at, duration_ms, metrics_json, message
  FROM cron_runs
  ORDER BY started_at DESC
  LIMIT 200");
while($r=$st->fetch()){
  if (!isset($lastRuns[$r['job']])) $lastRuns[$r['job']] = $r;
}

function lock_info(string $job): array {
  $file = __DIR__ . '/cron/locks/' . $job . '.lock';
  if (!file_exists($file)) return ['locked'=>false,'age'=>null,'ttl'=>1200,'stale'=>false];
  $age = time() - filemtime($file);
    $ttl = 1200;
  $stale = $age >= $ttl;
  return ['locked'=>true,'age'=>$age,'ttl'=>$ttl,'stale'=>$stale];
}

require_once __DIR__ . '/_inc/layout_top.php';
?>

<section class="card">
  <div class="card-h">
    <div class="card-title">Crons</div>
    <div class="row" style="justify-content:flex-end">
      <a class="btn btn-sm btn-ghost" href="/open_leads.php">Open leads</a>
      <a class="btn btn-sm btn-ghost" href="/bad_tracking.php">Bad tracking</a>
      <a class="btn btn-sm btn-ghost" href="/pickpack_import.php">Pick&Pack import</a>
      <div class="muted">Run from UI or via server cron (recommended)</div>
    </div>
  <div class="muted small" style="margin-top:6px">Auto refresh: <span id="arSec">15</span>s · Shows live lock files + last run</div>

  </div>

  <div class="table-wrap">
    <table class="table">
      <thead>
        <tr>
          <th>Job</th><th>Description</th><th>Health</th><th>Last run</th><th>Metrics</th><th></th>
        </tr>
      </thead>
      <tbody>
        <?php foreach($jobs as $j):
          $id = $j['id'];
          $lr = $lastRuns[$id] ?? null;
          $lock = lock_info($id);
          $metrics = $lr && $lr['metrics_json'] ? json_decode((string)$lr['metrics_json'], true) : null;
        ?>
          <tr>
            <td><strong><?= h($id) ?></strong><div class="muted small"><?= h($j['name']) ?></div></td>
            <td class="muted"><?= h($j['desc']) ?></td>
            <td>
              <?php if($lock['locked']): ?>
                <span class="badge <?= $lock['stale'] ? 'badge-bad' : 'badge-warn' ?>"><?= $lock['stale'] ? 'STALE LOCK' : 'LOCKED' ?></span>
                <div class="muted small"><?= (int)$lock['age'] ?>s / ttl <?= (int)$lock['ttl'] ?>s</div>
              <?php else: ?>
                <span class="badge badge-ok">UNLOCKED</span>
              <?php endif; ?>
            </td>
            <td>
              <?php if($lr): ?>
                <div><span class="badge <?= $lr['status']==='OK'?'badge-ok':'badge-bad' ?>"><?= h($lr['status']) ?></span></div>
                <div class="muted small"><?= h(dd($lr['started_at'])) ?><?php if($lr['duration_ms']): $ms=(int)$lr['duration_ms']; $s=round($ms/1000,2); ?> · <?= $s ?>s (<?= $ms ?>ms)<?php endif; ?></div>
                <?php if($lr['message']): ?><div class="muted small"><?= h($lr['message']) ?></div><?php endif; ?>
              <?php else: ?>
                <span class="muted">—</span>
              <?php endif; ?>
            </td>
            <td class="muted small">
              <?php if(is_array($metrics)): ?>
                <?= h(json_encode($metrics, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES)) ?>
              <?php else: ?>—
              <?php endif; ?>
            </td>
            <td class="right">
              <?php
                $extra = '';
                if ($id === 'sync_leads') $extra = '&max_seconds=20&max_pages=5&max_leads=800&per_country_limit=200';
                if ($id === 'sync_details') $extra = '&max_seconds=20&limit=12';
                if ($id === 'watch_tracking') $extra = '&max_seconds=55&limit=100&retry_minutes=10&max_age_hours=48&all_missing=1';
                if ($id === 'refresh_statuses') $extra = '&max_seconds=20&limit=20';
                if ($id === 'sync_stock') $extra = '&max_seconds=20&limit=500';
              ?>
              <a class="btn btn-sm" href="/cron/run.php?job=<?= urlencode($id) ?>&key=<?= urlencode($cronKey) ?><?= $extra ?>" target="_blank" rel="noopener">Run</a>
            </td>
          </tr>
        <?php endforeach; ?>
      </tbody>
    </table>
  </div>

  <div class="sep"></div>
  <div class="muted small">
    For real server cron: call these URLs with the key, or run via CLI (recommended).
  </div>
  <pre class="code" style="margin-top:10px">wget -qO- "<?= h(($cfg['app']['base_url'] ?? 'https://status.clixsee.eu')) ?>/cron/run.php?job=sync_leads&key=<?= h(urlencode($cronKey)) ?>&max_seconds=20&max_pages=5&max_leads=800&per_country_limit=200" >/dev/null
wget -qO- "<?= h(($cfg['app']['base_url'] ?? 'https://status.clixsee.eu')) ?>/cron/run.php?job=refresh_statuses&key=<?= h(urlencode($cronKey)) ?>&max_seconds=20&limit=20" >/dev/null
wget -qO- "<?= h(($cfg['app']['base_url'] ?? 'https://status.clixsee.eu')) ?>/cron/run.php?job=watch_tracking&key=<?= h(urlencode($cronKey)) ?>&max_seconds=55&limit=100&retry_minutes=10&max_age_hours=48&all_missing=1" >/dev/null
wget -qO- "<?= h(($cfg['app']['base_url'] ?? 'https://status.clixsee.eu')) ?>/cron/run.php?job=sync_details&key=<?= h(urlencode($cronKey)) ?>&max_seconds=20&limit=12" >/dev/null
wget -qO- "<?= h(($cfg['app']['base_url'] ?? 'https://status.clixsee.eu')) ?>/cron/run.php?job=sync_stock&key=<?= h(urlencode($cronKey)) ?>&max_seconds=20&limit=500" >/dev/null</pre>

</section>

<section class="card" style="margin-top:16px">
  <div class="card-h">
    <div class="card-title">Recent cron runs</div>
    <div class="muted">Last 50 runs</div>
  </div>

  <?php
    $runs = $pdo->query("SELECT job,status,started_at,finished_at,duration_ms,message,metrics_json FROM cron_runs ORDER BY started_at DESC LIMIT 50")->fetchAll();
  ?>
  <div class="table-wrap">
    <table class="table">
      <thead><tr><th>When</th><th>Job</th><th>Status</th><th>Duration</th><th>Metrics</th><th>Message</th></tr></thead>
      <tbody>
        <?php foreach($runs as $r): ?>
          <tr>
            <td><?= h(dd($r['started_at'])) ?></td>
            <td><strong><?= h($r['job']) ?></strong></td>
            <td><span class="badge <?= $r['status']==='OK'?'badge-ok':'badge-bad' ?>"><?= h($r['status']) ?></span></td>
            <td class="muted"><?= $r['duration_ms'] ? ((int)$r['duration_ms']).'ms' : '—' ?></td>
            <td class="muted small"><?= h((string)$r['metrics_json']) ?></td>
            <td class="muted small"><?= h($r['message']) ?></td>
          </tr>
        <?php endforeach; ?>
      </tbody>
    </table>
  </div>
</section>

<script>
(function(){
  var sec = 15;
  var el = document.getElementById('arSec');
  function tick(){
    sec--;
    if (el) el.textContent = String(sec);
    if (sec<=0) { location.reload(); return; }
    setTimeout(tick, 1000);
  }
  setTimeout(tick, 1000);
})();
</script>

  <section class="card wide" style="margin-top:14px">
    <div class="hd">
      <div class="title">Backfill (FULL lead data)</div>
      <div class="badge">Country-by-country · pulls details + history for N leads</div>
    </div>
    <div class="bd">
      <div class="row" style="gap:10px; flex-wrap:wrap; align-items:end">
        <div>
          <div class="muted" style="font-size:12px; margin-bottom:6px">Country</div>
          <select id="bfCountry" class="input">
<?php foreach ($countriesBackfill as $c): ?>
            <option value="<?= h($c['code']) ?>"><?= h($c['code']) ?> · <?= h($c['name']) ?></option>
<?php endforeach; ?>
          </select>
        </div>
        <div>
          <div class="muted" style="font-size:12px; margin-bottom:6px">Leads per run</div>
          <input id="bfLimit" class="input" type="number" min="1" max="200" value="10" style="width:120px">
        </div>
        <div>
          <div class="muted" style="font-size:12px; margin-bottom:6px">Max seconds</div>
          <input id="bfSeconds" class="input" type="number" min="3" max="300" value="20" style="width:120px">
        </div>
        <div>
          <div class="muted" style="font-size:12px; margin-bottom:6px">Lock TTL (s)</div>
          <input id="bfTtl" class="input" type="number" min="30" max="21600" value="1200" style="width:120px">
        </div>
        <div>
          <button class="btn" id="bfRunBtn">Run backfill_full</button>
        </div>
        <div class="muted" style="font-size:12px">
          Tip: run it every minute until FULL DETAILS reaches 100%.
        </div>
      </div>

      <div class="muted" style="margin-top:10px; font-size:12px">
        Endpoint:
        <span class="mono">/cron/run.php?job=backfill_full&key=…&country=SPAIN&limit=10&max_seconds=20&lock_ttl=1200</span>
      </div>
    </div>
  </section>

  <script>
  (function(){
    function getCronKey(){ return localStorage.getItem('cronKey') || ''; }
    var btn = document.getElementById('bfRunBtn');
    if(!btn) return;
    btn.addEventListener('click', function(){
      var key = getCronKey();
      if(!key){ alert('Set Cron key first (top of page)'); return; }
      var c = document.getElementById('bfCountry').value;
      var lim = document.getElementById('bfLimit').value || '10';
      var sec = document.getElementById('bfSeconds').value || '20';
      var ttl = document.getElementById('bfTtl').value || '1200';
      var url = '/cron/run.php?job=backfill_full'
        + '&key=' + encodeURIComponent(key)
        + '&country=' + encodeURIComponent(c)
        + '&limit=' + encodeURIComponent(lim)
        + '&max_seconds=' + encodeURIComponent(sec)
        + '&lock_ttl=' + encodeURIComponent(ttl);
      window.open(url, '_blank');
    });
  })();
  </script>

<?php require_once __DIR__ . '/_inc/layout_bottom.php'; ?>
