<?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 App\Support\HtmlDocument;
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
    {
        // Script bodies and SVG names survive this round trip; see HtmlDocument.
        if (! $document = HtmlDocument::from($html, 'catalog affiliate links')) {
            return $html;
        }

        $dom = $document->dom();

        /** @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),
            );
        }

        return $document->html();
    }
}
