<?php

declare(strict_types=1);

namespace App\Shared\Twig;

use App\Entity\Tenant\Advertisement;
use App\Entity\Tenant\Setting;
use Doctrine\ORM\EntityManagerInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
use Twig\Environment;

class AdExtension extends AbstractExtension
{
    /** @var array<string, Advertisement[]>|null */
    private ?array $cachedAds = null;

    private ?string $contactPhone = null;
    private bool $contactPhoneLoaded = false;

    /**
     * Human-readable position names for placeholder banners.
     */
    private const POSITION_LABELS = [
        'foto_galeri_akis_reklam' => 'Foto Galeri Akış Reklam',
        'sayfa_baslangici' => 'Sayfa Başlangıcı',
        'sayfa_sonu' => 'Sayfa Sonu',
        'baslik_alti' => 'Başlık Altı',
        'baslik_ustu' => 'Başlık Üstü',
        'spot_alti' => 'Spot Altı',
        'fotograf_alti' => 'Fotoğraf Altı',
        'ilginizi_cekebilir_alti' => 'İlginizi Çekebilir Altı',
        'kategori_alti' => 'Kategori Altı',
        'kategori_mansetler_alti' => 'Kategori-Manşetler Altı',
        'acilis_reklami' => 'Açılış Reklamı',
        'en_ust' => 'En Üst',
        'paragraf_tekrar_eden' => 'Paragraf Tekrar Eden',
        'sidebar_ust' => 'Sidebar Üst',
        'sidebar_orta' => 'Sidebar Orta',
        'sidebar_alt' => 'Sidebar Alt',
        'sidebar_yapiskan' => 'Sidebar Yapışkan',
        'sol_kenar' => 'Sol Kenar',
        'sag_kenar' => 'Sağ Kenar',
        'slayt_arasi' => 'Slayt Arası',
    ];

    /**
     * Position category map for building ad creation links.
     */
    private const POSITION_CATEGORY_MAP = [
        'foto_galeri_akis_reklam' => 'alan_reklam',
        'sayfa_baslangici' => 'altsayfa',
        'sayfa_sonu' => 'altsayfa',
        'baslik_alti' => 'altsayfa',
        'baslik_ustu' => 'altsayfa',
        'spot_alti' => 'altsayfa',
        'fotograf_alti' => 'altsayfa',
        'ilginizi_cekebilir_alti' => 'altsayfa',
        'kategori_alti' => 'genel',
        'kategori_mansetler_alti' => 'genel',
        'acilis_reklami' => 'genel',
        'en_ust' => 'genel',
        'paragraf_tekrar_eden' => 'paragraf',
        'sidebar_ust' => 'yan',
        'sidebar_orta' => 'yan',
        'sidebar_alt' => 'yan',
        'sidebar_yapiskan' => 'yan',
        'sol_kenar' => 'yan',
        'sag_kenar' => 'yan',
        'slayt_arasi' => 'alan_reklam',
    ];

    public function __construct(
        private readonly EntityManagerInterface $entityManager,
    ) {}

    public function getFunctions(): array
    {
        return [
            new TwigFunction('render_ad', [$this, 'renderAd'], [
                'is_safe' => ['html'],
                'needs_environment' => true,
            ]),
            new TwigFunction('render_ad_side', [$this, 'renderAdSide'], [
                'is_safe' => ['html'],
                'needs_environment' => true,
            ]),
            new TwigFunction('render_ad_slider', [$this, 'renderAdSlider'], [
                'is_safe' => ['html'],
                'needs_environment' => true,
            ]),
        ];
    }

    public function renderAd(Environment $twig, string $position, bool $showPlaceholder = true): string
    {
        $ads = $this->getActiveAdsForPosition($position);

        if (!empty($ads)) {
            return $this->renderActiveAds($ads);
        }

        // Show placeholder only if enabled (typically for admin users, controlled in template)
        if ($showPlaceholder) {
            return $this->renderPlaceholder($position);
        }

        return '';
    }

    /**
     * Render side (skyscraper) ad - tall vertical banner 160x600.
     */
    public function renderAdSide(Environment $twig, string $position, bool $showPlaceholder = true): string
    {
        $ads = $this->getActiveAdsForPosition($position);

        if (!empty($ads)) {
            return $this->renderActiveAds($ads);
        }

        if ($showPlaceholder) {
            return $this->renderSidePlaceholder($position);
        }

        return '';
    }

    /**
     * Render slider ad - full-size banner that fills the entire slide area.
     */
    public function renderAdSlider(Environment $twig, string $position, bool $showPlaceholder = true): string
    {
        $ads = $this->getActiveAdsForPosition($position);

        if (!empty($ads)) {
            return $this->renderActiveAds($ads);
        }

        if ($showPlaceholder) {
            return $this->renderSliderPlaceholder($position);
        }

        return '';
    }

