<?php
require_once __DIR__ . '/../global.php';

function twilio_signature_ok(): bool
{
  $sig = $_SERVER['HTTP_X_TWILIO_SIGNATURE'] ?? '';
  if ($sig === '')
    return false;

  $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https://' : 'http://';
  $url = $scheme . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

  $params = $_POST;
  ksort($params);
  $data = $url;
  foreach ($params as $k => $v)
    $data .= $k . $v;

  $expected = base64_encode(hash_hmac('sha1', $data, TWILIO_AUTH_TOKEN, true));
  return hash_equals($expected, $sig);
}

if (!function_exists('normalize_e164_guess')) {
  function normalize_e164_guess($raw, $defaultCc = '+92')
  {
    $s = preg_replace('/[^0-9+]/', '', (string) $raw);
    if ($s === '')
      return '';
    if ($s[0] === '+')
      return $s;
    return $defaultCc . ltrim($s, '0');
  }
}

if (!twilio_signature_ok()) {
  http_response_code(403);
  exit;
}

$from = $_POST['From'] ?? '';
$to = $_POST['To'] ?? '';
$body = $_POST['Body'] ?? '';
$lower = mb_strtolower(trim((string) $body));
if ($lower !== '' && preg_match('/\b(stop|unsubscribe|opt\s*out)\b/u', $lower)) {
  $phoneNorm = normalize_e164_guess(preg_replace('/^whatsapp:/', '', $from));
  if ($phoneNorm !== '') {
    $dbF->setRow("UPDATE whatsapp_contacts SET opt_out=1 WHERE phone_e164=?", [$phoneNorm]);
  }
}
$mediaUrl = ((int) ($_POST['NumMedia'] ?? 0) > 0) ? ($_POST['MediaUrl0'] ?? '') : '';
$waId = $_POST['WaId'] ?? null;
$profileName = $_POST['ProfileName'] ?? null;

if (!$profileName && !empty($_POST['ChannelMetadata'])) {
  $meta = json_decode($_POST['ChannelMetadata'], true);
  if (json_last_error() === JSON_ERROR_NONE) {
    $ctx = $meta['data']['context'] ?? [];
    if (!empty($ctx['ProfileName']))
      $profileName = $ctx['ProfileName'];
    if (!$waId && !empty($ctx['WaId']))
      $waId = $ctx['WaId'];
  }
}

if ($from !== '') {
  $phone = preg_replace('/^whatsapp:/', '', $from);
  $display = $profileName ?: $waId ?: null;
  $dbF->setRow("INSERT INTO whatsapp_contacts (phone_e164, display_name) VALUES (?, ?) ON DUPLICATE KEY UPDATE display_name = COALESCE(NULLIF(VALUES(display_name), ''), display_name)", [$phone, $display]);
}

$dbF->setRow("INSERT INTO whatsapp_messages (direction, wa_from, wa_to, body, media_url, status, twilio_sid) VALUES ('inbound', ?, ?, ?, ?, 'received', ?)", [$from, $to, $body, $mediaUrl ?: null, ($_POST['MessageSid'] ?? null)]);
$inboundId = $dbF->rowLastId ?? null;

$phoneNorm = normalize_e164_guess(preg_replace('/^whatsapp:/', '', $from));
$acc = $dbF->getRow("SELECT acc_id FROM accounts_user WHERE acc_phone = ? LIMIT 1", [$phoneNorm]);
if (empty($acc)) {
  $acc = $dbF->getRow("SELECT user_id AS acc_id FROM user_phones WHERE phone = ? LIMIT 1", [$phoneNorm]);
}

if (empty($acc)) {
  $guessName = $profileName ?: $waId ?: $phoneNorm;
  $dbF->setRow("INSERT INTO accounts_user (acc_name, acc_phone, acc_email, created_at) VALUES (?, ?, NULL, NOW())", [$guessName, $phoneNorm]);
  $newAccId = $dbF->rowLastId ?? null;
  $acc = ['acc_id' => $newAccId];
}

