<?php
// LOG DEBUG
$debug_trace = [];
function debug_log($msg)
{
  global $debug_trace;
  $logFile = __DIR__ . '/debug_pix.log';
  $time = date('Y-m-d H:i:s');
  // Se for array/object, converte pra string
  if (!is_string($msg)) {
    $msg = json_encode($msg, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
  }
  $line = "[$time] $msg";
  $debug_trace[] = $line;
  @file_put_contents($logFile, $line . PHP_EOL, FILE_APPEND);
}

debug_log("Script gerar.php iniciado.");

require '../config.php';
debug_log("Config.php incluido com sucesso.");

ini_set('display_errors', 0); // Evitar que warnings quebrem o JSON
error_reporting(E_ALL);
header('Content-Type: application/json');

// ====== SESSÃO PRIMEIRO (vamos ler UTMs da sessão) ======
if (session_status() === PHP_SESSION_NONE)
  session_start();
date_default_timezone_set('America/Sao_Paulo');

// 🔎 Chaves de metas que poderemos limpar DEPOIS de ler
$metaKeys = [
  'utm_source',
  'utm_medium',
  'utm_campaign',
  'utm_content',
  'utm_term',
  'campaign_id',
  'adset_id',
  'ad_id',
  'placement',
  'fbclid',
  'gclid',
  'msclkid',
  'ttclid'
];

// ====== CONFIG ======
$paradise_secret = 'sk_c8593ee9ca73ae48b9f38215e670403baff754b9034080a15d87890e3aeb5c07'; // Chave Paradise
$PIX_DB_PATH = __DIR__ . '/dutty.json'; // Mantém o mesmo arquivo de banco por compatibilidade
$BASE_URL = $url_raiz ?? ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http') . '://' . ($_SERVER['HTTP_HOST'] ?? 'localhost') . '/');

// ====== UTIL ======
function randCpf11(): string
{
  $s = '';
  for ($i = 0; $i < 11; $i++) {
    $s .= random_int(0, 9);
  }
  return $s;
}

function pow_name(?string $gender = null): string
{
  $firstMasc = ['Marcos', 'Pedro', 'Lucas', 'Rafael', 'Gustavo', 'Bruno', 'Felipe', 'Thiago', 'Paulo', 'Henrique', 'Matheus', 'Diego', 'Leandro', 'André', 'Vitor', 'Caio', 'Fábio', 'Renato', 'João', 'Carlos'];
  $firstFem = ['Ana', 'Mariana', 'Juliana', 'Camila', 'Larissa', 'Bruna', 'Fernanda', 'Patrícia', 'Aline', 'Carla', 'Beatriz', 'Letícia', 'Renata', 'Paula', 'Vanessa', 'Bianca', 'Tatiane', 'Roberta', 'Priscila', 'Caroline'];
  $lastNames = ['Silva', 'Souza', 'Oliveira', 'Santos', 'Pereira', 'Almeida', 'Ferreira', 'Rodrigues', 'Lima', 'Carvalho', 'Gomes', 'Martins', 'Barbosa', 'Ribeiro', 'Teixeira', 'Rocha', 'Dias', 'Moreira', 'Correia', 'Cardoso', 'Araújo', 'Monteiro', 'Melo', 'Moura', 'Batista', 'Nunes', 'Costa', 'Campos', 'Barros'];

  // define gênero
  $gender = $gender === 'M' || $gender === 'F' ? $gender : (random_int(0, 1) ? 'M' : 'F');

  $first = $gender === 'M'
    ? $firstMasc[random_int(0, count($firstMasc) - 1)]
    : $firstFem[random_int(0, count($firstFem) - 1)];

  // sempre pelo menos 1 sobrenome, ~40% chance de ter 2 sobrenomes
  $last1 = $lastNames[random_int(0, count($lastNames) - 1)];
  $fullLast = $last1;
  if (random_int(1, 100) <= 40) {
    $last2 = $lastNames[random_int(0, count($lastNames) - 1)];
    if ($last2 !== $last1)
      $fullLast = $last1 . ' ' . $last2;
  }

  return $first . ' ' . $fullLast;
}

/**
 * Gera um e-mail @gmail.com realista a partir de um nome.
 * Se $name for null, gera um nome internamente.
 * @param string|null $name Nome completo (opcional)
 * @return string Ex: "camila.souza.482@gmail.com"
 */
function pow_email(?string $name = null): string
{
  if (empty($name)) {
    $name = pow_name();
  }

  // pega primeiro e último pedaço do nome
  $parts = preg_split('/\s+/', trim($name));
  $first = $parts[0] ?? 'user';
  $last = $parts[count($parts) - 1] ?? 'cliente';

  $firstNorm = _pow_normalize($first);
  $lastNorm = _pow_normalize($last);

  // sufixo curto pra reduzir colisões (2-4 dígitos)
  $suffix = random_int(10, 9999);

  // padrões comuns de local-part
  $choice = random_int(1, 3);
  switch ($choice) {
    case 1:
      // nome.sobrenome.123
      $local = "{$firstNorm}.{$lastNorm}.{$suffix}";
      break;
    case 2:
      // nome_sobrenome123
      $local = "{$firstNorm}_{$lastNorm}{$suffix}";
      break;
    case 3:
    default:
      // inicial.sobrenome123  (ex: j.silva482)
      $initial = substr($firstNorm, 0, 1);
      $local = "{$initial}.{$lastNorm}{$suffix}";
      break;
  }

  // forçar lowercase e gmail
  return strtolower($local) . '@gmail.com';
}

/* ---------- helpers internos ---------- */

function _pow_normalize(string $s): string
{
  // tenta remover acentos; se iconv não disponível, usa fallback simples
  $out = @iconv('UTF-8', 'ASCII//TRANSLIT', $s);
  if ($out === false)
    $out = $s;
  $out = strtolower($out);
  // remove tudo que não for a-z0-9
  $out = preg_replace('/[^a-z0-9]+/i', '', $out);
  if ($out === '' || $out === null)
    $out = 'user';
  return $out;
}

/** Acrescenta um registro ao “banco” JSON com LOCK */
function db_append(array $row, ?string $path = null): bool
{
  global $PIX_DB_PATH;
  $path = $path ?: ($PIX_DB_PATH ?? (__DIR__ . '/dutty.json'));
  if (!file_exists($path))
    file_put_contents($path, "[]", LOCK_EX);

  $fp = fopen($path, 'c+');
  if ($fp === false)
    return false;

  $ok = false;
  if (flock($fp, LOCK_EX)) {
    $size = filesize($path);
    rewind($fp);
    $json = $size > 0 ? fread($fp, $size) : '[]';
    $data = json_decode($json, true);
    if (!is_array($data))
      $data = [];
    $data[] = $row;

    $out = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
    ftruncate($fp, 0);
    rewind($fp);
    $ok = fwrite($fp, $out) !== false;
    fflush($fp);
    flock($fp, LOCK_UN);
  }
  fclose($fp);
  return $ok;
}

// 🔹 PEGA AS METAS DA SESSÃO
$meta = [];
foreach ($metaKeys as $k) {
  if (!empty($_SESSION[$k])) {
    $val = preg_replace('/[\x00-\x1F\x7F]/u', '', trim((string) $_SESSION[$k]));
    $meta[$k] = mb_substr($val, 0, 512);
  }
}
$meta['_meta_source'] = 'SESSION';


function generate_cpf(bool $formatted = true): string
{
  // Gera os 9 primeiros dígitos aleatórios, evitando sequências repetidas simples
  do {
    $n = [];
    for ($i = 0; $i < 9; $i++) {
      $n[] = random_int(0, 9);
    }
    // evita CPFs como 000000000, 111111111, etc.
    $all_equal = count(array_unique($n)) === 1;
  } while ($all_equal);

  // calcula 1º dígito verificador (d10)
  $sum = 0;
  for ($i = 0; $i < 9; $i++) {
    $sum += $n[$i] * (10 - $i);
  }
  $d10 = ($sum * 10) % 11;
  if ($d10 === 10)
    $d10 = 0;
  $n[] = $d10;

  // calcula 2º dígito verificador (d11)
  $sum = 0;
  for ($i = 0; $i < 10; $i++) {
    $sum += $n[$i] * (11 - $i);
  }
  $d11 = ($sum * 10) % 11;
  if ($d11 === 10)
    $d11 = 0;
  $n[] = $d11;

  $cpf = implode('', $n); // 11 dígitos

  if ($formatted) {
    return substr($cpf, 0, 3) . '.' . substr($cpf, 3, 3) . '.' . substr($cpf, 6, 3) . '-' . substr($cpf, 9, 2);
  }
  return $cpf;
}

/**
 * Valida um CPF (aceita com ou sem formatação).
 *
 * @param string $cpf
 * @return bool
 */
function validate_cpf(string $cpf): bool
{
  // remove tudo que nao é dígito
  $cpf = preg_replace('/\D/', '', (string) $cpf);

  if (strlen($cpf) !== 11)
    return false;

  // elimina CPFs de dígitos repetidos (ex: 00000000000)
  if (preg_match('/^([0-9])\1{10}$/', $cpf))
    return false;

  // calcula primeiro dígito verificador
  $sum = 0;
  for ($i = 0; $i < 9; $i++) {
    $sum += (int) $cpf[$i] * (10 - $i);
  }
  $d10 = ($sum * 10) % 11;
  if ($d10 === 10)
    $d10 = 0;
  if ($d10 !== (int) $cpf[9])
    return false;

  // calcula segundo dígito verificador
  $sum = 0;
  for ($i = 0; $i < 10; $i++) {
    $sum += (int) $cpf[$i] * (11 - $i);
  }
  $d11 = ($sum * 10) % 11;
  if ($d11 === 10)
    $d11 = 0;
  if ($d11 !== (int) $cpf[10])
    return false;

  return true;
}


// ====== VALIDA ENTRADA ======
$priceCents = isset($_GET['price_cents']) ? (int) $_GET['price_cents'] : 0;
debug_log("Iniciando requisicao. PriceCents: $priceCents");
if ($priceCents < 100) {
  debug_log("ERRO: PriceCents menor que 100");
  http_response_code(400);
  echo json_encode(['ok' => false, 'error' => 'price_cents mínimo é 100 (R$ 1,00)', 'trace' => $debug_trace]);
  exit;
}

$name = pow_name();              // "Paula Souza" (por exemplo)
$email = pow_email($name);        // "paula.souza.482@gmail.com"

// ou gerar apenas email (ele vai criar um nome interno)
$email2 = pow_email();            // "bruno.silva123@gmail.com"



// ====== MONTA DADOS (apenas preço real; resto pode ser aleatório) ======
$rand = random_int(1000, 999999);
$lead = [
  'name' => '' . $name . '',
  'email' => '' . $email . '',
  'document' => generate_cpf(),
  'phone' => '1999' . random_int(100000, 999999),
];

$data = [
  'method' => 'pix',
  'lead' => $lead,
  'items' => [
    [
      'title' => 'Pagamento PIX',
      'price_cents' => $priceCents,
      'qty' => 1,
      'externalRef' => (string) $rand,
    ]
  ],
  'amounts' => ['total_cents' => $priceCents],
];

// ====== CHAMA PARADISE ======
try {
  // UTMs para tracking, se necessario
  $tracking = [
    'utm_source' => $meta['utm_source'] ?? 'api',
    'utm_medium' => $meta['utm_medium'] ?? '',
    'utm_campaign' => $meta['utm_campaign'] ?? '',
    'utm_content' => $meta['utm_content'] ?? '',
    'utm_term' => $meta['utm_term'] ?? '',
  ];

  debug_log("Enviando para Paradise. Data: " . json_encode($data));
  $resp = paradise_create_transaction($paradise_secret, $data, $tracking);
  debug_log("Resposta Paradise: " . json_encode($resp));

  if (!is_array($resp)) {
    throw new Exception('Resposta inválida da Paradise');
  }

  if (isset($resp['status']) && $resp['status'] === 'error') {
    throw new Exception($resp['message'] ?? 'Erro desconhecido na Paradise');
  }

  // Extrai conforme a documentação Paradise
  $transactionId = $resp['transaction_id'] ?? null;
  $externalId = $resp['id'] ?? null; // ID espelho da referencia
  $status = strtoupper((string) ($resp['status'] ?? 'PENDING'));

  // O QR Code vem no campo 'qr_code' (copia e cola)
  $emv = $resp['qr_code'] ?? null;

  // A imagem base64 vem no campo 'qr_code_base64'
  $qrImg = $resp['qr_code_base64'] ?? null;

  if (!$transactionId || !$emv) {
    throw new Exception('Resposta sem qr_code ou transaction_id: ' . json_encode($resp, JSON_UNESCAPED_UNICODE));
  }

  // para compatibilidade com seu add_utm()
  $amountCents = (int) preg_replace('/\D+/', '', (string) $priceCents);

  // Disparo opcional no UTMify, se existir sua função
  if (function_exists('add_utm')) {
    try {
      $resU = add_utm(
        $lead['name'],
        $lead['document'],
        $lead['email'],
        $lead['phone'],
        $amountCents,
        $meta['utm_source'] ?? null,
        $meta['utm_campaign'] ?? null,
        $meta['utm_medium'] ?? null,
        $meta['utm_content'] ?? null,
        $meta['utm_term'] ?? null,
        $transactionId, // Usando transaction_id numérico da Paradise ou o ID externo? Geralmente o interno é melhor para rastreio se for único
        $utmfy_token // do seu config.php
      );
      @file_put_contents(
        __DIR__ . '/utmify_dispatch.log',
        '[' . date('Y-m-d H:i:s') . "] TX=$transactionId RES=" . json_encode($resU, JSON_UNESCAPED_UNICODE) . "\n",
        FILE_APPEND
      );
    } catch (\Throwable $e) {
      @file_put_contents(
        __DIR__ . '/utmify_dispatch.log',
        '[' . date('Y-m-d H:i:s') . "] TX=$transactionId ERROR=" . $e->getMessage() . "\n",
        FILE_APPEND
      );
    }
  }

  // grava no JSON local
  db_append([
    'ts' => date('Y-m-d H:i:s'),
    'type' => 'success',
    'transactionId' => $transactionId,
    'external_id' => $externalId,
    'valor_centavos' => $priceCents,
    'lead' => $lead,
    'meta' => $meta,
    'resp' => $resp
  ]);

  echo json_encode([
    'ok' => true,
    'external_id' => $transactionId, // Frontend espera o ID para consultar status depois
    'qrcode' => $emv,     // copia-e-cola
    'qrcode_img' => $qrImg,
    'status' => $status,
  ]);
  exit;

} catch (Exception $e) {
  $errMsg = $e->getMessage();
  debug_log("EXCEPTION CATCH: $errMsg");
  db_append([
    'ts' => date('Y-m-d H:i:s'),
    'type' => 'error',
    'msg' => $errMsg,
    'price_cents' => $priceCents,
    'meta' => $meta,
    'payload_try' => $data ?? null
  ]);

  http_response_code(400);
  echo json_encode(['ok' => false, 'error' => $errMsg, 'trace' => $debug_trace]);
  exit;
}

/**
 * Chama a API PIX da Paradise
 * Endpoint: POST https://multi.paradisepags.com/api/v1/transaction.php
 */
function paradise_create_transaction(string $secret_key, array $data, array $tracking = []): array
{
  if (!$secret_key) {
    return ['error' => 'Chave da Paradise ausente'];
  }

  // Sanitiza documentos/telefone
  $doc = isset($data['lead']['document']) ? preg_replace('/\D+/', '', $data['lead']['document']) : '';
  $phone = isset($data['lead']['phone']) ? preg_replace('/\D+/', '', $data['lead']['phone']) : '';

  // Formato BR para telefone: 55 + DDD + Numero. Se já tiver 55 ou for curto, tenta ajustar.
  // A API pede "Telefone do cliente com DDD (apenas números)". Não especifica DDI (55). 
  // O exemplo é "11999999999" (11 digitos). Vamos garantir 11 digitos min.

  $amount = $data['amounts']['total_cents'] ?? 0;
  $description = $data['items'][0]['title'] ?? 'Compra';
  $reference = 'REF-' . uniqid();

  $payload = [
    'amount' => $amount,
    'description' => $description,
    'reference' => $reference,
    // ID DO PRODUTO: Substitua pelo hash do seu produto na Paradise
    'productHash' => 'prod_0744f162a067935f',
    'customer' => [
      'name' => $data['lead']['name'],
      'email' => $data['lead']['email'],
      'document' => $doc,
      'phone' => $phone
    ],
    'tracking' => $tracking
  ];

  $url = 'https://multi.paradisepags.com/api/v1/transaction.php';

  $ch = curl_init($url);
  curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
    CURLOPT_HTTPHEADER => [
      'Content-Type: application/json',
      'X-API-Key: ' . $secret_key
    ],
    CURLOPT_TIMEOUT => 30,
    CURLOPT_CONNECTTIMEOUT => 10,
  ]);

  $response = curl_exec($ch);
  $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  $err = curl_error($ch);
  curl_close($ch);

  if ($err) {
    return ['error' => 'Erro de rede: ' . $err];
  }

  $resp = json_decode($response, true);
  if (!is_array($resp)) {
    return ['error' => 'Resposta inválida da Paradise (HTTP ' . $status . '): ' . $response];
  }

  // Se HTTP for erro
  if ($status < 200 || $status >= 300) {
    $msg = $resp['message'] ?? ($resp['error'] ?? 'Erro desconhecido HTTP ' . $status);
    return ['error' => $msg];
  }

  return $resp;
}

