<?php

namespace Kanews\Kai\Support;

class ImageHelper
{
    public static function fetchPexelsImages(string $query): array
    {
        $apiKey = Options::getApiKey('pexels');
        if (empty($apiKey)) {
            return [];
        }

        $url = 'https://api.pexels.com/v1/search?' . http_build_query([
            'query'       => $query,
            'per_page'    => 9,
            'locale'      => 'tr-TR',
            'orientation' => 'landscape',
        ]);

        $response = wp_remote_get($url, [
            'timeout' => 20,
            'headers' => [
                'Authorization' => $apiKey,
            ],
        ]);

        if (is_wp_error($response)) {
            return [];
        }

        $data = json_decode(wp_remote_retrieve_body($response), true);
        if (!isset($data['photos']) || !is_array($data['photos'])) {
            return [];
        }

        $images = [];
        foreach ($data['photos'] as $photo) {
            if (!isset($photo['src'])) {
                continue;
            }
            $images[] = [
                'url'             => $photo['src']['large'] ?? '',
                'thumbnail'       => $photo['src']['medium'] ?? ($photo['src']['large'] ?? ''),
                'photographer'    => $photo['photographer'] ?? '',
                'photographer_url'=> $photo['photographer_url'] ?? '',
            ];
        }

        return $images;
    }

    public static function uploadFeaturedImage(array $imageData, int $postId)
    {
        require_once ABSPATH . 'wp-admin/includes/media.php';
        require_once ABSPATH . 'wp-admin/includes/file.php';
        require_once ABSPATH . 'wp-admin/includes/image.php';

        $tmp = download_url($imageData['url']);

        if (is_wp_error($tmp)) {
            return false;
        }

        $fileArray = [
            'name'     => sanitize_file_name(get_the_title($postId) . '-featured.jpg'),
            'tmp_name' => $tmp,
        ];

        $imageId = media_handle_sideload($fileArray, $postId);

        @unlink($tmp);

        if (is_wp_error($imageId)) {
            return false;
        }

        update_post_meta($imageId, 'photographer_name', $imageData['photographer'] ?? '');
        update_post_meta($imageId, 'photographer_url', $imageData['photographer_url'] ?? '');

        set_post_thumbnail($postId, $imageId);

        return $imageId;
    }

    public static function uploadFeaturedImageFromBytes(string $bytes, int $postId, ?string $filename = null)
    {
        require_once ABSPATH . 'wp-admin/includes/media.php';
        require_once ABSPATH . 'wp-admin/includes/file.php';
        require_once ABSPATH . 'wp-admin/includes/image.php';

        $filename = $filename ?: sanitize_file_name(get_the_title($postId) . '-featured.jpg');
        $tmp      = wp_tempnam($filename);

        if (!$tmp) {
            return false;
        }

        file_put_contents($tmp, $bytes);

        $fileArray = [
            'name'     => $filename,
            'tmp_name' => $tmp,
        ];

        $imageId = media_handle_sideload($fileArray, $postId);
        @unlink($tmp);

        if (is_wp_error($imageId)) {
            return false;
        }

        set_post_thumbnail($postId, $imageId);
        return $imageId;
    }

    public static function dalleImage(string $prompt, string $size = '1024x1024')
    {
        $apiKey = Options::getApiKey('openai');
        if (empty($apiKey)) {
            return new \WP_Error('openai_image_missing_key', __('OpenAI API anahtarı bulunamadı.', 'kanews'));
        }

        $payload = [
            'model'           => 'dall-e-3',
            'prompt'          => $prompt,
            'size'            => $size,
            'response_format' => 'b64_json',
            'n'               => 1,
        ];

        $response = wp_remote_post('https://api.openai.com/v1/images/generations', [
            'timeout' => 60,
            'headers' => [
                'Authorization' => 'Bearer ' . $apiKey,
                'Content-Type'  => 'application/json',
            ],
            'body'    => wp_json_encode($payload),
        ]);

        if (is_wp_error($response)) {
            return new \WP_Error('openai_image_request_failed', $response->get_error_message());
        }

        $data = json_decode(wp_remote_retrieve_body($response), true);
        if (isset($data['error']['message'])) {
            return new \WP_Error('openai_image_error', $data['error']['message']);
        }

        if (!isset($data['data'][0]['b64_json'])) {
            return new \WP_Error('openai_image_empty', __('OpenAI görsel yanıtı boş döndü.', 'kanews'));
        }

        return base64_decode($data['data'][0]['b64_json']);
    }

