<?php
declare(strict_types=1);

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();

if (empty($_SESSION['user_id'])) {
  header('Location: login.php');
  exit;
}

function sms_load_config(): array
{
  $cfg = app_config();
  $sms = $cfg['sms'] ?? null;
  if (!is_array($sms) || empty($sms)) {
    $file = __DIR__ . '/../config/sms.php';
    if (is_file($file)) {
      $sms = require $file;
    }
  }
  return is_array($sms) ? $sms : [];
}

function normalize_phone(string $raw): string
{
  $digits = preg_replace('/\D+/', '', $raw) ?? '';
  if ($digits === '') return '';
  if (strlen($digits) === 10) return '90' . $digits; // 5xxxxxxxxx
  if (strlen($digits) === 11 && str_starts_with($digits, '0')) return '90' . substr($digits, 1);
  if (strlen($digits) === 12 && str_starts_with($digits, '90')) return $digits;
  return $digits;
}

function parse_numbers(string $input): array
{
  $parts = preg_split('/[\s,;]+/', $input) ?: [];
  $set = [];
  foreach ($parts as $p) {
    $p = trim($p);
    if ($p === '') continue;
    $n = normalize_phone($p);
    if ($n !== '') $set[$n] = true;
  }
  return array_keys($set);
}

function fetch_onayli_numbers(PDO $pdo): array
{
  $nums = [];
  try {
    $st = $pdo->query("SELECT raw_body FROM webhook_logs WHERE raw_body IS NOT NULL AND raw_body <> '' ORDER BY id DESC");
    $rows = $st ? ($st->fetchAll() ?: []) : [];
    foreach ($rows as $r) {
      $raw = (string)($r['raw_body'] ?? '');
      if ($raw === '') continue;

      $payload = parse_webhook_payload($raw);
      if (!is_array($payload)) continue;

      $arayan = payload_pick($payload, ['arayan_no', 'arayan', 'caller', 'from', 'msisdn']);
      $tus = payload_pick($payload, ['tus_bilgisi', 'digit']);
      if ($arayan === '' || !consent_is_approved_digit($tus)) continue;

      $n = normalize_phone($arayan);
      if ($n !== '') $nums[$n] = true;
    }
  } catch (Throwable $e) {
    // ignore
  }

  return array_keys($nums);
}

function http_decode_chunked(string $body): string
{
  $out = '';
  while (true) {
    if (!preg_match('/^([0-9a-fA-F]+)\r\n/', $body, $m)) {
      return $out !== '' ? $out : $body;
    }
    $len = hexdec($m[1]);
    $body = substr($body, strlen($m[0]));
    if ($len === 0) {
      return $out;
    }
    $out .= substr($body, 0, $len);
    $body = substr($body, $len + 2);
  }
}

function socket_http_request(string $url, string $method, string $body, int $timeout): string
{
  $u = parse_url($url);
  if (!is_array($u) || empty($u['host'])) {
    throw new RuntimeException('NETGSM URL hatali.');
  }
  $scheme = strtolower((string)($u['scheme'] ?? 'http'));
  $host = (string)$u['host'];
  $port = (int)($u['port'] ?? ($scheme === 'https' ? 443 : 80));
  $path = (string)($u['path'] ?? '/');
  if (!empty($u['query'])) {
    $path .= '?' . $u['query'];
  }

  $transport = ($scheme == 'https') ? 'ssl://' : '';
  $fp = @stream_socket_client($transport . $host . ':' . $port, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT);
  if (!$fp) {
    throw new RuntimeException("NETGSM baglanti hatasi: {$errstr} ({$errno})");
  }
  stream_set_timeout($fp, $timeout);

  $headers = [];
  $headers[] = $method . ' ' . $path . ' HTTP/1.1';
  $headers[] = 'Host: ' . $host;
  $headers[] = 'User-Agent: IVR-SMS/1.0';
  $headers[] = 'Accept: */*';
  $headers[] = 'Connection: close';

  if ($method !== 'GET') {
    $headers[] = 'Content-Type: application/x-www-form-urlencoded';
    $headers[] = 'Content-Length: ' . strlen($body);
  }

  $raw = implode("\r\n", $headers) . "\r\n\r\n" . ($method === 'GET' ? '' : $body);
  fwrite($fp, $raw);

  $resp = stream_get_contents($fp);
  fclose($fp);

  if ($resp === false || $resp === '') {
    throw new RuntimeException('NETGSM baglanti hatasi: bos yanit.');
  }

  $parts = preg_split("/\r\n\r\n/", $resp, 2);
  $headersText = $parts[0] ?? '';
  $bodyText = $parts[1] ?? '';

  if (preg_match('/\r\nTransfer-Encoding:\s*chunked/i', $headersText)) {
    $bodyText = http_decode_chunked($bodyText);
  }

  return (string)$bodyText;
}

