<?php

namespace DZ\ImageShield\Service;

use XF;

/**
 * Simple overlay/watermark renderer using GD library.
 */
class OverlayRenderer
{
    private static ?string $fontPath = null;

    /**
     * Set the font path for text rendering.
     */
    public static function setFontPath(string $path): void
    {
        self::$fontPath = $path;
    }

    /**
     * Get the current font path.
     */
    public static function getFontPath(): string
    {
        if (self::$fontPath === null) {
            self::$fontPath = self::getDefaultFontPath();
        }
        return self::$fontPath;
    }

    /**
     * Get the default font path.
     */
    public static function getDefaultFontPath(): string
    {
        return XF::getAddOnDirectory() . '/DZ/ImageShield/fonts/Arial.ttf';
    }

    /**
     * Create a text preview image.
     *
     * @param string $text Text to render
     * @param int $fontSize Font size in points
     * @param string $bgColor Background color (hex)
     * @param string $textColor Text color (hex)
     * @param int $padding Padding around text
     * @return string Path to temporary PNG file
     */
    public static function fromText(
        string $text,
        int $fontSize = 24,
        string $bgColor = '#f5f5f5',
        string $textColor = '#333333',
        int $padding = 10
    ): string {
        $fontPath = self::getFontPath();

        // Ensure minimum font size
        if ($fontSize < 8) {
            $fontSize = 24;
        }

        if (!file_exists($fontPath)) {
            \XF::logError("[DZ ImageShield] Font file not found: {$fontPath}");
            throw new \RuntimeException("Font file not found: {$fontPath}");
        }

        // Calculate text bounding box
        $bbox = @imagettfbbox($fontSize, 0, $fontPath, $text);
        if ($bbox === false) {
            \XF::logError("[DZ ImageShield] imagettfbbox failed for font: {$fontPath}");
            // Fallback: create simple image with estimated size
            $textWidth = strlen($text) * $fontSize * 0.6;
            $textHeight = $fontSize * 1.2;
        } else {
            $textWidth = abs($bbox[4] - $bbox[0]);
            $textHeight = abs($bbox[5] - $bbox[1]);
        }

        // Ensure minimum dimensions
        $textWidth = max($textWidth, 50);
        $textHeight = max($textHeight, 20);

        // Create image with padding
        $width = (int) round($textWidth + ($padding * 2));
        $height = (int) round($textHeight + ($padding * 2));

        $image = imagecreatetruecolor($width, $height);
        if ($image === false) {
            throw new \RuntimeException("Failed to create image");
        }

        // Enable alpha blending for transparency
        imagealphablending($image, false);
        imagesavealpha($image, true);

        // Handle transparent background
        $isTransparent = (strtolower($bgColor) === 'transparent' || $bgColor === '');
        
        if ($isTransparent) {
            // Fill with transparent
            $transparent = imagecolorallocatealpha($image, 0, 0, 0, 127);
            imagefilledrectangle($image, 0, 0, $width - 1, $height - 1, $transparent);
        } else {
            // Fill with background color
            $bg = self::hexToRgb($bgColor);
            $bgColorAlloc = imagecolorallocate($image, $bg['r'], $bg['g'], $bg['b']);
            imagefilledrectangle($image, 0, 0, $width - 1, $height - 1, $bgColorAlloc);
        }

        // Enable alpha blending for text rendering
        imagealphablending($image, true);

        // Parse text color and allocate
        $text_rgb = self::hexToRgb($textColor);
        $textColorAlloc = imagecolorallocate($image, $text_rgb['r'], $text_rgb['g'], $text_rgb['b']);

        // Calculate text position (baseline)
        if ($bbox !== false) {
            $x = $padding - $bbox[0];
            $y = $padding - $bbox[5];
        } else {
            $x = $padding;
            $y = $padding + (int) ($fontSize * 0.8);
        }

        // Render text
        $result = @imagettftext($image, $fontSize, 0, (int) $x, (int) $y, $textColorAlloc, $fontPath, $text);
        
        if ($result === false) {
            \XF::logError("[DZ ImageShield] imagettftext FAILED - font: {$fontPath}, fontSize: {$fontSize}, text: {$text}, x: {$x}, y: {$y}");
            \XF::logError("[DZ ImageShield] GD info: " . json_encode(gd_info()));
            
            // Fallback: use imagestring (built-in font, no TTF required)
            $builtinFont = 5; // largest built-in font
            imagestring($image, $builtinFont, (int) $padding, (int) $padding, $text, $textColorAlloc);
        } else {
            \XF::logError("[DZ ImageShield] imagettftext SUCCESS - rendered text: {$text}");
        }

        // Save to temp file
        $tempDir = \XF\Util\File::getTempDir();
        $tempFile = $tempDir . '/font_preview_' . md5($fontPath . $text . $fontSize) . '.png';
        imagepng($image, $tempFile);
        imagedestroy($image);

        return $tempFile;
    }

    /**
     * Convert hex color to RGB array.
     */
    private static function hexToRgb(string $hex): array
    {
        $hex = ltrim($hex, '#');

        if (strlen($hex) === 3) {
            $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
        }

        return [
            'r' => hexdec(substr($hex, 0, 2)),
            'g' => hexdec(substr($hex, 2, 2)),
            'b' => hexdec(substr($hex, 4, 2)),
        ];
    }
}