    public static function geminiImage(string $prompt, string $size = '1024x682')
    {
        $apiKey = Options::getApiKey('gemini');
        if (empty($apiKey)) {
            return false;
        }

        [$width, $height] = self::parseSize($size, 1024, 682);
        $aspectRatio = self::determineAspectRatio($width, $height);

        $url = sprintf(
            'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-image:generateContent?key=%s',
            rawurlencode($apiKey)
        );

        $payload = [
            'contents' => [
                [
                    'role'  => 'user',
                    'parts' => [
                        ['text' => $prompt],
                        ['text' => sprintf('Create a photo-realistic image in JPEG format. Aspect ratio: %s.', $aspectRatio)],
                    ],
                ],
            ],
        ];

        $response = wp_remote_post($url, [
            'timeout' => 60,
            'headers' => ['Content-Type' => 'application/json'],
            'body'    => wp_json_encode($payload),
        ]);

        if (is_wp_error($response)) {
            return $response;
        }

        $data = json_decode(wp_remote_retrieve_body($response), true);

        if (isset($data['error'])) {
            $message = $data['error']['message'] ?? __('Gemini görsel API hatası.', 'kanews');
            return new \WP_Error('gemini_image_error', $message);
        }

        $base64 = self::extractGeminiBase64($data);

        if ($base64) {
            return base64_decode($base64);
        }

        $message = __('Gemini görsel yanıtı boş döndü.', 'kanews');
        $errors = $data['error']['message'] ?? null;
        if ($errors) {
            $message .= ' ' . $errors;
        }

        return new \WP_Error('gemini_image_empty', $message);
    }

    private static function parseSize(string $size, int $defaultWidth, int $defaultHeight): array
    {
        $parts = explode('x', strtolower($size));
        if (count($parts) === 2) {
            $w = max(1, intval($parts[0]));
            $h = max(1, intval($parts[1]));
            return [$w, $h];
        }

        return [$defaultWidth, $defaultHeight];
    }

    private static function determineAspectRatio(int $width, int $height): string
    {
        $ratios = [
            '1:1'  => 1.0,
            '4:3'  => 4 / 3,
            '3:2'  => 3 / 2,
            '16:9' => 16 / 9,
            '3:4'  => 3 / 4,
            '9:16' => 9 / 16,
        ];

        if ($height <= 0) {
            return '1:1';
        }

        $target = $width / $height;
        $closest = '1:1';
        $diff = PHP_FLOAT_MAX;

        foreach ($ratios as $label => $value) {
            $currentDiff = abs($target - $value);
            if ($currentDiff < $diff) {
                $closest = $label;
                $diff = $currentDiff;
            }
        }

        return $closest;
    }

    private static function extractGeminiBase64(array $data): ?string
    {
        $paths = [
            ['generatedImages', 0, 'base64Data'],
            ['generatedImages', 0, 'base64_data'],
            ['generatedImages', 0, 'image', 'base64Data'],
            ['generatedImages', 0, 'image', 'base64_data'],
            ['generatedImages', 0, 'image', 'base64'],
            ['generatedImages', 0, 'inlineData', 'data'],
            ['generatedImages', 0, 'inline_data', 'data'],
            ['generatedImages', 0, 'content', 'parts', 0, 'inlineData', 'data'],
            ['generatedImages', 0, 'content', 'parts', 0, 'inline_data', 'data'],
            ['generatedImages', 0, 'content', 'parts', 0, 'image', 'base64Data'],
            ['generatedImages', 0, 'content', 'parts', 0, 'image', 'base64'],
            ['images', 0, 'base64Data'],
            ['images', 0, 'base64'],
            ['candidates', 0, 'image', 'base64Data'],
            ['candidates', 0, 'image', 'base64'],
            ['candidates', 0, 'content', 'parts', 0, 'inline_data', 'data'],
            ['candidates', 0, 'content', 'parts', 0, 'inlineData', 'data'],
        ];

        foreach ($paths as $path) {
            $value = self::arrayGet($data, $path);
            if (!empty($value) && is_string($value)) {
                return $value;
            }
        }

        return null;
    }