function netgsm_request(string $endpoint, array $payload, string $method, int $timeout): string
{
  $isHttps = str_starts_with(strtolower($endpoint), 'https://');
  if ($isHttps && !extension_loaded('openssl')) {
    throw new RuntimeException('OpenSSL aktif degil. php.ini icinde extension=openssl acin ve web sunucusunu yeniden baslatin.');
  }
  $method = strtoupper($method);
  $query = http_build_query($payload);

  $url = $endpoint;
  $body = '';
  if ($method === 'GET') {
    $url = rtrim($endpoint, '?');
    $url .= (str_contains($url, '?') ? '&' : '?') . $query;
  } else {
    $body = $query;
  }

  $resp = null;

  if (ini_get('allow_url_fopen')) {
    if ($method === 'GET') {
      $resp = @file_get_contents($url);
    } else {
      $opts = [
        'http' => [
          'method' => 'POST',
          'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
          'content' => $body,
          'timeout' => $timeout,
        ],
      ];
      $ctx = stream_context_create($opts);
      $resp = @file_get_contents($url, false, $ctx);
    }
  }

  if (($resp === false || $resp === null) && function_exists('curl_init')) {
    $ch = curl_init($url);
    if ($method !== 'GET') {
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
    }
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    $resp = curl_exec($ch);
    $err = curl_error($ch);
    curl_close($ch);
    if ($resp === false) {
      $resp = null;
      $errMsg = $err ?: 'bilinmiyor';
    }
  }

  if ($resp === false || $resp === null) {
    $resp = socket_http_request($url, $method, $body, $timeout);
  }

  if ($resp === false || $resp === null) {
    $err = error_get_last();
    throw new RuntimeException('NETGSM baglanti hatasi: ' . ($err['message'] ?? 'bilinmiyor'));
  }

  return (string)$resp;
}

function netgsm_send(array $numbers, string $message, array $cfg): array
{
  $endpoint = (string)($cfg['endpoint'] ?? '');
  $username = (string)($cfg['username'] ?? '');
  $password = (string)($cfg['password'] ?? '');
  $header = (string)($cfg['header'] ?? '');
  $method = (string)($cfg['method'] ?? 'POST');
  $timeout = (int)($cfg['timeout'] ?? 30);
  $batchSize = (int)($cfg['batch_size'] ?? 300);

  if ($endpoint === '' || $username === '' || $password === '' || $header === '') {
    return [false, 0, 'NETGSM ayarlari eksik.'];
  }

  $sent = 0;
  $responses = [];
  $chunks = array_chunk($numbers, max(1, $batchSize));

  foreach ($chunks as $chunk) {
    $payload = [
      'usercode' => $username,
      'password' => $password,
      'gsmno' => implode(',', $chunk),
      'message' => $message,
      'msgheader' => $header,
      'dil' => 'TR',
    ];

    try {
      $resp = trim(netgsm_request($endpoint, $payload, $method, $timeout));
    } catch (Throwable $e) {
      return [false, $sent, $e->getMessage()];
    }
    $responses[] = $resp;

    // Netgsm success usually starts with 00
    if (substr($resp, 0, 2) !== '00') {
      return [false, $sent, 'NETGSM yanit: ' . $resp];
    }

    $sent += count($chunk);
  }

  return [true, $sent, implode(' | ', $responses)];
}

$pdo = db();
$smsCfg = sms_load_config();
$onayliNumbers = fetch_onayli_numbers($pdo);
$onayliCount = count($onayliNumbers);

$defaultType = 'bilgi';
$selectedType = (string)($_POST['sms_type'] ?? $defaultType);
$selectedType = in_array($selectedType, ['bilgi', 'ticari'], true) ? $selectedType : $defaultType;

$includeOnayli = !empty($_POST['include_onayli']);
$includeExtra = !empty($_POST['include_extra']);
$message = trim((string)($_POST['message'] ?? ''));
$extraRaw = (string)($_POST['extra_numbers'] ?? '');

