<?php
declare(strict_types=1);

/**
 * IMPORTANT (NetGSM):
 * - Bu dosyayı MUTLAKA "UTF-8 (BOM'suz)" kaydet.
 * - <?php öncesinde tek boşluk / satır olmasın.
 */

ob_start(); // output kirlenmesin (NetGSM success/error bozulmasın)

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

require_once __DIR__ . '/../lib/db.php';
require_once __DIR__ . '/../lib/helpers.php';
require_once __DIR__ . '/../lib/consent.php';

start_app_session();

/**
 * consent-test.php
 * - NetGSM Modu: POST + (?api=1 yoksa) -> SADECE "success" / "error" (plain text)
 * - JSON Modu : ?api=1 veya Content-Type: application/json -> JSON response
 * - UI Modu   : Browser GET -> test ekranı
 *
 * Kural:
 * - arayan_no için geçmişte 1 kere bile onaylı tuş varsa => ask_consent=false (bir daha sorma)
 * - aksi halde => ask_consent=true (onay gelene kadar sor)
 */

/** ✅ Token opsiyonel/konfige bağlı: config'te varsa zorunlu tutar */
$cfg = function_exists('app_config') ? app_config() : [];
$expectedToken = (string)($cfg['netgsm_webhook_token'] ?? $cfg['webhook_token'] ?? '1b40bd059d3ee0f9c5acccf50618a46b259e9460b2c844f7');

/** JSON çıkış helper */
function json_out(array $data, int $code = 200): void {
  http_response_code($code);
  header('Content-Type: application/json; charset=UTF-8');
  header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
  header('Pragma: no-cache');
  echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
  exit;
}

/** ✅ NetGSM için düz metin çıkış: SADECE success / error */
function plain_out(string $text, int $code = 200): void {
  // Buffer'da ne varsa temizle (success/error saf kalsın)
  while (ob_get_level() > 0) { ob_end_clean(); }

  http_response_code($code);
  header('Content-Type: text/plain; charset=UTF-8');
  header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
  header('Pragma: no-cache');
  echo $text; // TAM olarak success / error
  exit;
}

/** İstekten input topla (GET/POST/JSON) */
function read_input(): array {
  $in = [];

  foreach (['token','arayan_no','caller','from','msisdn','arama_id','call_id','santral_no','aranan_no'] as $k) {
    if (isset($_GET[$k]))  $in[$k] = (string)$_GET[$k];
    if (isset($_POST[$k])) $in[$k] = (string)$_POST[$k];
  }

  $ct = (string)($_SERVER['CONTENT_TYPE'] ?? $_SERVER['HTTP_CONTENT_TYPE'] ?? '');
  if (stripos($ct, 'application/json') !== false) {
    $raw = file_get_contents('php://input');
    if (is_string($raw) && $raw !== '') {
      $j = json_decode($raw, true);
      if (is_array($j)) {
        foreach ($j as $k => $v) {
          if (is_scalar($v) || $v === null) {
            $in[(string)$k] = (string)$v;
          }
        }
      }
    }
  }

  return $in;
}

/** arayan_no normalize */
function norm_phone(string $s): string {
  $s = trim($s);
  if ($s === '') return '';
  return preg_replace('/\D+/', '', $s) ?? '';
}

/**
 * DB: webhook_logs raw_body JSON içinde arayan_no + tus_bilgisi arar.
 * Önce JSON_EXTRACT ile dener, olmazsa LIKE + json_decode fallback.
 */
