<?php
require "../config.php";
ini_set('display_errors', 1);
error_reporting(E_ALL);
header('Content-Type: application/json');

// ===== Config / Paths =====

// ===== Config / Paths =====
const PIX_DB_PATH = __DIR__ . '/dutty.json';   // fallback local (mesmo “banco” usado no gerar.php)
const UTM_SENT_DIR = __DIR__ . '/utm_sent';    // marca envios já feitos p/ evitar duplicidade

// ===== Helpers =====
function load_db(string $path): array
{
    if (!file_exists($path) || filesize($path) === 0)
        return [];
    $json = file_get_contents($path);
    $data = json_decode($json, true);
    return is_array($data) ? $data : [];
}

/** Normaliza status para o front (APPROVED = pago) */
function map_status_for_front(?string $raw): string
{
    $raw = strtoupper(trim((string) $raw));
    // Paradise usa 'paid' em lowercase, mas convertemos pra UPPER.
    if (in_array($raw, ['COMPLETED', 'PAID', 'APPROVED', 'SUCCEEDED', 'CONCLUDED', 'AUTHORIZED'], true))
        return 'APPROVED';
    if (in_array($raw, ['PENDING', 'WAITING_PAYMENT', 'PENDING_PAYMENT'], true))
        return 'PENDING';
    if (in_array($raw, ['REFUSED', 'DECLINED'], true))
        return 'DECLINED';
    if (in_array($raw, ['CANCELED', 'CANCELLED'], true))
        return 'CANCELLED';
    return $raw !== '' ? $raw : 'UNKNOWN';
}

/** GET JSON com cURL */
function http_get_json(string $url): array
{
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_TIMEOUT => 20,
        CURLOPT_CONNECTTIMEOUT => 8,
        CURLOPT_HTTPGET => true,
        CURLOPT_HTTPHEADER => ['Accept: application/json'],
    ]);
    $res = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $err = curl_error($ch);
    curl_close($ch);

    if ($err)
        return ['error' => 'Erro de rede: ' . $err, '_http' => $code];
    $json = json_decode($res, true);
    if (!is_array($json))
        $json = ['error' => 'Resposta inválida: ' . $res, '_http' => $code];
    if ($code < 200 || $code >= 300) {
        if (!isset($json['error']))
            $json['error'] = 'HTTP ' . $code;
        $json['_http'] = $code;
    }
    return $json;
}

/** Consulta status na Paradise (por ID ou REF) */
function paradise_status(string $id): array
{
    // Se conter letras, assume que é external_id, se for numérico, id interno.
    // Mas o gerador retorna o ID numérico como "transaction_id" ou "external_id" pro front?
    // O front chama com ?id=...
    // Na Paradise:
    // endpoint /api/v1/query.php?action=get_transaction&id={id}  (ID numérico)
    // endpoint /api/v1/query.php?action=list_transactions&external_id={ref} (Reference string)

    // Vamos tentar detectar. Se for puramente numérico, tenta por ID.
    // Se tiver traço ou letras, tenta por external_id.

    // O "id" salvo no front vem do campo `transaction_id` (numérico) ou `id` (ref) do gerar.php?
    // Verificando gerar.php: echo json_encode(['external_id' => $transactionId ...]) 
    // E $transactionId na resposta da Paradise é o ID numérico (ex: 158).

    $action = 'get_transaction';
    $param = 'id';

    // Se não for numérico, assume busca por referência
    if (!ctype_digit((string) $id)) {
        $action = 'list_transactions';
        $param = 'external_id';
    }

    $url = "https://multi.paradisepags.com/api/v1/query.php?action={$action}&{$param}=" . rawurlencode($id);

    // A query da Paradise é aberta ou precisa de API Key?
    // A doc diz "Recurso: Consultas" e lista GET. Geralmente precisa de Auth. 
    // O exemplo anterior de POST usou X-API-Key. Vamos usar aqui também por segurança.
    // Mas a função http_get_json não suporta headers customizados agora.
    // Vamos alterar http_get_json ou criar uma especifica.

    // Ajustando para passar a chave Global (definida no config ou variável)
    // Precisamos da $paradise_secret aqui.
    global $paradise_secret;
    // Fallback se não estiver global
    if (empty($paradise_secret)) {
        $paradise_secret = 'sk_c8593ee9ca73ae48b9f38215e670403baff754b9034080a15d87890e3aeb5c07';
    }

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_TIMEOUT => 20,
        CURLOPT_CONNECTTIMEOUT => 8,
        CURLOPT_HTTPGET => true,
        CURLOPT_HTTPHEADER => [
            'Accept: application/json',
            'X-API-Key: ' . $paradise_secret
        ],
    ]);
    $res = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $err = curl_error($ch);
    curl_close($ch);

    if ($err)
        return ['error' => 'Erro de rede: ' . $err, '_http' => $code];
    $json = json_decode($res, true);

    // Se for list_transactions, retorna array. Pegamos o primeiro.
    if ($action === 'list_transactions' && is_array($json) && isset($json[0])) {
        return $json[0];
    }

    if (!is_array($json))
        $json = ['error' => 'Resposta inválida: ' . $res, '_http' => $code];
    if ($code < 200 || $code >= 300) {
        if (!isset($json['error']))
            $json['error'] = 'HTTP ' . $code;
        $json['_http'] = $code;
    }
    return $json;
}