$errors = [];
$successMsg = '';
$resultDetails = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST' && (string)($_POST['action'] ?? '') === 'send_sms') {
  csrf_verify();

  if ($message === '') {
    $errors[] = 'SMS icerigi bos olamaz.';
  }

  $extraNumbers = parse_numbers($extraRaw);

  if ($selectedType === 'ticari') {
    if (!$includeOnayli) {
      $errors[] = 'Ticari icerik sadece onayli numaralara gonderebilir.';
    }
    if ($includeExtra && $extraNumbers) {
      $errors[] = 'Ticari icerik icin ekstra numara eklenemez.';
    }
    $includeExtra = false;
    $extraNumbers = [];
  } else {
    if (!$includeOnayli && !$includeExtra) {
      $errors[] = 'En az bir hedef secmelisiniz.';
    }
    if (!$includeExtra) {
      $extraNumbers = [];
    }
  }

  $recipients = [];
  if ($includeOnayli) {
    foreach ($onayliNumbers as $n) $recipients[$n] = true;
  }
  if ($includeExtra) {
    foreach ($extraNumbers as $n) $recipients[$n] = true;
  }

  $totalRecipients = count($recipients);
  if ($totalRecipients === 0 && !$errors) {
    $errors[] = 'Gonderilecek numara bulunamadi.';
  }

  if (!$errors) {
    [$ok, $sentCount, $resp] = netgsm_send(array_keys($recipients), $message, $smsCfg);
    if ($ok) {
      $successMsg = 'SMS gonderildi.';
      $resultDetails = 'Giden kisi sayisi: ' . $sentCount;
    } else {
      $errors[] = $resp;
    }
  }
}

$previewHeader = (string)($smsCfg['header'] ?? '');
$previewType = $selectedType === 'ticari' ? 'Ticari' : 'Bilgilendirme';