    /**
     * @return Advertisement[]
     */
    private function getActiveAdsForPosition(string $position): array
    {
        $this->loadAds();

        return $this->cachedAds[$position] ?? [];
    }

    private function loadAds(): void
    {
        if ($this->cachedAds !== null) {
            return;
        }

        $this->cachedAds = [];

        try {
            $now = new \DateTimeImmutable();

            $qb = $this->entityManager->getRepository(Advertisement::class)
                ->createQueryBuilder('a')
                ->where('a.status = :status')
                ->setParameter('status', 'active')
                ->orderBy('a.isPinned', 'DESC')
                ->addOrderBy('a.displayOrder', 'ASC');

            $ads = $qb->getQuery()->getResult();

            foreach ($ads as $ad) {
                // Check date range
                if ($ad->getStartsAt() && $ad->getStartsAt() > $now) {
                    continue;
                }
                if ($ad->getEndsAt() && $ad->getEndsAt() < $now) {
                    continue;
                }

                $pos = $ad->getPosition();
                if (!isset($this->cachedAds[$pos])) {
                    $this->cachedAds[$pos] = [];
                }
                $this->cachedAds[$pos][] = $ad;
            }
        } catch (\Exception) {
            // DB might not be ready
        }
    }

    /**
     * @param Advertisement[] $ads
     */
    private function renderActiveAds(array $ads): string
    {
        $html = '';
        foreach ($ads as $ad) {
            $html .= '<div class="ad-container" data-ad-id="' . $ad->getId() . '">';

            switch ($ad->getAdType()) {
                case 'image':
                    if ($ad->getImageUrl()) {
                        $style = '';
                        if ($ad->getWidth()) {
                            $w = is_numeric($ad->getWidth()) ? $ad->getWidth() . 'px' : $ad->getWidth();
                            $style .= 'max-width:' . $w . ';';
                        }
                        if ($ad->getHeight()) {
                            $h = is_numeric($ad->getHeight()) ? $ad->getHeight() . 'px' : $ad->getHeight();
                            $style .= 'height:' . $h . ';';
                        }
                        $img = '<img src="' . htmlspecialchars($ad->getImageUrl()) . '" alt="' . htmlspecialchars($ad->getName()) . '" class="w-full h-auto" style="' . $style . '">';
                        if ($ad->getTargetUrl()) {
                            $html .= '<a href="' . htmlspecialchars($ad->getTargetUrl()) . '" target="_blank" rel="noopener noreferrer sponsored">' . $img . '</a>';
                        } else {
                            $html .= $img;
                        }
                    }
                    break;

                case 'video':
                    $content = $ad->getContent();
                    if ($content) {
                        if (str_starts_with($content, '/') || str_starts_with($content, 'http')) {
                            // Direct video file
                            $html .= '<video src="' . htmlspecialchars($content) . '" controls class="w-full h-auto" muted></video>';
                        } else {
                            // Embed code
                            $html .= $content;
                        }
                    }
                    break;

                case 'adsense':
                case 'custom_html':
                    if ($ad->getContent()) {
                        $html .= $ad->getContent();
                    }
                    break;
            }

            $html .= '</div>';
        }

        return $html;
    }

    private function getContactPhone(): ?string
    {
        if (!$this->contactPhoneLoaded) {
            $this->contactPhoneLoaded = true;
            try {
                $setting = $this->entityManager->getRepository(Setting::class)
                    ->findOneBy(['settingKey' => 'contact_phone']);
                if ($setting && $setting->getSettingValue()) {
                    $this->contactPhone = trim($setting->getSettingValue());
                }
            } catch (\Exception) {
                // DB might not be ready
            }
        }

        return $this->contactPhone;
    }

    private function renderPlaceholder(string $position): string
    {
        $label = self::POSITION_LABELS[$position] ?? $position;
        $phone = $this->getContactPhone();

        // Build WhatsApp link if phone is configured
        $whatsappMessage = urlencode('Merhaba, sitenizde "' . $label . '" reklam alanı hakkında bilgi almak istiyorum.');
        $contactButton = '';

        if ($phone) {
            // Clean phone number (remove spaces, dashes, plus sign for wa.me)
            $cleanPhone = preg_replace('/[^0-9]/', '', $phone);
            $contactButton = '<a href="https://wa.me/' . $cleanPhone . '?text=' . $whatsappMessage . '" '
                . 'target="_blank" rel="noopener noreferrer" '
                . 'class="inline-flex items-center gap-1.5 text-xs bg-green-500 hover:bg-green-600 text-white font-medium mt-2 px-3 py-1.5 rounded-full transition-colors">'
                . '<i class="fab fa-whatsapp text-sm"></i> İletişime Geç</a>';
        } else {
            $contactButton = '<span class="inline-flex items-center gap-1 text-xs text-gray-400 dark:text-gray-600 font-medium mt-1">'
                . '<i class="fab fa-whatsapp"></i> İletişim bilgisi henüz eklenmedi</span>';
        }

        return '<div class="ad-placeholder" style="position:relative;border:2px dashed #fdba74;border-radius:0.5rem;background:#fff7ed;text-align:center;padding:1.5rem 1rem;margin:1rem 0;transition:all 0.2s;">'
            . '<div style="display:flex;flex-direction:column;align-items:center;gap:0.5rem;">'
            . '<i class="fas fa-ad" style="font-size:1.5rem;color:#fb923c;"></i>'
            . '<p style="font-size:0.875rem;font-weight:600;color:#ea580c;margin:0;">' . htmlspecialchars($label) . '</p>'
            . '<p style="font-size:0.75rem;color:#9a3412;margin:0;">Bu alana reklam verebilirsiniz</p>'
            . $contactButton
            . '</div></div>';
    }