/** Encontra o registro completo do TX no dutty.json */
function find_db_row_by_tx(string $id): ?array
{
    $db = load_db(PIX_DB_PATH);
    for ($i = count($db) - 1; $i >= 0; $i--) {
        $row = $db[$i];
        if (!is_array($row))
            continue;
        $txRow = (string) ($row['transactionId'] ?? '');
        $txExt = (string) ($row['external_id'] ?? ''); // adicionado external_id
        $txResp = '';
        if (isset($row['resp']) && is_array($row['resp'])) {
            $txResp = (string) ($row['resp']['id'] ?? ($row['resp']['transaction_id'] ?? ''));
        }
        if ($txRow === $id || $txResp === $id || $txExt === $id) {
            return $row;
        }
    }
    return null;
}

/** Fallback: procura no JSON local pelo transactionId (string/UUID) */
function fallback_local(string $id): array
{
    $row = find_db_row_by_tx($id);
    if ($row) {
        $raw = '';
        // Tenta pegar status da resposta salva ou do registro
        if (isset($row['resp']) && is_array($row['resp'])) {
            $raw = (string) ($row['resp']['status'] ?? '');
        }
        if ($raw === '' && isset($row['status'])) {
            $raw = (string) $row['status'];
        }
        return [
            'source' => 'cache',
            'raw_status' => $raw,
            'status' => map_status_for_front($raw),
            'transaction_id' => $id,
            'paidAt' => null,
            'success' => true,
            'found' => true,
        ];
    }
    return [
        'source' => 'cache',
        'raw_status' => null,
        'status' => 'UNKNOWN',
        'transaction_id' => $id,
        'paidAt' => null,
        'success' => true,
        'found' => false,
    ];
}

/** Cria diretório de flags se necessário */
function ensure_dir(string $dir): void
{
    if (!is_dir($dir)) {
        @mkdir($dir, 0775, true);
    }
}

/** Caminho do flag de envio UTM por transação */
function utm_flag_path(string $tx): string
{
    $safe = preg_replace('/[^A-Za-z0-9_.-]/', '_', $tx);
    return UTM_SENT_DIR . '/' . $safe . '.ok';
}