function has_tus(string $arayanNo, string $tus): bool {
  $arayanNo = trim($arayanNo);
  if ($arayanNo === '' || $tus === '') return false;

  // 1) JSON fonksiyonları
  try {
    $pdo = db();
    $sql = "
      SELECT 1
      FROM webhook_logs
      WHERE raw_body IS NOT NULL
        AND JSON_VALID(raw_body)
        AND JSON_UNQUOTE(JSON_EXTRACT(raw_body,'$.arayan_no')) = ?
        AND JSON_UNQUOTE(JSON_EXTRACT(raw_body,'$.tus_bilgisi')) = ?
      LIMIT 1
    ";
    $st = $pdo->prepare($sql);
    $st->execute([$arayanNo, $tus]);
    return (bool)$st->fetchColumn();
  } catch (Throwable $e) {
    // fallback
  }

  // 2) Fallback: LIKE + json_decode
  try {
    $pdo = db();

    $likeArayan = '%"arayan_no":"'.$arayanNo.'"%';
    $likeTus    = '%"tus_bilgisi":"'.$tus.'"%';

    $sql = "
      SELECT raw_body
      FROM webhook_logs
      WHERE raw_body IS NOT NULL
        AND raw_body LIKE ?
        AND raw_body LIKE ?
      ORDER BY id DESC
      LIMIT 200
    ";
    $st = $pdo->prepare($sql);
    $st->execute([$likeArayan, $likeTus]);
    $rows = $st->fetchAll() ?: [];

    foreach ($rows as $r) {
      $raw = (string)($r['raw_body'] ?? '');
      if ($raw === '') continue;
      $j = json_decode($raw, true);
      if (!is_array($j)) continue;

      $a = isset($j['arayan_no']) ? (string)$j['arayan_no'] : '';
      $t = isset($j['tus_bilgisi']) ? (string)$j['tus_bilgisi'] : '';
      if ($a === $arayanNo && $t === $tus) return true;
    }
    return false;
  } catch (Throwable $e2) {
    return false;
  }
}

/** Son tuş bilgisi (debug) */
function latest_tus(string $arayanNo): array {
  $arayanNo = trim($arayanNo);
  if ($arayanNo === '') return ['tus' => '', 'at' => ''];

  // 1) JSON fonksiyonları
  try {
    $pdo = db();
    $sql = "
      SELECT
        JSON_UNQUOTE(JSON_EXTRACT(raw_body,'$.tus_bilgisi')) AS tus,
        created_at
      FROM webhook_logs
      WHERE raw_body IS NOT NULL
        AND JSON_VALID(raw_body)
        AND JSON_UNQUOTE(JSON_EXTRACT(raw_body,'$.arayan_no')) = ?
        AND JSON_EXTRACT(raw_body,'$.tus_bilgisi') IS NOT NULL
      ORDER BY created_at DESC, id DESC
      LIMIT 1
    ";
    $st = $pdo->prepare($sql);
    $st->execute([$arayanNo]);
    $row = $st->fetch() ?: null;
    if ($row) {
      return ['tus' => (string)($row['tus'] ?? ''), 'at' => (string)($row['created_at'] ?? '')];
    }
  } catch (Throwable $e) {}

  // 2) Fallback
  try {
    $pdo = db();
    $likeArayan = '%"arayan_no":"'.$arayanNo.'"%';
    $sql = "
      SELECT raw_body, created_at
      FROM webhook_logs
      WHERE raw_body IS NOT NULL
        AND raw_body LIKE ?
        AND raw_body LIKE '%\"tus_bilgisi\"%'
      ORDER BY id DESC
      LIMIT 300
    ";
    $st = $pdo->prepare($sql);
    $st->execute([$likeArayan]);
    $rows = $st->fetchAll() ?: [];
    foreach ($rows as $r) {
      $raw = (string)($r['raw_body'] ?? '');
      $j = json_decode($raw, true);
      if (!is_array($j)) continue;
      $a = isset($j['arayan_no']) ? (string)$j['arayan_no'] : '';
      $t = isset($j['tus_bilgisi']) ? (string)$j['tus_bilgisi'] : '';
      if ($a === $arayanNo && $t !== '') {
        return ['tus' => $t, 'at' => (string)($r['created_at'] ?? '')];
      }
    }
  } catch (Throwable $e2) {}

  return ['tus' => '', 'at' => ''];
}