$initialIncludeOnayli = $includeOnayli || $_SERVER['REQUEST_METHOD'] !== 'POST';
$initialIncludeExtra = $includeExtra && $selectedType === 'bilgi';
?>
<!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>SMS Gonder</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:white; color:black; line-height:1.3; min-height:100vh;
      padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
    }

    .container { max-width:100%; padding:8px; }
    @media (min-width: 900px){
      .container{ max-width:980px; margin:0 auto; padding:16px; }
    }

    .header{
      display:flex; align-items:center; justify-content:space-between;
      padding:12px 0 8px 0; margin-bottom:12px; gap: 10px; flex-wrap:wrap;
    }
    .header-left{ display:flex; flex-direction:column; gap:4px; min-width: 0; }
    .header-title{ font-size:18px; font-weight:800; letter-spacing:-0.2px; }
    .header-sub{ font-size:12px; color:#666; font-weight:800; }
    .header-actions{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; justify-content:flex-end; }

    .pillbtn{
      background:#f0f0f0; border:none; padding:6px 12px; border-radius:16px;
      font-size:13px; font-family:'Nexa', sans-serif;
      display:inline-flex; align-items:center; gap:6px;
      cursor:pointer; text-decoration:none; color:black; font-weight:800;
      white-space: nowrap;
    }

    .preview{
      background:#f8f8f8; border-radius:14px; padding:12px; margin-bottom:10px;
    }
    .preview-title{ font-weight:900; font-size:14px; margin-bottom:6px; }
    .preview-box{
      background:#fff; border:1px solid #e6e6e6; border-radius:12px; padding:12px;
    }
    .preview-head{ font-size:12px; color:#666; font-weight:800; margin-bottom:6px; }
    .preview-msg{ font-size:14px; font-weight:800; white-space:pre-wrap; }

    .form-card{ background:#f8f8f8; border-radius:14px; padding:12px; }
    .grid{ display:grid; grid-template-columns:1fr; gap:10px; }
    @media (min-width: 900px){
      .grid{ grid-template-columns: 1fr 1fr; }
      .grid .full{ grid-column: 1 / -1; }
    }

    .field{ display:flex; flex-direction:column; gap:6px; }
    .field-label{ font-size:12px; color:#666; font-weight:800; padding:0 2px; }
    .in{
      width:100%; padding:10px 14px; border:1px solid #e0e0e0; border-radius:20px;
      font-size:15px; background:#fff; font-family:'Nexa', sans-serif; outline:none;
    }
    .in:focus{ border-color:#d0d0d0; }

    .radio-row{ display:flex; gap:8px; flex-wrap:wrap; }
    .radio{
      display:flex; align-items:center; gap:10px; padding:10px 16px; border-radius:999px;
      border:1px solid #e5e5e5; background:#fff; cursor:pointer; font-weight:900; font-size:13px;
      transition: all .15s ease;
    }
    .radio input{ display:none; }
    .radio .dot{
      width:12px; height:12px; border-radius:50%; background:#d6d6d6;
      box-shadow: inset 0 0 0 2px #fff;
      transition: all .15s ease;
    }
    .radio.active{
      border-color:#bfe5c6; background: linear-gradient(135deg, #e9f7ef, #ffffff);
      color:#2e7d32; box-shadow: 0 6px 14px rgba(46,125,50,0.12);
    }
    .radio.active .dot{
      background:#2e7d32; box-shadow: 0 0 0 3px rgba(46,125,50,0.2);
    }

    .check{
      position:relative;
      display:flex; align-items:center; gap:10px; background:#fff; border:1px solid #e0e0e0;
      border-radius:20px; padding:10px 14px; cursor:pointer; font-weight:900; font-size:13px;
      transition: border .15s ease, background .15s ease, opacity .15s ease;
    }
    .check input{ position:absolute; opacity:0; pointer-events:none; }
    .check .toggle{
      width:38px; height:20px; background:#e5e5e5; border-radius:999px; position:relative;
      transition: background .15s ease; flex-shrink:0;
    }
    .check .toggle::after{
      content:''; position:absolute; top:2px; left:2px; width:16px; height:16px;
      background:#fff; border-radius:50%; box-shadow:0 2px 6px rgba(0,0,0,0.15);
      transition: transform .15s ease;
    }
    .check input:checked + .toggle{ background:#2e7d32; }
    .check input:checked + .toggle::after{ transform: translateX(18px); }
    .check .ctext{ line-height:1.2; }
    .check.disabled{ opacity:.55; }

    .counts{ font-size:12px; color:#666; font-weight:800; }
    .counts b{ color:#111; }

    .notice{ padding:8px 10px; border-radius:10px; font-size:12px; font-weight:900; margin-bottom:8px; }
    .notice.ok{ background:#e8f5e9; color:#2e7d32; }
    .notice.err{ background:#ffebee; color:#c62828; }

    .btnrow{ display:flex; gap:8px; justify-content:flex-end; margin-top:10px; flex-wrap:wrap; }
    .btn{
      padding:10px 14px; background:#111; border:none; border-radius:20px;
      font-weight:900; cursor:pointer; font-family:'Nexa', sans-serif;
      font-size:14px; white-space:nowrap; color:#fff;
    }

    .hint{ font-size:12px; color:#666; font-weight:800; line-height:1.35; }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <div class="header-left">
        <div class="header-title">SMS Gonder</div>
        <div class="header-sub">Onayli sayisi: <?= (int)$onayliCount ?></div>
      </div>
      <div class="header-actions">
        <a href="dashboard.php" class="pillbtn"><- Panel</a>
      </div>
    </div>

    <div class="preview">
      <div class="preview-title">Gonderim Onizleme</div>
      <div class="preview-box">
        <div class="preview-head">Baslik: <span id="prevHeader"><?= e($previewHeader) ?></span> | Tip: <span id="prevType"><?= e($previewType) ?></span></div>
        <div class="preview-msg" id="prevMessage"><?= e($message !== '' ? $message : 'Mesaj burada gorunecek') ?></div>
      </div>
    </div>

    <div class="form-card">
      <?php if ($successMsg !== ''): ?>
        <div class="notice ok"><?= e($successMsg) ?> <?= $resultDetails ? ' - ' . e($resultDetails) : '' ?></div>
      <?php endif; ?>
      <?php foreach ($errors as $err): ?>
        <div class="notice err"><?= e($err) ?></div>
      <?php endforeach; ?>

      <form method="post">
        <input type="hidden" name="action" value="send_sms" />
        <input type="hidden" name="csrf" value="<?= e(csrf_token()) ?>" />

        <div class="grid">
          <div class="field full">
            <div class="field-label">SMS Tipi</div>
            <div class="radio-row" id="smsTypeRow">
              <label class="radio" id="lblBilgi">
                <input type="radio" name="sms_type" value="bilgi" <?= $selectedType==='bilgi'?'checked':''; ?>>
                <span class="dot"></span>
                Bilgilendirme
              </label>
              <label class="radio" id="lblTicari">
                <input type="radio" name="sms_type" value="ticari" <?= $selectedType==='ticari'?'checked':''; ?>>
                <span class="dot"></span>
                Ticari
              </label>
            </div>
          </div>

          <div class="field full">
            <div class="field-label">SMS Icerigi</div>
            <textarea class="in" name="message" id="message" rows="4" placeholder="Mesajinizi yazin..."><?= e($message) ?></textarea>
          </div>

          <div class="field">
            <div class="field-label">Hedef Secimi</div>
            <label class="check" id="lblOnayli">
              <input type="checkbox" name="include_onayli" id="include_onayli" value="1" <?= $initialIncludeOnayli ? 'checked' : '' ?>>
              <span class="toggle"></span>
              <span class="ctext">Onaylilara gonder (<?= (int)$onayliCount ?>)</span>
            </label>
          </div>
          <div class="field">
            <div class="field-label">Ekstra Numara</div>
            <label class="check" id="lblExtra">
              <input type="checkbox" name="include_extra" id="include_extra" value="1" <?= $initialIncludeExtra ? 'checked' : '' ?>>
              <span class="toggle"></span>
              <span class="ctext">Ekstra numaralari dahil et</span>
            </label>
          </div>

          <div class="field full">
            <div class="field-label">Ekstra Numara Listesi (virgul veya yeni satir)</div>
            <textarea class="in" name="extra_numbers" id="extra_numbers" rows="3" placeholder="905xxxxxxxxx, 05xxxxxxxxx ..."><?= e($extraRaw) ?></textarea>
            <div class="hint">Ticari icerikte ekstra numara kullanilamaz. Bilgilendirme icin ekleyebilirsiniz.</div>
          </div>

          <div class="field full">
            <div class="counts" id="countInfo">Toplam kisi: <b>0</b></div>
          </div>
        </div>

        <div class="btnrow">
          <button class="btn" type="submit">SMS Gonder</button>
        </div>
      </form>
    </div>
  </div>

  <script>
    const onayliCount = <?= (int)$onayliCount ?>;
    const messageEl = document.getElementById('message');
    const prevMessage = document.getElementById('prevMessage');
    const prevHeader = document.getElementById('prevHeader');
    const prevType = document.getElementById('prevType');
    const includeOnayli = document.getElementById('include_onayli');
    const includeExtra = document.getElementById('include_extra');
    const extraNumbers = document.getElementById('extra_numbers');
    const countInfo = document.getElementById('countInfo');

    const lblBilgi = document.getElementById('lblBilgi');
    const lblTicari = document.getElementById('lblTicari');
    const lblExtra = document.getElementById('lblExtra');

    function parseNums(txt){
      const parts = txt.split(/[\s,;]+/).map(p => p.trim()).filter(Boolean);
      const set = new Set();
      for (const p of parts){
        const digits = p.replace(/\D+/g, '');
        if (!digits) continue;
        let n = '';
        if (digits.length === 10) n = '90' + digits;
        else if (digits.length === 11 && digits.startsWith('0')) n = '90' + digits.slice(1);
        else if (digits.length === 12 && digits.startsWith('90')) n = digits;
        else n = digits;
        if (n) set.add(n);
      }
      return Array.from(set);
    }

    function updatePreview(){
      const msg = messageEl.value.trim();
      prevMessage.textContent = msg || 'Mesaj burada gorunecek';

      const type = document.querySelector('input[name="sms_type"]:checked')?.value || 'bilgi';
      prevType.textContent = type === 'ticari' ? 'Ticari' : 'Bilgilendirme';

      // toggle radio style
      if (type === 'ticari') {
        lblTicari.classList.add('active');
        lblBilgi.classList.remove('active');
        includeExtra.checked = false;
        includeExtra.disabled = true;
        extraNumbers.disabled = true;
        if (lblExtra) lblExtra.classList.add('disabled');
      } else {
        lblBilgi.classList.add('active');
        lblTicari.classList.remove('active');
        includeExtra.disabled = false;
        extraNumbers.disabled = !includeExtra.checked;
        if (lblExtra) lblExtra.classList.remove('disabled');
      }

      const extraList = includeExtra.checked ? parseNums(extraNumbers.value) : [];
      const total = (includeOnayli.checked ? onayliCount : 0) + extraList.length;
      const parts = [];
      parts.push('Toplam kisi: ' + total);
      parts.push('Onayli: ' + (includeOnayli.checked ? onayliCount : 0));
      parts.push('Ekstra: ' + extraList.length);
      countInfo.innerHTML = parts.join(' | ');
    }

    document.querySelectorAll('input[name="sms_type"]').forEach(r => r.addEventListener('change', updatePreview));
    includeOnayli.addEventListener('change', updatePreview);
    includeExtra.addEventListener('change', () => {
      extraNumbers.disabled = !includeExtra.checked;
      updatePreview();
    });
    extraNumbers.addEventListener('input', updatePreview);
    messageEl.addEventListener('input', updatePreview);

    updatePreview();
  </script>
</body>
</html>