    /**
     * Render a tall skyscraper (160x600) placeholder for side ads.
     */
    private function renderSidePlaceholder(string $position): string
    {
        $label = self::POSITION_LABELS[$position] ?? $position;
        $phone = $this->getContactPhone();

        $whatsappMessage = urlencode('Merhaba, sitenizde "' . $label . '" reklam alanı hakkında bilgi almak istiyorum.');
        $contactButton = '';

        if ($phone) {
            $cleanPhone = preg_replace('/[^0-9]/', '', $phone);
            $contactButton = '<a href="https://wa.me/' . $cleanPhone . '?text=' . $whatsappMessage . '" '
                . 'target="_blank" rel="noopener noreferrer" '
                . 'class="inline-flex items-center gap-1.5 text-[10px] bg-green-500 hover:bg-green-600 text-white font-medium px-2.5 py-1 rounded-full transition-colors leading-tight">'
                . '<i class="fab fa-whatsapp text-xs"></i> İletişime Geç</a>';
        } else {
            $contactButton = '<span class="text-[10px] text-gray-400 dark:text-gray-600">'
                . '<i class="fab fa-whatsapp"></i></span>';
        }

        return '<div class="ad-placeholder" style="position:relative;border:2px dashed #fdba74;border-radius:0.5rem;background:#fff7ed;text-align:center;width:160px;height:600px;transition:all 0.2s;">'
            . '<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0.75rem;height:100%;padding:0.75rem;">'
            . '<i class="fas fa-ad" style="font-size:2rem;color:#fb923c;"></i>'
            . '<p style="font-size:0.75rem;font-weight:600;color:#ea580c;margin:0;line-height:1.3;">' . htmlspecialchars($label) . '</p>'
            . '<p style="font-size:0.625rem;color:#9a3412;margin:0;">160×600</p>'
            . '<p style="font-size:0.625rem;color:#9a3412;margin:0;padding:0 0.25rem;">Bu alana reklam verebilirsiniz</p>'
            . $contactButton
            . '</div></div>';
    }

    /**
     * Render a full-size placeholder for slider ads (fills entire slide area).
     */
    private function renderSliderPlaceholder(string $position): string
    {
        $label = self::POSITION_LABELS[$position] ?? $position;
        $phone = $this->getContactPhone();

        $whatsappMessage = urlencode('Merhaba, sitenizde "' . $label . '" reklam alanı hakkında bilgi almak istiyorum.');
        $contactButton = '';

        if ($phone) {
            $cleanPhone = preg_replace('/[^0-9]/', '', $phone);
            $contactButton = '<a href="https://wa.me/' . $cleanPhone . '?text=' . $whatsappMessage . '" '
                . 'target="_blank" rel="noopener noreferrer" '
                . 'class="inline-flex items-center gap-2 text-sm bg-green-500 hover:bg-green-600 text-white font-semibold px-6 py-2.5 rounded-full transition-colors shadow-lg hover:shadow-xl">'
                . '<i class="fab fa-whatsapp text-lg"></i> İletişime Geç</a>';
        } else {
            $contactButton = '<span class="inline-flex items-center gap-1 text-sm text-gray-400 font-medium">'
                . '<i class="fab fa-whatsapp"></i> İletişim bilgisi henüz eklenmedi</span>';
        }

        return '<div style="width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;">'
            . '<div style="width:80px;height:80px;border-radius:50%;background:rgba(255,255,255,0.1);display:flex;align-items:center;justify-content:center;">'
            . '<i class="fas fa-ad" style="font-size:2.5rem;color:#fb923c;"></i>'
            . '</div>'
            . '<p style="font-size:1.25rem;font-weight:700;color:rgba(255,255,255,0.9);margin:0;">' . htmlspecialchars($label) . '</p>'
            . '<p style="font-size:0.875rem;color:rgba(255,255,255,0.6);margin:0;">Bu alana reklam verebilirsiniz</p>'
            . $contactButton
            . '</div>';
    }
}
