<?php

namespace App\Core\Email;

use League\HTMLToMarkdown\HtmlConverter;

/**
 * HTML e-posta gövdesini link-koruyan düz-metin (multipart/alternative text
 * part'ı) üretir. PRC-1073.
 *
 * PRC-1063'ün strip_tags türevi text part'ı düşük kaliteydi: <a href> link
 * URL'leri kaybolur, <style>/<script> CSS'i text'e sızardı. Burada:
 *   1) <style>/<script>/<head> içerikleri ÖNCE strip edilir (strip_tags TEK
 *      başına içeriklerini bırakır → CSS sızardı).
 *   2) league/html-to-markdown ile link-koruyan çevrim yapılır
 *      (use_autolinks=false → daima [metin](url), böylece URL text partta kalır).
 *   3) Çevirici karmaşık HTML/tablolarda kırılırsa güvenli strip fallback'e düşer.
 */
class HtmlToTextConverter
{
    /**
     * <style>/<script>/<head> bloklarını (açılış+içerik+kapanış) yakalayan regex.
     */
    private const STRIP_BLOCKS_PATTERN = '#<(style|script|head)\b[^>]*>.*?</\1>#is';

    public function convert(string $html): string
    {
        if (trim($html) === '') {
            return '';
        }

        // 1) CSS/JS/head içeriğini tamamen kaldır — strip_tags bunların
        //    İÇERİĞİNİ bırakır, o yüzden markdown çeviriminden ÖNCE temizle.
        $preStripped = preg_replace(self::STRIP_BLOCKS_PATTERN, '', $html) ?? $html;

        try {
            $converter = new HtmlConverter([
                'strip_tags' => true,        // markdown karşılığı olmayan tag'leri temizle
                'remove_nodes' => 'style script head meta title link',
                'hard_break' => true,        // <br> → \n
                'use_autolinks' => false,    // daima [metin](url) — URL text partta korunur
                'suppress_errors' => true,   // tam HTML doküman malformasyonlarında sessiz kal
            ]);

            $text = $converter->convert($preStripped);
        } catch (\Throwable $e) {
            // Tablolar / kompleks yapılar çeviriciyi çökertebilir → güvenli strip.
            $text = $this->safeStrip($preStripped);
        }

        return $this->normalizeWhitespace($text);
    }

    /**
     * Çevirici başarısız olursa: kalan tag'leri strip + entity decode.
     * (style/script/head zaten pre-strip edildi.)
     */
    private function safeStrip(string $html): string
    {
        $text = strip_tags($html);

        return html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    }

    /**
     * Fazla boşluk/satırı normalize et: satır sonu boşlukları kırp, 2'den fazla
     * ardışık boş satırı tek boş satıra indir, baş/son boşlukları temizle.
     */
    private function normalizeWhitespace(string $text): string
    {
        // Windows/Mac satır sonlarını normalize et
        $text = str_replace(["\r\n", "\r"], "\n", $text);

        // Her satırın sonundaki boşlukları kırp
        $text = preg_replace('/[ \t]+\n/', "\n", $text) ?? $text;

        // 3+ ardışık yeni satırı 2'ye indir (tek boş satır)
        $text = preg_replace('/\n{3,}/', "\n\n", $text) ?? $text;

        return trim($text);
    }
}
