<?php
/**
 * Serves a QR code PNG with the API-key owner's profile avatar stamped in
 * the center. Called as an <img> src, e.g.:
 *   /api/qr_image.php?order_id=FAMPAY123...
 *
 * Why this file exists: the free qrserver.com QR generator we use elsewhere
 * can't embed a logo, so this endpoint re-renders that same QR data locally
 * with GD and overlays the user's avatar on top, positioned so the QR's
 * built-in error-correction can tolerate the obstruction.
 */
require_once __DIR__ . '/../includes/functions.php';

// NOTE: stays GET intentionally — this is loaded via <img src="...">
// which only ever issues a browser GET request; it can't POST.
$orderId = $_GET['order_id'] ?? '';
$order = getOrderById($orderId);

header('Content-Type: image/png');

if (!$order) {
    // Order not found — return a small red placeholder rather than crashing
    // the <img> tag with an HTML error body.
    $img = imagecreatetruecolor(300, 300);
    $bg = imagecolorallocate($img, 20, 15, 20);
    imagefill($img, 0, 0, $bg);
    imagepng($img);
    imagedestroy($img);
    exit;
}

// Rebuild the exact same UPI string used when the order/QR was created,
// so the QR content matches what the payer already saw.
$upiString = "upi://pay?pa=" . urlencode($order['upi_id'] ?? '')
    . "&pn=" . urlencode('FamPay')
    . "&tr=" . urlencode($order['order_id'])
    . "&tn=" . urlencode($order['note_code'] ?? '')
    . "&am=" . urlencode((string) $order['amount'])
    . "&cu=INR";

$baseQrUrl = "https://api.qrserver.com/v1/create-qr-code/?size=400x400&ecc=H&data=" . urlencode($upiString);

// Fetch the plain QR PNG. If this or GD is unavailable, fall back to a
// straight redirect to the plain QR so integrations never see a broken image.
if (!function_exists('imagecreatefromstring')) {
    header('Location: ' . $baseQrUrl);
    exit;
}

$qrData = @file_get_contents($baseQrUrl);
if ($qrData === false) {
    header('Location: ' . $baseQrUrl);
    exit;
}

$qrImage = @imagecreatefromstring($qrData);
if (!$qrImage) {
    header('Location: ' . $baseQrUrl);
    exit;
}

// Look up the avatar of the user this order belongs to
$user = getUserById($order['user_id'] ?? '');
$avatarDataUri = $user['avatar'] ?? '';
$qrCenterImageEnabled = $user['qr_center_image'] ?? false;

// Only add center image if user has enabled it
if ($qrCenterImageEnabled && !empty($avatarDataUri) && strpos($avatarDataUri, 'base64,') !== false) {
    $base64 = substr($avatarDataUri, strpos($avatarDataUri, 'base64,') + 7);
    $avatarBinary = base64_decode($base64);
    $avatarImage = @imagecreatefromstring($avatarBinary);

    if ($avatarImage) {
        $qrSize = imagesx($qrImage);

        // Logo should stay small relative to the QR (~20%) so ECC level H
        // (used above) can still recover the obscured modules.
        $logoSize = (int) round($qrSize * 0.20);
        $x = (int) (($qrSize - $logoSize) / 2);
        $y = (int) (($qrSize - $logoSize) / 2);

        // White padded square behind the avatar so it doesn't blend into
        // dark QR modules, then a circular avatar clipped on top of that.
        $paddedSize = $logoSize + 16;
        $px = (int) (($qrSize - $paddedSize) / 2);
        $py = (int) (($qrSize - $paddedSize) / 2);
        $white = imagecolorallocate($qrImage, 255, 255, 255);
        imagefilledrectangle($qrImage, $px, $py, $px + $paddedSize, $py + $paddedSize, $white);

        // Resize avatar to target size on its own canvas first
        $resizedAvatar = imagecreatetruecolor($logoSize, $logoSize);
        imagecopyresampled(
            $resizedAvatar, $avatarImage,
            0, 0, 0, 0,
            $logoSize, $logoSize,
            imagesx($avatarImage), imagesy($avatarImage)
        );

        // Clip resized avatar into a circle using a mask, then paste onto QR
        $circular = imagecreatetruecolor($logoSize, $logoSize);
        imagesavealpha($circular, true);
        $transparent = imagecolorallocatealpha($circular, 0, 0, 0, 127);
        imagefill($circular, 0, 0, $transparent);

        for ($cy = 0; $cy < $logoSize; $cy++) {
            for ($cx = 0; $cx < $logoSize; $cx++) {
                $dx = $cx - $logoSize / 2;
                $dy = $cy - $logoSize / 2;
                if (($dx * $dx + $dy * $dy) <= pow($logoSize / 2, 2)) {
                    $color = imagecolorat($resizedAvatar, $cx, $cy);
                    imagesetpixel($circular, $cx, $cy, $color);
                }
            }
        }

        imagecopy($qrImage, $circular, $x, $y, 0, 0, $logoSize, $logoSize);

        imagedestroy($avatarImage);
        imagedestroy($resizedAvatar);
        imagedestroy($circular);
    }
}

imagepng($qrImage);
imagedestroy($qrImage);