$accId = $acc['acc_id'] ?? null;

$dbF->setRow("UPDATE whatsapp_contacts SET account_id = COALESCE(?, account_id) WHERE phone_e164 = ?", [$accId, $phoneNorm]);
if ($inboundId) {
  $dbF->setRow("UPDATE whatsapp_messages SET account_id = ? WHERE id = ?", [$accId, $inboundId]);
}

$isFirst = false;
$prev = $dbF->getRow("SELECT id FROM whatsapp_messages WHERE (wa_from = ? OR wa_to = ?) AND id <> ? ORDER BY id ASC LIMIT 1", [$from, $from, (int) $inboundId]);
if (!$prev)
  $isFirst = true;

$rules = $dbF->getRows("SELECT * FROM wa_rules WHERE active=1 ORDER BY priority ASC");
$bodyLower = mb_strtolower(trim((string) $body));

foreach ($rules as $rule) {
  $match = false;
  switch ($rule['match_type']) {
    case 'always':
      $match = true;
      break;

    case 'first_message':
      $match = $isFirst;
      break;

    case 'keyword':
      $terms = array_filter(array_map('trim', explode(',', (string) $rule['match_value'])));
      foreach ($terms as $t) {
        if ($t !== '' && mb_strpos($bodyLower, mb_strtolower($t)) !== false) {
          $match = true;
          break;
        }
      }
      break;
  }

  if ($match) {
    $tpl = $dbF->getRow("SELECT body FROM wa_templates WHERE id = ?", [$rule['template_id']]);
    if (!empty($tpl)) {
      $contactRow = $dbF->getRow("SELECT * FROM whatsapp_contacts WHERE phone_e164 = ? LIMIT 1", [$phoneNorm]);
      $accountRow = $accId ? $dbF->getRow("SELECT * FROM accounts_user WHERE acc_id = ? LIMIT 1", [$accId]) : null;

      $rendered = WATemplate::render($tpl['body'], [
        'name' => $profileName ?: ($waId ?: $phoneNorm),
        'phone' => $phoneNorm,
        'contact' => [
          'name' => $contactRow['display_name'] ?? '',
          'phone' => $contactRow['phone_e164'] ?? $phoneNorm,
        ],
        'account' => [
          'id' => $accountRow['acc_id'] ?? '',
          'name' => $accountRow['acc_name'] ?? '',
          'phone' => $accountRow['acc_phone'] ?? '',
        ],
      ]);

      $scheduleAt = !empty($rule['schedule_delay_minutes'])
        ? date('Y-m-d H:i:s', time() + (int) $rule['schedule_delay_minutes'] * 60)
        : null;

      $opt = $dbF->getRow("SELECT opt_out FROM whatsapp_contacts WHERE phone_e164 = ? LIMIT 1", [$phoneNorm]);
      if ($opt && (int) $opt['opt_out'] === 1) {
        continue;
      }

      $insOk = $dbF->setRow("INSERT INTO wa_queue (to_e164, rendered_body, status, schedule_at, rule_id, inbound_id) VALUES (?, ?, 'queued', ?, ?, ?)", 
      [$phoneNorm, $rendered, $scheduleAt, $rule['id'], $inboundId]);

      $qid = $dbF->rowLastId ?? null;
      if (!$qid && is_numeric($insOk)) {
        $qid = (int) $insOk;
      }
      if (!$qid) {
        $row = $dbF->getRow("SELECT LAST_INSERT_ID() AS lid");
        if (!empty($row['lid']))
          $qid = (int) $row['lid'];
      }

      if ($qid) {
        $dbF->setRow("INSERT INTO wa_rule_logs (rule_id, wa_message_id, wa_queue_id) VALUES (?,?,?)", [$rule['id'], $inboundId, $qid]);
      }
    }

    if ((int) $rule['stop_after_match'] === 1)
      break;
  }
}

header('Content-Type: text/xml; charset=utf-8');
echo '<Response></Response>';