/* ---------------- Mod Seçimi ---------------- */

$apiFlag = (string)($_GET['api'] ?? '');
$ct = (string)($_SERVER['CONTENT_TYPE'] ?? $_SERVER['HTTP_CONTENT_TYPE'] ?? '');

// JSON sadece bunlarda:
$wantsJson =
  ($apiFlag === '1')
  || (stripos($ct, 'application/json') !== false)
  || ((string)($_SERVER['HTTP_X_REQUESTED_WITH'] ?? '') === 'XMLHttpRequest');

// Input
$in = read_input();
$token = trim((string)($in['token'] ?? '1b40bd059d3ee0f9c5acccf50618a46b259e9460b2c844f7'));
$arayanNo = norm_phone((string)($in['arayan_no'] ?? $in['caller'] ?? $in['from'] ?? $in['msisdn'] ?? ''));

/* ---------------- ✅ NetGSM Modu: POST + api=1 değilse -> daima plain success/error ---------------- */
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $apiFlag !== '1') {
  // NetGSM için output'u kirletecek her şeyi kapat
  ini_set('display_errors', '0');
  ini_set('display_startup_errors', '0');
  error_reporting(0);

  // token kontrol (config'te token tanımlıysa zorunlu)
  if ($expectedToken !== '1b40bd059d3ee0f9c5acccf50618a46b259e9460b2c844f7') {
    if ($token === '1b40bd059d3ee0f9c5acccf50618a46b259e9460b2c844f7' || !hash_equals($expectedToken, $token)) {
      plain_out('error', 200);
    }
  }

  if ($arayanNo === '') {
    plain_out('error', 200);
  }

  // NetGSM paneli sadece success/error ister.
  // İstersen DB erişimini test etmek için aç:
  /*
  try {
    $tmp = has_tus($arayanNo, '2');
  } catch (Throwable $e) {
    plain_out('error', 200);
  }
  */

  plain_out('success', 200);
}

/* ---------------- JSON API Modu ---------------- */
if ($wantsJson) {
  // token kontrol (config'te token tanımlıysa zorunlu)
  if ($expectedToken !== '1b40bd059d3ee0f9c5acccf50618a46b259e9460b2c844f7') {
    if ($token === '1b40bd059d3ee0f9c5acccf50618a46b259e9460b2c844f7' || !hash_equals($expectedToken, $token)) {
      json_out([
        'status' => 'error',
        'message' => 'Token hatalı veya eksik.',
        'token_ok' => false,
      ], 401);
    }
  }

  if ($arayanNo === '') {
    json_out([
      'status' => 'error',
      'message' => 'arayan_no eksik.',
      'token_ok' => ($expectedToken === '1b40bd059d3ee0f9c5acccf50618a46b259e9460b2c844f7' ? null : true),
    ], 400);
  }

  // ✅ KURAL
  $hasApproved = has_tus($arayanNo, consent_digit_approved());
  $hasRejected = $hasApproved ? true : has_tus($arayanNo, consent_digit_rejected());
  $latest = latest_tus($arayanNo);

  if ($hasApproved) {
    json_out([
      'status' => 'success',
      'message' => 'Daha önce onaylı tuş seçilmiş. IVR tekrar sormasın.',
      'arayan_no' => $arayanNo,
      'consent' => 'granted',
      'ask_consent' => false,
      'reason' => 'approved_digit_found',
      'found' => [
        'approved' => $hasApproved,
        'rejected' => $hasRejected,
        'approved_digit' => consent_digit_approved(),
        'rejected_digit' => consent_digit_rejected(),
      ],
      'latest' => $latest,
      'token_ok' => ($expectedToken === '1b40bd059d3ee0f9c5acccf50618a46b259e9460b2c844f7' ? null : true),
    ]);
  }

  $reason = $hasRejected ? 'only_rejected_digit_found' : 'no_history';
  $msg = $hasRejected
    ? 'Gecmiste onaysiz tus var. Onayli tusa basana kadar her aramada sor.'
    : 'Geçmiş kayıt yok. İlk kez sor.';

  json_out([
    'status' => 'success',
    'message' => $msg,
    'arayan_no' => $arayanNo,
    'consent' => $hasRejected ? 'pending' : 'unknown',
    'ask_consent' => true,
    'reason' => $reason,
    'found' => [
      'approved' => $hasApproved,
      'rejected' => $hasRejected,
      'approved_digit' => consent_digit_approved(),
      'rejected_digit' => consent_digit_rejected(),
    ],
    'latest' => $latest,
    'token_ok' => ($expectedToken === '1b40bd059d3ee0f9c5acccf50618a46b259e9460b2c844f7' ? null : true),
  ]);
}

