<?php

namespace App\Services;

use App\Models\LandingPage;
use App\Models\LandingPageGeneration;
use App\Support\CatalogProductLinkMatcher;
use App\Support\CatalogValidClickSubid;
use App\Support\CatalogValidClickUrl;
use DOMDocument;
use DOMElement;
use DOMNodeList;

class CatalogLandingPageAffiliateDocument
{
    public function apply(LandingPage $page, ?string $utmSource, ?string $utmCampaign): string
    {
        $generation = $page->relationLoaded('generation')
            ? $page->generation
            : $page->generation()->first();

        if (! $generation instanceof LandingPageGeneration || ! $generation->hasAffiliateTracking()) {
            return $page->renderedDocument();
        }

        $affId = $generation->affiliateId();
        $campaignId = $generation->admediaCampaignId();

        if ($affId === null || $campaignId === null) {
            return $page->renderedDocument();
        }

        return $this->wrapProductLinks(
            $page->renderedDocument(),
            $affId,
            $campaignId,
            CatalogValidClickSubid::fromUtm($utmSource, $utmCampaign),
        );
    }

    private function wrapProductLinks(string $html, string $affId, string $campaignId, string $subid): string
    {
        $dom = new DOMDocument;
        $dom->preserveWhiteSpace = true;

        libxml_use_internal_errors(true);
        $loaded = $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
        libxml_clear_errors();

        if (! $loaded) {
            return $html;
        }

        /** @var DOMNodeList<DOMElement> $links */
        $links = $dom->getElementsByTagName('a');

        for ($index = $links->length - 1; $index >= 0; $index--) {
            $link = $links->item($index);

            if (! $link instanceof DOMElement || ! CatalogProductLinkMatcher::isProductCta($link)) {
                continue;
            }

            $destination = trim($link->getAttribute('href'));

            if ($destination === '' || str_contains(strtolower($destination), 'click.validclick.net/')) {
                continue;
            }

            $link->setAttribute(
                'href',
                CatalogValidClickUrl::build($affId, $campaignId, $subid, $destination),
            );
        }

        $output = $dom->saveHTML();

        return is_string($output) ? $output : $html;
    }
}