    private static function arrayGet(array $data, array $path)
    {
        $current = $data;
        foreach ($path as $segment) {
            if (is_array($current) && array_key_exists($segment, $current)) {
                $current = $current[$segment];
            } else {
                return null;
            }
        }

        return $current;
    }

    /**
     * Görsel üzerine metin ekler ve yeni görsel oluşturur
     * 
     * @param int $imageId WordPress attachment ID
     * @param string $title Ana başlık
     * @param string $subtitle Alt başlık
     * @param string $textColor Yazı rengi (hex)
     * @param string $bgColor Arkaplan rengi (hex)
     * @param int $bgOpacity Arkaplan şeffaflığı (0-100)
     * @param int $postId Yazı ID'si
     * @param int $signatureImageId İmza / logo görsel ID'si (opsiyonel)
     * @param string $signaturePosition İmza konumu (top_left, top_right)
     * @param int $cropWidth Kırpma genişliği (px), 0 ise orijinal
     * @param int $cropHeight Kırpma yüksekliği (px), 0 ise orijinal
     * @param string $textAlign İçerik hizalaması (center, left, right)
     * @return int|\WP_Error Yeni görsel ID'si veya WP_Error
     */
    public static function createHeroImageWithText(
        int $imageId,
        string $title,
        string $subtitle,
        string $textColor = '#ffffff',
        string $bgColor = '#000000',
        int $bgOpacity = 70,
        int $postId = 0,
        int $signatureImageId = 0,
        string $signaturePosition = 'top_right',
        int $cropWidth = 0,
        int $cropHeight = 0,
        string $textAlign = 'center',
        string $sourceField = 'manset_desktop'
    ) {
        if (!function_exists('imagecreatefromjpeg') || !function_exists('imagecreatefrompng')) {
            return new \WP_Error('gd_not_available', __('GD kütüphanesi yüklü değil.', 'kanews'));
        }

        $imagePath = get_attached_file($imageId);
        if (!$imagePath || !file_exists($imagePath)) {
            return new \WP_Error('image_not_found', __('Görsel dosyası bulunamadı.', 'kanews'));
        }

        // Görsel bilgilerini al
        $imageInfo = wp_get_attachment_image_src($imageId, 'full');
        if (!$imageInfo) {
            return new \WP_Error('image_info_failed', __('Görsel bilgileri alınamadı.', 'kanews'));
        }

        // Görsel tipini belirle
        $imageType = wp_check_filetype($imagePath);
        $mimeType = $imageType['type'];

        // Görseli yükle
        $sourceImage = null;
        switch ($mimeType) {
            case 'image/jpeg':
            case 'image/jpg':
                $sourceImage = imagecreatefromjpeg($imagePath);
                break;
            case 'image/png':
                $sourceImage = imagecreatefrompng($imagePath);
                break;
            case 'image/gif':
                $sourceImage = imagecreatefromgif($imagePath);
                break;
            default:
                return new \WP_Error('unsupported_format', __('Desteklenmeyen görsel formatı.', 'kanews'));
        }

        if (!$sourceImage) {
            return new \WP_Error('image_load_failed', __('Görsel yüklenemedi.', 'kanews'));
        }

        $srcWidth = imagesx($sourceImage);
        $srcHeight = imagesy($sourceImage);

        // Hedef boyutları belirle (kırpma varsa ona göre)
        if ($cropWidth > 0 && $cropHeight > 0) {
            $width = $cropWidth;
            $height = $cropHeight;
        } else {
            $width = $srcWidth;
            $height = $srcHeight;
        }

        // Yeni görsel oluştur
        $newImage = imagecreatetruecolor($width, $height);
        
        // Şeffaflığı koru (PNG için)
        if ($mimeType === 'image/png') {
            imagealphablending($newImage, false);
            imagesavealpha($newImage, true);
            $transparent = imagecolorallocatealpha($newImage, 0, 0, 0, 127);
            imagefill($newImage, 0, 0, $transparent);
        }

        // Orijinal görseli kopyala veya kırp
        if ($cropWidth > 0 && $cropHeight > 0) {
            // Oranı koruyarak merkezden kırpma (cover mantığı)
            $scale = max(
                $cropWidth / max(1, $srcWidth),
                $cropHeight / max(1, $srcHeight)
            );

            $scaledWidth = (int)max(1, $srcWidth * $scale);
            $scaledHeight = (int)max(1, $srcHeight * $scale);

            // Geçici ölçeklenmiş görsel
            $scaledImage = imagecreatetruecolor($scaledWidth, $scaledHeight);
            if ($mimeType === 'image/png') {
                imagealphablending($scaledImage, false);
                imagesavealpha($scaledImage, true);
                $transparent = imagecolorallocatealpha($scaledImage, 0, 0, 0, 127);
                imagefill($scaledImage, 0, 0, $transparent);
            }

            imagecopyresampled(
                $scaledImage,
                $sourceImage,
                0,
                0,
                0,
                0,
                $scaledWidth,
                $scaledHeight,
                $srcWidth,
                $srcHeight
            );

            // Merkezden kırp
            $srcX = (int)max(0, ($scaledWidth - $cropWidth) / 2);
            $srcY = (int)max(0, ($scaledHeight - $cropHeight) / 2);

            imagecopy(
                $newImage,
                $scaledImage,
                0,
                0,
                $srcX,
                $srcY,
                $cropWidth,
                $cropHeight
            );

            imagedestroy($scaledImage);
        } else {
            // Kırpma yoksa orijinal boyutta kopyala
            imagecopy($newImage, $sourceImage, 0, 0, 0, 0, $width, $height);
        }

        // BebasNeue font yolunu al
        $fontPath = get_template_directory() . '/assets/fonts/BebasNeue-Regular.ttf';
        if (!file_exists($fontPath)) {
            $fontPath = self::getFontPath(); // Fallback
        }

        // Gradient overlay için - alt kısımda koyu, yukarı doğru saydamlaşan
        $gradientHeight = (int)($height * 0.4); // Alt %40'a gradient uygula
        $gradientStartY = $height - $gradientHeight;
        
        // Pürüzsüz gradient için - her pixel için alpha hesapla
        // Performans için her 2 pixel'de bir çiz (yeterince pürüzsüz)
        $step = 2;
        for ($y = $height; $y >= $gradientStartY; $y -= $step) {
            // Alttan yukarı doğru alpha değeri artar (daha saydam)
            // y=height (en alt) -> alpha=0 (opak), y=gradientStartY (en üst) -> alpha=127 (tam saydam)
            // Quadratic easing kullanarak başlangıcı daha koyu yap (progress^2)
            $progress = ($height - $y) / $gradientHeight;
            // Quadratic easing: başlangıçta daha yavaş artış, sonra hızlanır
            $easedProgress = $progress * $progress;
            $alpha = (int)(127 * $easedProgress);
            $alpha = max(0, min(127, $alpha));
            $gradientColor = imagecolorallocatealpha($newImage, 0, 0, 0, $alpha);
            
            // Her adım için dikdörtgen çiz (pürüzsüz görünüm için)
            $yEnd = max($gradientStartY, $y - $step);
            imagefilledrectangle($newImage, 0, (int)$yEnd, $width, (int)$y, $gradientColor);
        }
        
        // Son pixel'i de çiz (tam pürüzsüzlük için)
        if ($yEnd > $gradientStartY) {
            $finalAlpha = (int)(127 * (($height - $gradientStartY) / $gradientHeight));
            $finalColor = imagecolorallocatealpha($newImage, 0, 0, 0, $finalAlpha);
            imageline($newImage, 0, (int)$gradientStartY, $width, (int)$gradientStartY, $finalColor);
        }

        // Font boyutlarını hesapla - mobil için daha küçük
        $isMobile = ($sourceField === 'manset_mobile');
        if ($isMobile) {
            // Mobil için daha küçük font boyutları
            $titleFontSize = max(28, (int)($width / 22)); // Başlık için başlangıç punto (mobil)
            $subtitleFontSize = max(16, (int)($width / 38)); // Subtitle için (mobil)
        } else {
            // Masaüstü için normal font boyutları
            $titleFontSize = max(40, (int)($width / 18)); // Başlık için başlangıç punto
            $subtitleFontSize = max(20, (int)($width / 30)); // Subtitle için
        }

        // Başlık rengi: #ffed05 (sarı)
        $titleRgb = self::hexToRgb('#ffed05');
        $titleColorResource = imagecolorallocate($newImage, $titleRgb['r'], $titleRgb['g'], $titleRgb['b']);
        // Inline stil renkleri:
        // **...**  -> beyaz
        // ***...*** -> kırmızı
        $titleWhiteColor = imagecolorallocate($newImage, 255, 255, 255);
        $titleRedColor   = imagecolorallocate($newImage, 215, 5, 15); // Kırmızıya yakın

        // Subtitle için: beyaz yazı, saydam kırmızı arkaplan
        $subtitleTextColor = imagecolorallocate($newImage, 255, 255, 255); // Beyaz
        $subtitleBgRgb = self::hexToRgb('#d7050f'); // Kırmızı
        // Biraz daha opak kırmızı arkaplan (önceki 80'den daha dolu)
        $subtitleBgAlpha = 30; // 127 = tam saydam, 0 = opak
        $subtitleBgColor = imagecolorallocatealpha($newImage, $subtitleBgRgb['r'], $subtitleBgRgb['g'], $subtitleBgRgb['b'], $subtitleBgAlpha);

        // Metin pozisyonları - altta
        $bottomPadding = (int)($height * 0.05); // Alt padding - overlay üzerinde biraz içeride
        // Başlık ve subtitle arası boşluğu artırıldı
        $spacing = (int)($titleFontSize * 0.35);

        // Metinleri decode et (HTML entity'leri ve escape karakterlerini düzelt)
        $title = stripslashes($title);
        $title = html_entity_decode($title, ENT_QUOTES | ENT_HTML5, 'UTF-8');
        $subtitle = stripslashes($subtitle);
        $subtitle = html_entity_decode($subtitle, ENT_QUOTES | ENT_HTML5, 'UTF-8');
        
        // Başlık metnini çiz (padding ve satır kırma ile)
        $titleLines = [];
        $titleLineHeight = 0;
        $maxTitleLines = 2;

        if (!empty($title) && $fontPath) {
            // Hizalama tipine göre maksimum genişlik belirle
            if ($textAlign === 'left' || $textAlign === 'right') {
                $maxTextWidth = (int)($width * 0.95); // Sağdan soldan %2.5 boşluk (kenar yaslı için daha az)
            } else {
                $maxTextWidth = (int)($width * 0.9); // Sağdan soldan %5 boşluk (ortalı için)
            }

            // Yardımcı fonksiyon: verilen punto ile satırları sığdır
            $wrapText = function (int $fontSize, string $fontPath, string $text, int $maxWidth) {
                // Stil bloklarının ( **...**, ***...*** ) satır arasında bölünmesini engellemek için
                // bu blokların içindeki boşlukları geçici bir placeholder ile değiştiriyoruz.
                $placeholder = "\x1F"; // görünmeyen ayırıcı

                $protectedText = preg_replace_callback(
                    '/(\*\*\*.*?\*\*\*|\*\*.*?\*\*)/s',
                    static function (array $matches) use ($placeholder) {
                        return str_replace(' ', $placeholder, $matches[0]);
                    },
                    $text
                );

                $words = preg_split('/\s+/', $protectedText);
                $lines = [];
                $current = '';

                foreach ($words as $word) {
                    if ($word === '') {
                        continue;
                    }

                    $candidate = $current === '' ? $word : $current . ' ' . $word;
                    // Genişlik hesabında stil işaretlerini metinden çıkart
                    $renderTest = ImageHelper::stripBoldMarkers(str_replace($placeholder, ' ', $candidate));
                    $box = imagettfbbox($fontSize, 0, $fontPath, $renderTest);
                    $testWidth = abs($box[4] - $box[0]);

                    if ($testWidth > $maxWidth && $current !== '') {
                        // Satır tamamlandı, placeholder'ları tekrar boşluğa çevirerek ekle
                        $lines[] = str_replace($placeholder, ' ', $current);
                        $current = $word;
                    } else {
                        $current = $candidate;
                    }
                }

                if ($current !== '') {
                    $lines[] = str_replace($placeholder, ' ', $current);
                }

                return $lines;
            };

            // Puntoyu, en fazla 2 satıra sığacak şekilde ayarla
            // Mobil için daha küçük minimum font boyutu
            if ($isMobile) {
                $minTitleFontSize = max(18, (int)($width / 35));
            } else {
                $minTitleFontSize = max(24, (int)($width / 28));
            }
            do {
                $titleLines = $wrapText($titleFontSize, $fontPath, $title, $maxTextWidth);
                if (count($titleLines) > $maxTitleLines && $titleFontSize > $minTitleFontSize) {
                    $titleFontSize -= 2;
                } else {
                    break;
                }
            } while (true);

            // Tek satır yüksekliğini hesapla
            $sampleBox = imagettfbbox($titleFontSize, 0, $fontPath, 'Hg');
            $titleLineHeight = abs($sampleBox[5] - $sampleBox[1]);

            $linesCount = max(1, count($titleLines));
            $lineSpacing = (int)($titleLineHeight * 0.2);

            // Son satırın baseline'ı altta olacak şekilde Y pozisyonu
            $titleY = $height - $bottomPadding;
            $firstLineY = $titleY - ($linesCount - 1) * ($titleLineHeight + $lineSpacing);

            // Her satırı çiz (hizalamaya göre)
            $shadowColor = imagecolorallocatealpha($newImage, 0, 0, 0, 100);
            for ($i = 0; $i < $linesCount; $i++) {
                $lineText = $titleLines[$i];
                // Hizalama için, ** işaretlerini düşürerek genişlik hesapla
                $renderLineText = self::stripBoldMarkers($lineText);
                $box = imagettfbbox($titleFontSize, 0, $fontPath, $renderLineText);
                $lineWidth = abs($box[4] - $box[0]);
                if ($textAlign === 'left') {
                    $titleX = (int)($width * 0.025); // soldan %2.5 padding (azaltıldı)
                } elseif ($textAlign === 'right') {
                    $titleX = (int)($width - $lineWidth - $width * 0.025); // sağdan %2.5 padding (azaltıldı)
                } else {
                    $titleX = (int)(($width - $lineWidth) / 2); // ortalı
                }
                $lineY = $firstLineY + $i * ($titleLineHeight + $lineSpacing);

                // Satır içi **...** bloklarına göre segmentleri çöz
                $segments = self::parseBoldSegments($lineText);
                $cursorX = $titleX;

                foreach ($segments as $segment) {
                    $segmentText = $segment['text'];
                    if ($segmentText === '') {
                        continue;
                    }

                    // Segment genişliğini hesapla
                    $segBox = imagettfbbox($titleFontSize, 0, $fontPath, $segmentText);
                    $segWidth = abs($segBox[4] - $segBox[0]);

                    // Renge göre color resource seç
                    switch ($segment['style']) {
                        case 'white':
                            $segColor = $titleWhiteColor;
                            break;
                        case 'red':
                            $segColor = $titleRedColor;
                            break;
                        case 'normal':
                        default:
                            $segColor = $titleColorResource;
                            break;
                    }

                    // Drop shadow
                    imagettftext($newImage, $titleFontSize, 0, (int)$cursorX + 3, $lineY + 3, $shadowColor, $fontPath, $segmentText);
                    // Renkli metin
                    imagettftext($newImage, $titleFontSize, 0, (int)$cursorX, $lineY, $segColor, $fontPath, $segmentText);

                    $cursorX += $segWidth;
                }
            }
            
            // Subtitle pozisyonu (başlığın üstünde)
            if (!empty($subtitle) && $fontPath) {
                // Subtitle metin boyutunu hesapla
                $subtitleBox = imagettfbbox($subtitleFontSize, 0, $fontPath, $subtitle);
                $subtitleWidth = abs($subtitleBox[4] - $subtitleBox[0]);
                $subtitleHeight = abs($subtitleBox[5] - $subtitleBox[1]);
                if ($textAlign === 'left') {
                    $subtitleX = (int)($width * 0.025); // soldan %2.5 padding (azaltıldı)
                } elseif ($textAlign === 'right') {
                    $subtitleX = (int)($width - $subtitleWidth - $width * 0.025); // sağdan %2.5 padding (azaltıldı)
                } else {
                    $subtitleX = ($width - $subtitleWidth) / 2;
                }
                
                // Subtitle için küçük padding (metin boyutuna göre)
                $subtitlePaddingH = (int)($subtitleFontSize * 0.3); // Yatay padding - daha küçük
                $subtitlePaddingV = (int)($subtitleFontSize * 0.2); // Dikey padding - daha küçük
                
                // Subtitle Y pozisyonu - başlığın üstünde, daha yakın
                // En üst başlık satırının üstüne göre hesapla
                $contentTopY = isset($firstLineY)
                    ? $firstLineY - $titleLineHeight // başlığın en üstünün biraz üstü
                    : $titleY - $titleHeight;
                $subtitleY = $contentTopY - $spacing - $subtitlePaddingV;
                
                // Subtitle arkaplan kutusu (saydam kırmızı) - ortalı
                $subtitleBgX = $subtitleX - $subtitlePaddingH;
                $subtitleBgY = $subtitleY - $subtitleHeight - $subtitlePaddingV;
                $subtitleBgWidth = $subtitleWidth + ($subtitlePaddingH * 2);
                $subtitleBgHeight = $subtitleHeight + ($subtitlePaddingV * 2);
                
                // Saydam kırmızı arkaplan
                imagefilledrectangle(
                    $newImage,
                    (int)$subtitleBgX,
                    (int)$subtitleBgY,
                    (int)($subtitleBgX + $subtitleBgWidth),
                    (int)($subtitleBgY + $subtitleBgHeight),
                    $subtitleBgColor
                );
                
                // Subtitle metni (beyaz, ortalı)
                imagettftext($newImage, $subtitleFontSize, 0, (int)$subtitleX, $subtitleY, $subtitleTextColor, $fontPath, $subtitle);
            }
        } elseif (!empty($title)) {
            // Font yoksa built-in font kullan (fallback)
            $titleY = $height - $bottomPadding;
            $titleX = ($width - strlen($title) * imagefontwidth(5)) / 2;
            imagestring($newImage, 5, (int)$titleX, $titleY - 20, $title, $titleColorResource);
        }



        // İmza / logo görselini ekle (sağ veya sol üst köşe)
        if ($signatureImageId > 0) {
            $signaturePath = get_attached_file($signatureImageId);
            if ($signaturePath && file_exists($signaturePath)) {
                $sigType = wp_check_filetype($signaturePath);
                $sigMime = $sigType['type'] ?? '';

                $signatureImage = null;
                switch ($sigMime) {
                    case 'image/png':
                        $signatureImage = imagecreatefrompng($signaturePath);
                        break;
                    case 'image/jpeg':
                    case 'image/jpg':
                        $signatureImage = imagecreatefromjpeg($signaturePath);
                        break;
                    case 'image/gif':
                        $signatureImage = imagecreatefromgif($signaturePath);
                        break;
                    default:
                        $signatureImage = null;
                        break;
                }

                if ($signatureImage) {
                    $sigW = imagesx($signatureImage);
                    $sigH = imagesy($signatureImage);

                    // İmza boyutunu ana görsele göre ölçekle (maks. %18)
                    $maxSigWidth = (int)($width * 0.18);
                    $maxSigHeight = (int)($height * 0.18);
                    $scale = min(
                        $maxSigWidth / max(1, $sigW),
                        $maxSigHeight / max(1, $sigH),
                        1.0
                    );

                    $targetW = (int)max(1, $sigW * $scale);
                    $targetH = (int)max(1, $sigH * $scale);

                    // Yeniden boyutlandırılmış imza görseli oluştur
                    $resizedSignature = imagecreatetruecolor($targetW, $targetH);
                    imagealphablending($resizedSignature, false);
                    imagesavealpha($resizedSignature, true);
                    $transparent = imagecolorallocatealpha($resizedSignature, 0, 0, 0, 127);
                    imagefill($resizedSignature, 0, 0, $transparent);

                    imagecopyresampled(
                        $resizedSignature,
                        $signatureImage,
                        0,
                        0,
                        0,
                        0,
                        $targetW,
                        $targetH,
                        $sigW,
                        $sigH
                    );

                    imagedestroy($signatureImage);

                    // Kenarlardan mesafe
                    $margin = (int)min($width, $height) * 0.03;

                    if ($signaturePosition === 'top_left') {
                        $sigX = $margin;
                    } else {
                        // Varsayılan: sağ üst
                        $sigX = $width - $targetW - $margin;
                    }
                    $sigY = $margin;

                    imagealphablending($newImage, true);
                    imagecopy(
                        $newImage,
                        $resizedSignature,
                        (int)$sigX,
                        (int)$sigY,
                        0,
                        0,
                        $targetW,
                        $targetH
                    );

                    imagedestroy($resizedSignature);
                }
            }
        }

        // Geçici dosyaya kaydet
        $uploadDir = wp_upload_dir();
        $filename = 'hero-image-' . time() . '-' . wp_generate_password(8, false) . '.jpg';
        $filePath = $uploadDir['path'] . '/' . $filename;

        // JPEG olarak kaydet
        imagejpeg($newImage, $filePath, 90);
        imagedestroy($sourceImage);
        imagedestroy($newImage);

        // WordPress media library'ye ekle
        require_once ABSPATH . 'wp-admin/includes/media.php';
        require_once ABSPATH . 'wp-admin/includes/file.php';
        require_once ABSPATH . 'wp-admin/includes/image.php';

        $fileArray = [
            'name'     => $filename,
            'tmp_name' => $filePath,
        ];

        $newImageId = media_handle_sideload($fileArray, $postId);

        if (is_wp_error($newImageId)) {
            @unlink($filePath);
            return $newImageId;
        }

        return $newImageId;
    }