/* ---------------- UI TEST SAYFASI (Browser GET) ---------------- */

$tokenForUi = (string)($_GET['token'] ?? '1b40bd059d3ee0f9c5acccf50618a46b259e9460b2c844f7');
?>
<!doctype html>
<html lang="tr">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
  <title>Consent Test</title>
  <style>
    @font-face {
      font-family: 'Nexa';
      src: url('/assets/fonts/NexaRegular.woff2') format('woff2'),
           url('/assets/fonts/NexaRegular.woff') format('woff');
      font-weight: 400; font-style: normal; font-display: swap;
    }
    @font-face {
      font-family: 'Nexa';
      src: url('/assets/fonts/Nexa Bold.woff2') format('woff2'),
           url('/assets/fonts/Nexa Bold.woff') format('woff');
      font-weight: 700; font-style: normal; font-display: swap;
    }
    @font-face {
      font-family: 'Nexa';
      src: url('/assets/fonts/Nexa-Heavy.woff2') format('woff2'),
           url('/assets/fonts/Nexa-Heavy.woff') format('woff');
      font-weight: 800; font-style: normal; font-display: swap;
    }

    * { margin:0; padding:0; box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
    body{
      font-family:'Nexa', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
      background:#fff; color:#000; min-height:100vh;
      padding: 14px 10px;
      display:flex; align-items:center; justify-content:center;
    }
    .wrap{ width:100%; max-width:520px; }
    .card{
      background:#f8f8f8;
      border-radius:16px;
      padding:14px;
    }
    .title{ font-size:18px; font-weight:900; letter-spacing:-0.2px; text-align:center; }
    .sub{ margin-top:6px; font-size:12px; font-weight:800; color:#666; text-align:center; line-height:1.35; }
    .field{ margin-top:12px; }
    .label{ font-size:12px; font-weight:900; color:#666; padding:0 2px 6px 2px; }
    .inrow{
      display:flex; align-items:center; gap:8px;
      background:#fff; border:1px solid #e0e0e0; border-radius:20px;
      padding:10px 12px;
    }
    .inrow input{
      width:100%;
      border:none; outline:none;
      background:transparent;
      font-family:'Nexa', sans-serif;
      font-weight:900;
      font-size:15px;
    }
    .btn{
      width:100%;
      margin-top:12px;
      padding:12px 14px;
      border:none;
      border-radius:14px;
      font-family:'Nexa', sans-serif;
      font-weight:900;
      font-size:15px;
      cursor:pointer;
      background:#111;
      color:#fff;
      display:flex;
      align-items:center;
      justify-content:center;
      gap:10px;
    }
    .btn[disabled]{ opacity:.75; cursor:not-allowed; }
    .spin{
      width:16px; height:16px; border-radius:999px;
      border:2px solid rgba(255,255,255,.35);
      border-top-color:#fff;
      animation: spin .8s linear infinite;
      display:none;
    }
    @keyframes spin{ to{ transform:rotate(360deg);} }

    .alert{
      margin-top:12px;
      border-radius:12px;
      padding:12px;
      font-weight:900;
      font-size:13px;
      line-height:1.35;
      background:#eeeeee;
      color:#333;
      word-break:break-word;
    }
    .ok{ background:#e8f5e9; color:#2e7d32; }
    .err{ background:#ffebee; color:#c62828; }

    .box{
      margin-top:10px;
      background:#fff;
      border:1px solid #e6e6e6;
      border-radius:12px;
      padding:10px;
      font-size:12px;
      font-weight:800;
      color:#444;
      white-space:pre-wrap;
    }
    .tiny{
      margin-top:10px;
      text-align:center;
      font-size:12px;
      color:#999;
      font-weight:800;
    }
  </style>
</head>
<body>
  <div class="wrap">
    <div class="card">
      <div class="title">Consent / IVR Karar Testi</div>
      <div class="sub">
        arayan_no gir ve kontrol et: <br>
        2 varsa <b>sorma</b>, 2 yoksa <b>her aramada sor</b>.
      </div>

      <div class="field">
        <div class="label">Token (opsiyonel)</div>
        <div class="inrow">
          <input id="token" placeholder="token" value="<?= htmlspecialchars($tokenForUi, ENT_QUOTES, 'UTF-8') ?>"/>
        </div>
      </div>

      <div class="field">
        <div class="label">Arayan Numara</div>
        <div class="inrow">
          <input id="arayan" placeholder="0533..." inputmode="tel" />
        </div>
      </div>

      <button class="btn" id="btn">
        <span class="spin" id="spin"></span>
        <span id="btnText">Kontrol Et</span>
      </button>

      <div id="msg" class="alert" style="display:none;"></div>
      <div id="raw" class="box" style="display:none;"></div>

      <div class="tiny">Endpoint: <?= htmlspecialchars(basename(__FILE__), ENT_QUOTES, 'UTF-8') ?></div>
    </div>
  </div>

  <script>
    const btn = document.getElementById('btn');
    const spin = document.getElementById('spin');
    const btnText = document.getElementById('btnText');
    const msg = document.getElementById('msg');
    const raw = document.getElementById('raw');

    function setLoading(on){
      btn.disabled = on;
      spin.style.display = on ? 'inline-block' : 'none';
      btnText.textContent = on ? 'Kontrol ediliyor...' : 'Kontrol Et';
    }

    function showAlert(type, text){
      msg.style.display = 'block';
      msg.className = 'alert ' + (type === 'ok' ? 'ok' : 'err');
      msg.textContent = text;
    }

    btn.addEventListener('click', async () => {
      const token = document.getElementById('token').value.trim();
      const arayan = document.getElementById('arayan').value.trim();

      msg.style.display = 'none';
      raw.style.display = 'none';
      raw.textContent = '';

      if (!arayan) {
        showAlert('err', 'Arayan numara gir.');
        return;
      }

      setLoading(true);
      try {
        const form = new URLSearchParams();
        form.set('arayan_no', arayan);
        if (token) form.set('token', token);

        const res = await fetch(window.location.pathname + '?api=1', {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' },
          body: form.toString()
        });

        const text = await res.text();

        let data = null;
        try { data = JSON.parse(text); } catch(e) {}

        if (!data || typeof data !== 'object') {
          showAlert('err', 'Sunucu JSON döndürmedi. Çıktı: ' + text.slice(0, 250));
          raw.style.display = 'block';
          raw.textContent = text;
          return;
        }

        if (data.status === 'success') {
          const ask = data.ask_consent ? 'SOR' : 'SORMAYACAK';
          showAlert('ok', ask + ' • ' + (data.message || 'OK'));
        } else {
          showAlert('err', (data.message || 'Hata'));
        }

        raw.style.display = 'block';
        raw.textContent = JSON.stringify(data, null, 2);

      } catch (e) {
        showAlert('err', 'İstek hatası: ' + (e?.message || e));
      } finally {
        setLoading(false);
      }
    });
  </script>
</body>
</html>
