<?php

namespace App\Campaigns;

use App\Models\Campaign;

/**
 * The destination URL as it is actually sent to the platform.
 *
 * The tracking parameters are appended here rather than stored joined onto the
 * landing page URL, so the two stay separately editable and the panel can keep
 * showing the page the user named rather than a URL they did not write.
 *
 * Appended to the URL rather than sent in Meta's url_tags field on purpose:
 * the ad creative is built by two transports, and only one of them is known to
 * accept url_tags. A URL is a URL to both.
 */
class TrackedUrl
{
    /** The landing page with this campaign's tracking on the end. */
    public static function for(Campaign $campaign): string
    {
        return self::build((string) $campaign->landing_url, (string) $campaign->utm);
    }

    public static function build(string $url, string $utm): string
    {
        $utm = trim($utm, " \t\n\r\0\x0B?&");

        if ($url === '' || $utm === '') {
            return $url;
        }

        // A landing page frequently already carries parameters of its own, and
        // a second question mark silently breaks the whole query string.
        $separator = str_contains($url, '?') ? '&' : '?';

        // A fragment has to stay at the end or the browser keeps it and drops
        // everything after it from the query.
        [$base, $fragment] = array_pad(explode('#', $url, 2), 2, null);

        return $base.$separator.$utm.($fragment === null ? '' : '#'.$fragment);
    }

    /**
     * What the parameters look like once Meta has filled its macros in.
     *
     * Only for showing the user, which is the point: {{campaign.name}} in a
     * summary tells them nothing about whether the tagging is right.
     */
    public static function asExample(Campaign $campaign): string
    {
        return strtr(self::for($campaign), [
            '{{campaign.name}}' => $campaign->name ?: 'campaign',
            '{{adset.name}}' => ($campaign->name ?: 'campaign').' - ad set',
            '{{ad.name}}' => ($campaign->name ?: 'campaign').' - ad 1',
            '{{placement}}' => 'facebook_feed',
            '{{site_source_name}}' => 'fb',
        ]);
    }
}
