<?php
declare(strict_types=1);

ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);

header('Content-Type: application/json; charset=utf-8');

require_once __DIR__ . '/../lib/db.php'; // db() + app_config()
require_once __DIR__ . '/../lib/consent.php';
require_once __DIR__ . '/../lib/iys.php';

function out(string $status, string $result, string $data): void {
  echo json_encode(['status' => $status, 'result' => $result, 'data' => $data], JSON_UNESCAPED_UNICODE);
  exit;
}

function client_ip(): string {
  foreach (['HTTP_CF_CONNECTING_IP','HTTP_X_FORWARDED_FOR','HTTP_CLIENT_IP','REMOTE_ADDR'] as $k) {
    if (!empty($_SERVER[$k])) {
      $ip = (string)$_SERVER[$k];
      if (str_contains($ip, ',')) $ip = trim(explode(',', $ip)[0]);
      return $ip;
    }
  }
  return '0.0.0.0';
}

if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
  out('error', 'e', 'POST bekleniyor');
}

$cfg = app_config();

/** Token kontrolü: config boşsa bloke etme */
$token = (string)($_GET['token'] ?? '');
$expectedToken = (string)($cfg['netgsm_webhook_token'] ?? '');
$tokenOk = true;
if ($expectedToken !== '') {
  $tokenOk = hash_equals($expectedToken, $token);
}

$ip = client_ip();

$rawBody = (string)file_get_contents('php://input');
$contentType = (string)($_SERVER['CONTENT_TYPE'] ?? '');
$httpMethod  = (string)($_SERVER['REQUEST_METHOD'] ?? 'POST');

/** Payload al (JSON object veya [object]) */
$payload = $_POST;
if ((empty($payload) || !is_array($payload)) && str_contains(strtolower($contentType), 'application/json')) {
  $j = json_decode($rawBody, true);
  if (is_array($j)) {
    $isList = array_keys($j) === range(0, count($j) - 1);
    $payload = $isList ? ($j[0] ?? []) : $j;
  }
}

/** Debug format: {"ts":...,"raw":"{...}"} gelirse raw içini parse et */
if (isset($payload['raw']) && is_string($payload['raw'])) {
  $inner = json_decode($payload['raw'], true);
  if (is_array($inner)) {
    $payload = $inner;
  }
}

$arayan_no   = trim((string)($payload['arayan_no']   ?? ''));
$aranan_no   = trim((string)($payload['aranan_no']   ?? ''));
$santral_no  = trim((string)($payload['santral_no']  ?? ''));
$arama_id    = trim((string)($payload['arama_id']    ?? ''));
$tus_bilgisi = trim((string)($payload['tus_bilgisi'] ?? ''));

try {
  $pdo = db();

  // --- (İsteğe bağlı) dosya log: /webhook/_debug/hits.ndjson ---
  $dir = __DIR__ . '/_debug';
  if (!is_dir($dir)) { @mkdir($dir, 0755, true); }
  @file_put_contents(
    $dir . '/hits.ndjson',
    json_encode([
      'ts' => date('c'),
      'method' => $httpMethod,
      'ip' => $ip,
      'ct' => $contentType,
      'get' => $_GET,
      'payload' => $payload,
      'ua' => ($_SERVER['HTTP_USER_AGENT'] ?? ''),
    ], JSON_UNESCAPED_UNICODE) . PHP_EOL,
    FILE_APPEND
  );

  // 1) webhook_logs her zaman yaz (tablon yoksa bu kısmı kaldır)
  try {
    $stLog = $pdo->prepare("
      INSERT INTO webhook_logs (arama_id, ip, token_ok, http_method, content_type, raw_body)
      VALUES (?, ?, ?, ?, ?, ?)
    ");
    $stLog->execute([
      $arama_id !== '' ? $arama_id : null,
      $ip,
      $tokenOk ? 1 : 0,
      $httpMethod,
      $contentType,
      $rawBody,
    ]);
  } catch (Throwable $ignored) {
    // webhook_logs tablosu yoksa sessiz geç
  }

  if (!$tokenOk) out('error', 'e', 'Token hatalı');
  if ($arama_id === '') out('error', 'e', 'arama_id boş gelemez');

  // ✅ Sadece 1 tuşlayanları işle
  if (!consent_is_approved_digit($tus_bilgisi) || $arayan_no === '') {
    out('success', '1', 'ok'); // akışı bozma
  }

  // 2) calls tablosuna upsert (varsa güncelle) — yer kaplamaz
  // (calls tablon yoksa bu kısmı kaldırabilirsin)
  try {
    $callStatus = 'routed';
    $st2 = $pdo->prepare("
      INSERT INTO calls (arama_id, arayan_no, aranan_no, santral_no, status, last_tus)
      VALUES (?, ?, ?, ?, ?, ?)
      ON DUPLICATE KEY UPDATE
        arayan_no  = VALUES(arayan_no),
        aranan_no  = VALUES(aranan_no),
        santral_no = VALUES(santral_no),
        status     = 'routed',
        last_tus   = COALESCE(NULLIF(VALUES(last_tus),''), last_tus),
        updated_at = CURRENT_TIMESTAMP
    ");
    $st2->execute([
      $arama_id,
      $arayan_no,
      $aranan_no !== '' ? $aranan_no : null,
      $santral_no !== '' ? $santral_no : null,
      $callStatus,
      consent_digit_approved(),
    ]);
  } catch (Throwable $ignored) {
    // calls tablosu yoksa sessiz geç
  }

  // 3) unique_approvals: aynı numara ikinci kez EKLENMEZ (UNIQUE)
  // - ilk kez gelirse insert
  // - varsa sadece last_seen_at + seen_count artar
  $stU = $pdo->prepare("
    INSERT INTO unique_approvals (arayan_no, first_arama_id, first_tus, first_seen_at, last_seen_at, seen_count)
    VALUES (?, ?, ?, NOW(), NOW(), 1)
    ON DUPLICATE KEY UPDATE
      last_seen_at = NOW(),
      seen_count = seen_count + 1
  ");
  $stU->execute([
    $arayan_no,
    $arama_id !== '' ? $arama_id : null,
    consent_digit_approved(),
  ]);

  // 4) Onaylı numarayı IYS'ye kaydet (hata olursa çağrı akışını bozma)
  try {
    iys_sync_phone($pdo, $arayan_no, 'onayli', [
      'source' => 'webhook_ping',
      'event_ref' => $arama_id,
      'force' => false,
    ]);
  } catch (Throwable $ignored) {
    // IYS hatası webhook cevabını etkilemesin
  }

  out('success', '1', 'ok');

} catch (Throwable $e) {
  out('error', 'e', 'DB hata: ' . $e->getMessage());
}