/** Dispara add_utm uma única vez por transação (idempotente via arquivo-flag) */
function maybe_dispatch_utm(string $txId, ?array $row, ?string $utmfy_token): void
{
    if (!$row)
        return;
    if (!$utmfy_token)
        return;

    ensure_dir(UTM_SENT_DIR);
    $flag = utm_flag_path($txId);
    if (file_exists($flag))
        return; // já enviado

    // Extrai dados do "banco"
    $lead = $row['lead'] ?? [];
    $nome = (string) ($lead['name'] ?? '');
    $cpf = (string) ($lead['document'] ?? '');
    $email = (string) ($lead['email'] ?? '');
    $fone = (string) ($lead['phone'] ?? '');
    $valor = (int) ($row['valor_centavos'] ?? 0);

    $meta = $row['meta'] ?? [];
    $utm_source = $meta['utm_source'] ?? null;
    $utm_campaign = $meta['utm_campaign'] ?? null;
    $utm_medium = $meta['utm_medium'] ?? null;
    $utm_content = $meta['utm_content'] ?? null;
    $utm_term = $meta['utm_term'] ?? null;

    // Garante existência da função add_utm (usa definição abaixo se necessário)
    if (!function_exists('add_utm')) {
        // define fallback (a mesma que você enviou)
        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
            $amount = number_format((float) str_replace(',', '.', $valor / 100), 2, '.', '');

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

            $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" => "paid",
                "createdAt" => $createdAt,
                "approvedDate" => date("Y-m-d H:i:s"),
                "refundedAt" => null,
                "customer" => [
                    "name" => "" . $nome . "",
                    "email" => "" . $email . "",
                    "phone" => "" . $telefone_limpo . "",
                    "document" => "" . $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);
            // Se quiser logar: file_put_contents(__DIR__.'/utmify_dispatch.log', '['.date('c')."] TX=$token RES=".$response."\n", FILE_APPEND);
            curl_close($ch);
        }
    }

    // Dispara
    try {
        add_utm($nome, $cpf, $email, $fone, $valor, $utm_source, $utm_campaign, $utm_medium, $utm_content, $utm_term, $txId, $utmfy_token);
        // marca flag para evitar duplicidade
        @file_put_contents($flag, date('c'));
    } catch (\Throwable $e) {
        // log opcional de erro
        @file_put_contents(__DIR__ . '/utmify_dispatch.log', '[' . date('c') . "] TX=$txId ERROR=" . $e->getMessage() . "\n", FILE_APPEND);
    }
}

// ===== Entrada =====
$id = isset($_GET['id']) ? trim($_GET['id']) : (isset($_GET['transactionId']) ? trim($_GET['transactionId']) : '');
if ($id === '') {
    http_response_code(400);
    echo json_encode(['success' => false, 'error' => 'Parâmetro id vazio']);
    exit;
}

// Config chave Paradise (Mesma do gerar.php)
$paradise_secret = 'sk_c8593ee9ca73ae48b9f38215e670403baff754b9034080a15d87890e3aeb5c07';

// ===== Chama API da Paradise =====
$api = paradise_status($id);

// Erros de API
if (isset($api['error']) && !isset($api['status'])) { // Paradise retorna erro como campo top-level ou dentro? O exemplo de sucesso não tem error.
    $msg = (string) $api['error'];

    // transação não encontrada
    if (strpos(mb_strtolower($msg), 'não encontrada') !== false) {
        $fb = fallback_local($id);
        echo json_encode($fb);
        exit;
    }

    echo json_encode([
        'success' => true,
        'status' => 'UNKNOWN',
        'raw_status' => null,
        'transaction_id' => $id,
        'error' => $msg,
        'source' => 'api',
    ]);
    exit;
}

// Sucesso API
// Paradise retorna "status": "pending" | "paid" ? O exemplo diz "status": "pending" (lower)
$raw = isset($api['status']) ? (string) $api['status'] : '';
// Paradise não parece retornar paidAt explicito no GET, mas tem "updated_at".
$paid = $api['updated_at'] ?? null;

$mapped = map_status_for_front($raw);

// === NOVO: se pago/aprovado, dispara UTMify uma vez ===
if ($mapped === 'APPROVED') {
    // carrega dados do dutty.json para montar o payload do UTMify
    $row = find_db_row_by_tx($id);
    // token do UTMify vem do config (ex.: $utmfy_token)
    $utm_token = isset($utmfy_token) ? $utmfy_token : null;
    maybe_dispatch_utm($id, $row, $utm_token);

    // Opcional: Atualizar status no banco local também?
    // Seria bom para cache, mas não estritamente necessário se o fluxo principal é front -> api status.
}

echo json_encode([
    'success' => true,
    'found' => true,
    'status' => $mapped,       // APPROVED | PENDING | ...
    'raw_status' => $raw,          // "pending" | "paid"
    'paid_at' => $paid,
    'transaction_id' => $id,
    'source' => 'api',
]);