// ===============================
// UTMify (mantido como no seu código)
// ===============================
function add_utm($nome, $cpf, $email, $telefone, $valor, $utm_source, $utm_campaign, $utm_medium, $utm_content, $utm_term, $token, $utm_token)
{
  $apiUrl = 'https://api.utmify.com.br/api-credentials/orders';
  $apiToken = $utm_token;

  $amount = $valor; // em centavos? (mantido como no seu código)
  $amount = number_format((float) str_replace(',', '.', $valor), 2, '.', '');

  $gatewayFee = 0;
  $userCommission = $amount - $gatewayFee;
  $amountCents = (int) preg_replace('/\D+/', '', (string) $valor);

  $createdAt = date('Y-m-d H:i:s');

  $telefone_limpo = preg_replace('/\D/', '', $telefone);
  $cpf_limpo = preg_replace('/\D/', '', $cpf);

  $payload = [
    "orderId" => rand(10000, 19999),
    "platform" => "Pix",
    "paymentMethod" => "pix",
    "status" => "waiting_payment",
    "createdAt" => $createdAt,
    "approvedDate" => date("Y-m-d H:i:s"),
    "refundedAt" => null,
    "customer" => [
      "name" => (string) $nome,
      "email" => (string) $email,
      "phone" => (string) $telefone_limpo,
      "document" => (string) $cpf_limpo,
      "country" => "BR"
    ],
    "products" => [
      [
        "id" => "produto-externo",
        "name" => "Produto Externo",
        "planId" => 11,
        "planName" => "externo",
        "quantity" => 1,
        "priceInCents" => $amount
      ]
    ],
    "trackingParameters" => [
      "utm_source" => $utm_source,
      "utm_campaign" => $utm_campaign,
      "utm_medium" => $utm_medium,
      "utm_content" => $utm_content,
      "utm_term" => $utm_term
    ],
    "commission" => [
      "totalPriceInCents" => $amountCents,
      "gatewayFeeInCents" => $gatewayFee,
      "userCommissionInCents" => $amountCents
    ],
    "isTest" => false
  ];

  $ch = curl_init($apiUrl);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'x-api-token: ' . $apiToken
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));

  $response = curl_exec($ch);
  curl_close($ch);

  return ['response' => $response]; // para log opcional
}