    /**
     * Hex rengi RGB'ye çevirir
     */
    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)),
        ];
    }



    /**
     * Başlık içindeki **...** bloklarını temizler (yalnızca stil işaretlerini kaldırır)
     */
    private static function stripBoldMarkers(string $text): string
    {
        // **kelime**  veya ***kelime***  -> kelime   (sadece işaretleri kaldır)
        return str_replace(['***', '**'], '', $text);
    }

    /**
     * Başlık için **...** (beyaz) ve ***...*** (kırmızı) bloklarını segmentlere böler
     * Örn: "Normal **Beyaz** ***Kırmızı*** Normal" ->
     * [
     *   ['text' => 'Normal ',  'style' => 'normal'],
     *   ['text' => 'Beyaz',    'style' => 'white'],
     *   ['text' => ' ',        'style' => 'normal'],
     *   ['text' => 'Kırmızı',  'style' => 'red'],
     *   ['text' => ' Normal',  'style' => 'normal'],
     * ]
     */
    private static function parseBoldSegments(string $text): array
    {
        $segments = [];
        $currentStyle = 'normal'; // normal | white | red

        // **  ve *** işaretlerine göre parçala (işaretleri de geri döndür)
        $parts = preg_split('/(\*\*\*|\*\*)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
        if (!is_array($parts) || count($parts) === 0) {
            return [
                [
                    'text'  => $text,
                    'style' => $currentStyle,
                ],
            ];
        }

        foreach ($parts as $part) {
            if ($part === '') {
                continue;
            }

            if ($part === '**' || $part === '***') {
                // Marker'a göre hedef stili belirle
                $markerStyle = ($part === '**') ? 'white' : 'red';

                // Aynı stile tekrar basılırsa normale dön (toggle)
                if ($markerStyle === $currentStyle) {
                    $currentStyle = 'normal';
                } else {
                    $currentStyle = $markerStyle;
                }
            } else {
                // Normal metin parçası
                $segments[] = [
                    'text'  => $part,
                    'style' => $currentStyle,
                ];
            }
        }

        return $segments;
    }

    /**
     * Türkçe karakter desteği için font yolunu bulur
     */
    private static function getFontPath(): ?string
    {
        // Önce BebasNeue fontunu kontrol et
        $bebasPath = get_template_directory() . '/assets/fonts/BebasNeue-Regular.ttf';
        if (file_exists($bebasPath)) {
            return $bebasPath;
        }

        // WordPress'in font dizinini kontrol et
        $possiblePaths = [
            get_template_directory() . '/assets/fonts/arial.ttf',
            get_template_directory() . '/assets/fonts/DejaVuSans.ttf',
            ABSPATH . 'wp-includes/fonts/arial.ttf',
        ];

        foreach ($possiblePaths as $path) {
            if (file_exists($path)) {
                return $path;
            }
        }

        // Sistem fontlarını kontrol et
        $systemFonts = [
            '/System/Library/Fonts/Helvetica.ttc',
            '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf',
            '/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf',
        ];

        foreach ($systemFonts as $font) {
            if (file_exists($font)) {
                return $font;
            }
        }

        return null;
    }
}

