<?php
// public/api/apioficial.php
require_once __DIR__ . '/../../app/config.php';
require_once __DIR__ . '/../../app/db.php';

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

function jexit(array $payload, int $status = 200) {
  http_response_code($status);
  echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
  exit;
}

// --- Sessão / autenticação ---
if (empty($_SESSION['user']['id']) || empty($_SESSION['user']['email'])) {
  jexit(['ok' => false, 'error' => 'não autenticado'], 401);
}

$USER_ID = (string)$_SESSION['user']['id'];
$EMAIL   = (string)$_SESSION['user']['email'];

$pdo = db();

/* =========================================================
 * Helpers
 * ======================================================= */

function getOrCreateUsersRow(PDO $pdo, string $sessionId, string $email, ?string $name = null): array {
  // 1) tenta por ID
  $q = $pdo->prepare("SELECT id, email, agente_ligado_waba, responder_todos_waba FROM users WHERE id = :id LIMIT 1");
  $q->execute([':id' => $sessionId]);
  $r = $q->fetch(PDO::FETCH_ASSOC);
  if ($r) return $r;

  // 2) tenta por email
  $q = $pdo->prepare("SELECT id, email, agente_ligado_waba, responder_todos_waba FROM users WHERE email = :e LIMIT 1");
  $q->execute([':e' => $email]);
  $r = $q->fetch(PDO::FETCH_ASSOC);
  if ($r) return $r;

  // 3) cria (forçando id da sessão para manter consistência com auth_users)
  $ins = $pdo->prepare("
    INSERT INTO users (id, email, name)
    VALUES (:id, :e, :n)
    ON CONFLICT (email) DO NOTHING
  ");
  $ins->execute([':id' => $sessionId, ':e' => $email, ':n' => $name]);

  // 4) busca de novo
  $q = $pdo->prepare("SELECT id, email, agente_ligado_waba, responder_todos_waba FROM users WHERE email = :e LIMIT 1");
  $q->execute([':e' => $email]);
  $r = $q->fetch(PDO::FETCH_ASSOC);
  if (!$r) throw new RuntimeException('Falha ao sincronizar usuário em `users`.');
  return $r;
}

function to_bool($v): bool {
  if (is_bool($v)) return $v;
  if (is_int($v)) return $v === 1;
  $s = strtolower(trim((string)$v));
  return in_array($s, ['1','true','yes','on','sim'], true);
}

function readJsonBody(): array {
  $raw = file_get_contents('php://input');
  if (!$raw) return [];
  $j = json_decode($raw, true);
  return is_array($j) ? $j : [];
}

function pickFromPostOrJson(string $key, array $json, $default = null) {
  if (isset($_POST[$key])) return $_POST[$key];
  if (array_key_exists($key, $json)) return $json[$key];
  return $default;
}

function t($v, int $max = 5000): ?string {
  if ($v === null) return null;
  $v = trim((string)$v);
  if ($v === '') return null;
  if (mb_strlen($v) > $max) $v = mb_substr($v, 0, $max);
  return $v;
}

function maskSecret(?string $v): ?string {
  if ($v === null) return null;
  $v = (string)$v;
  $len = strlen($v);
  if ($len === 0) return null;
  if ($len <= 10) return str_repeat('•', $len);
  return substr($v, 0, 6) . '…' . substr($v, -4);
}

/* =========================================================
 * Webhook único por usuário (auth_users.webhook_waba_evo_chat)
 * ======================================================= */

function make_webhook_token(int $bytes = 16): string {
  return bin2hex(random_bytes($bytes)); // 32 chars
}

function ensure_user_webhook(PDO $pdo, string $authUserId): string {
  // tenta ler o atual
  $st = $pdo->prepare("SELECT webhook_waba_evo_chat FROM auth_users WHERE id = :id LIMIT 1");
  $st->execute([':id' => $authUserId]);
  $current = trim((string)$st->fetchColumn());

  if ($current !== '') return $current;

  if (!defined('WABA_PROXY_BASE_URL') || !WABA_PROXY_BASE_URL) {
    throw new RuntimeException('WABA_PROXY_BASE_URL não configurada no config.php');
  }

  $token = make_webhook_token(16);
  $url = rtrim(WABA_PROXY_BASE_URL, '?') . '?w=' . $token;

  $up = $pdo->prepare("UPDATE auth_users SET webhook_waba_evo_chat = :url WHERE id = :id");
  $up->execute([':url' => $url, ':id' => $authUserId]);

  return $url;
}

/* =========================================================
 * auth_users helpers
 * ======================================================= */

function getUserAuthRow(PDO $pdo, string $userId): ?array {
  $s = $pdo->prepare("
    select
      id, email, plan,
      wa_conn_name,
      wa_phone_number_id,
      wa_waba_id,
      wa_access_token,
      wa_evolua_chat_token,
      wa_evolua_chat_user,
      wa_evolua_chat_pass,
      wa_phone_number,
      wa_connected_at,
      wa_updated_at,
      webhook_waba_evo_chat
    from auth_users
    where id = :id
    limit 1
  ");
  $s->execute([':id' => $userId]);
  $r = $s->fetch(PDO::FETCH_ASSOC);
  return $r ?: null;
}

function hasOfficialConn(?array $row): bool {
  if (!$row) return false;
  $hasToken = !empty($row['wa_evolua_chat_token']);
  $hasUser  = !empty($row['wa_evolua_chat_user']);
  $hasPass  = !empty($row['wa_evolua_chat_pass']);
  return $hasToken && $hasUser && $hasPass;
}

/**
 * =========================================================
 * CTRL+F: VALIDACAO_EVOLUA_CHAT (BACKEND)
 * =========================================================
 */
function validateEvoluaChatCredentials(string $email, string $pass): array {
  if (!function_exists('curl_init')) {
    return ['ok' => false, 'error' => 'cURL não está habilitado no PHP'];
  }

  $endpoints = [
    'https://api.evoluachat.com/auth/login',
    'https://app.evoluachat.com.br/api/auth/login',
  ];

  $payload = json_encode([
    'email'    => $email,
    'password' => $pass
  ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

  $lastError = 'Falha ao validar credenciais';

foreach ($endpoints as $url) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_POST           => true,
      CURLOPT_HTTPHEADER     => [
        'Content-Type: application/json',
        'Accept: application/json',
      ],
      CURLOPT_POSTFIELDS     => $payload,
      CURLOPT_TIMEOUT        => 15,
      CURLOPT_CONNECTTIMEOUT => 10,
    ]);

    $body  = curl_exec($ch);
    $errno = curl_errno($ch);
    $err   = curl_error($ch);
    $http  = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($errno) {
      $lastError = 'Falha ao conectar: ' . $err;
      continue;
    }

    $json = null;
    if (is_string($body) && $body !== '') $json = json_decode($body, true);

    if (($http === 200 || $http === 201) && is_array($json)) {
      return ['ok' => true];
    }

    // guarda o erro mas CONTINUA tentando o próximo endpoint
    if (in_array($http, [400, 401, 403], true)) {
      $lastError = 'usuário ou senha incorretos';
      continue;
    }

    $msg = 'Falha ao validar credenciais';
    if (is_array($json) && !empty($json['message'])) $msg = (string) $json['message'];
    $lastError = $msg . " (HTTP $http)";
  }

  return ['ok' => false, 'error' => $lastError];
}

$action = $_GET['action'] ?? '';

try {
  switch ($action) {

    case 'me': {
      $row  = getUserAuthRow($pdo, $USER_ID);
      $urow = getOrCreateUsersRow($pdo, $USER_ID, $EMAIL, $_SESSION['user']['name'] ?? null);

      if (!$row) jexit(['ok'=>false,'error'=>'Usuário não encontrado'], 404);

      // garante webhook único salvo no auth_users
      $wh = ensure_user_webhook($pdo, $USER_ID);

      $tokenMasked       = !empty($row['wa_access_token']) ? maskSecret((string)$row['wa_access_token']) : null;
      $evoluaTokenMasked = !empty($row['wa_evolua_chat_token']) ? maskSecret((string)$row['wa_evolua_chat_token']) : null;
      $evoluaUserMasked  = !empty($row['wa_evolua_chat_user']) ? maskSecret((string)$row['wa_evolua_chat_user']) : null;
      $evoluaPassMasked  = !empty($row['wa_evolua_chat_pass']) ? maskSecret((string)$row['wa_evolua_chat_pass']) : null;

      jexit([
        'ok' => true,
        'user' => [
          'id'    => $row['id'],
          'email' => $row['email'],
          'plan'  => $row['plan'],
        ],
        'connected' => hasOfficialConn($row),
        'data' => [
          'name'                  => $row['wa_conn_name'] ?? null,
          'phone_number_id'       => $row['wa_phone_number_id'] ?? null,
          'waba_id'               => $row['wa_waba_id'] ?? null,
          'token_masked'          => $tokenMasked,
          'evolua_token_masked'   => $evoluaTokenMasked,
          'evolua_user_masked'    => $evoluaUserMasked,
          'evolua_pass_masked'    => $evoluaPassMasked,
          'phone_number'          => $row['wa_phone_number'] ?? null,
          'connected_at'          => $row['wa_connected_at'] ?? null,
          'updated_at'            => $row['wa_updated_at'] ?? null,
          'agente_ligado_waba'    => !empty($urow['agente_ligado_waba']),
          'responder_todos_waba'  => !empty($urow['responder_todos_waba']),
          'webhook_waba_evo_chat' => $wh,
        ]
      ]);
    }

    case 'validate_evolua': {
      $json = readJsonBody();
      $email = t(pickFromPostOrJson('email', $json), 255);
      $pass  = t(pickFromPostOrJson('password', $json), 255);

      if (!$email || !$pass) jexit(['ok'=>false,'error'=>'Informe email e senha para validar'], 400);

      $res = validateEvoluaChatCredentials($email, $pass);
      if (!empty($res['ok'])) jexit(['ok'=>true]);

      jexit(['ok'=>false,'error'=>$res['error'] ?? 'usuário ou senha incorretos'], 401);
    }

    case 'save': {
      $row = getUserAuthRow($pdo, $USER_ID);
      if (!$row) jexit(['ok'=>false,'error'=>'Usuário não encontrado'], 404);

      $json = readJsonBody();

      $name            = t(pickFromPostOrJson('name', $json), 120);
      $phoneNumberId   = t(pickFromPostOrJson('phone_number_id', $json), 120);
      $wabaId          = t(pickFromPostOrJson('waba_id', $json), 120);
      $accessToken     = t(pickFromPostOrJson('access_token', $json), 5000);
      $phoneNumber     = t(pickFromPostOrJson('phone_number', $json), 50);
      $evoluaChatToken = t(pickFromPostOrJson('evolua_chat_token', $json), 5000);
      $evoluaChatUser  = t(pickFromPostOrJson('user_evolua_chat', $json), 255);
      $evoluaChatPass  = t(pickFromPostOrJson('pass_evolua_chat', $json), 255);

      $pdo->beginTransaction();

      $sql = "
        update auth_users
           set wa_conn_name         = :n,
               wa_phone_number_id   = :pnid,
               wa_waba_id           = :waba,
               wa_access_token      = :tok,
               wa_evolua_chat_token = :etok,
               wa_evolua_chat_user  = :euser,
               wa_evolua_chat_pass  = :epass,
               wa_phone_number      = :phone,
               wa_updated_at        = now(),
               wa_connected_at      = COALESCE(wa_connected_at, now())
         where id = :id
      ";
      $st = $pdo->prepare($sql);
      $st->execute([
        ':n'     => $name,
        ':pnid'  => $phoneNumberId,
        ':waba'  => $wabaId,
        ':tok'   => $accessToken,
        ':etok'  => $evoluaChatToken,
        ':euser' => $evoluaChatUser,
        ':epass' => $evoluaChatPass,
        ':phone' => $phoneNumber,
        ':id'    => $USER_ID,
      ]);

      // garante webhook criado ao salvar também
      $wh = ensure_user_webhook($pdo, $USER_ID);

      $pdo->commit();

      jexit(['ok'=>true, 'webhook_waba_evo_chat' => $wh]);
    }

    case 'delete': {
      $row = getUserAuthRow($pdo, $USER_ID);
      if (!$row) jexit(['ok'=>false,'error'=>'Usuário não encontrado'], 404);

      $pdo->prepare("
        update auth_users
           set wa_conn_name         = null,
               wa_phone_number_id   = null,
               wa_waba_id           = null,
               wa_access_token      = null,
               wa_evolua_chat_token = null,
               wa_evolua_chat_user  = null,
               wa_evolua_chat_pass  = null,
               wa_phone_number      = null,
               wa_connected_at      = null,
               wa_updated_at        = now()
         where id = :id
      ")->execute([':id' => $USER_ID]);

      jexit(['ok'=>true]);
    }

    case 'waba_settings.save': {
      $urow = getOrCreateUsersRow($pdo, $USER_ID, $EMAIL, $_SESSION['user']['name'] ?? null);
      $json = readJsonBody();

      $agenteBool = to_bool(pickFromPostOrJson('agente_ligado_waba', $json, false));
      $respBool   = to_bool(pickFromPostOrJson('responder_todos_waba', $json, false));

      $a = $agenteBool ? 1 : 0;
      $r = $respBool ? 1 : 0;

      try { $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); } catch (Throwable $e) {}

      $st = $pdo->prepare("
        UPDATE users
           SET agente_ligado_waba   = CASE WHEN :a = 1 THEN TRUE ELSE FALSE END,
               responder_todos_waba = CASE WHEN :r = 1 THEN TRUE ELSE FALSE END,
               updated_at = NOW()
         WHERE id = :id
      ");

      $st->bindValue(':a',  $a, PDO::PARAM_INT);
      $st->bindValue(':r',  $r, PDO::PARAM_INT);
      $st->bindValue(':id', $urow['id'], PDO::PARAM_STR);
      $st->execute();

      jexit([
        'ok' => true,
        'data' => [
          'agente_ligado_waba' => (bool)$a,
          'responder_todos_waba' => (bool)$r,
        ]
      ]);
    }

    default:
      jexit(['ok'=>false,'error'=>'Ação inválida'], 400);
  }

} catch (Throwable $e) {
  try { if ($pdo->inTransaction()) $pdo->rollBack(); } catch (Throwable $x) {}
  jexit(['ok'=>false,'error'=>'Exceção: '.$e->getMessage()], 500);
}
