<?php

declare(strict_types=1);

namespace PrettyLinks\Pro\Qr;

/**
 * Composites a logo image onto a QR PNG using GD.
 *
 * Pure logic, no WP dependencies. Mirrors the legacy
 * PlpQrCodeHelper::generate_qr_with_logo() pipeline.
 */
class LogoOverlay
{
    /**
     * Composites the logo onto the QR PNG and returns the resulting PNG bytes.
     *
     * @param  string  $qrPng           Raw PNG bytes of the source QR.
     * @param  string  $logoPath        Absolute filesystem path to the logo (jpg/png/gif/webp).
     * @param  integer $sizePercent     Percentage of QR width occupied by the logo (10..30).
     * @param  boolean $whiteBackground When true, paints a white safe-area rect behind the logo.
     * @return string Raw PNG bytes with the logo composited.
     */
    public static function apply(string $qrPng, string $logoPath, int $sizePercent, bool $whiteBackground): string
    {
        $qrImage = @imagecreatefromstring($qrPng);
        if ($qrImage === false) {
            return $qrPng;
        }

        $logoImage = self::loadImage($logoPath);
        if ($logoImage === null) {
            return $qrPng;
        }

        $sizePercent = max(10, min(30, $sizePercent));

        $qrWidth    = imagesx($qrImage);
        $qrHeight   = imagesy($qrImage);
        $logoSrcW   = imagesx($logoImage);
        $logoSrcH   = imagesy($logoImage);
        $logoWidth  = (int) ($qrWidth * $sizePercent / 100);
        $logoHeight = $logoSrcW > 0
            ? (int) ($logoSrcH * ($logoWidth / $logoSrcW))
            : $logoWidth;
        $logoX      = (int) (($qrWidth - $logoWidth) / 2);
        $logoY      = (int) (($qrHeight - $logoHeight) / 2);

        if ($whiteBackground) {
            $white     = imagecolorallocate($qrImage, 255, 255, 255);
            $bgPadding = (int) ($logoWidth * 0.1);
            $bgX       = $logoX - $bgPadding;
            $bgY       = $logoY - $bgPadding;
            $bgWidth   = $logoWidth + ($bgPadding * 2);
            $bgHeight  = $logoHeight + ($bgPadding * 2);
            imagefilledrectangle($qrImage, $bgX, $bgY, $bgX + $bgWidth, $bgY + $bgHeight, $white);
        }

        imagecopyresampled(
            $qrImage,
            $logoImage,
            $logoX,
            $logoY,
            0,
            0,
            $logoWidth,
            $logoHeight,
            $logoSrcW,
            $logoSrcH
        );

        ob_start();
        imagepng($qrImage);
        return (string) ob_get_clean();
    }

    /**
     * Loads an image file into a GD image resource by MIME type.
     *
     * @param  string $path Absolute filesystem path to the image file.
     * @return resource|\GdImage|null
     */
    private static function loadImage(string $path)
    {
        if (!file_exists($path)) {
            return null;
        }
        // Suppress warning: getimagesize() warns on corrupt/unrecognised files.
        // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- Intentional: getimagesize() warns on corrupt files; the false return is handled below.
        $info = @getimagesize($path);
        if ($info === false) {
            return null;
        }

        switch ($info['mime']) {
            case 'image/jpeg':
                $img = imagecreatefromjpeg($path);
                break;
            case 'image/png':
                $img = imagecreatefrompng($path);
                break;
            case 'image/gif':
                $img = imagecreatefromgif($path);
                break;
            case 'image/webp':
                if (!function_exists('imagecreatefromwebp')) {
                    return null;
                }
                $img = imagecreatefromwebp($path);
                break;
            default:
                return null;
        }

        return $img === false ? null : $img;
    }
}
