<?php

namespace App\Services\LinkedIn;

/**
 * Normalises and formats LinkedIn URNs and bare IDs.
 */
class LinkedInUrn
{
    public static function account(string $id): string
    {
        return str_starts_with($id, 'urn:li:sponsoredAccount:')
            ? $id
            : 'urn:li:sponsoredAccount:'.ltrim($id, '_');
    }

    public static function campaignGroup(string $id): string
    {
        return str_starts_with($id, 'urn:li:sponsoredCampaignGroup:')
            ? $id
            : 'urn:li:sponsoredCampaignGroup:'.$id;
    }

    public static function campaign(string $id): string
    {
        return str_starts_with($id, 'urn:li:sponsoredCampaign:')
            ? $id
            : 'urn:li:sponsoredCampaign:'.$id;
    }

    public static function creative(string $id): string
    {
        return str_starts_with($id, 'urn:li:sponsoredCreative:')
            ? $id
            : 'urn:li:sponsoredCreative:'.$id;
    }

    public static function organization(string $id): string
    {
        return str_starts_with($id, 'urn:li:organization:')
            ? $id
            : 'urn:li:organization:'.$id;
    }

    /**
     * Extracts the trailing bare ID from any URN.
     */
    public static function bare(string $urn): string
    {
        if (! str_contains($urn, ':')) {
            return $urn;
        }

        $parts = explode(':', $urn);

        return (string) end($parts);
    }

    /**
     * The bare id, but only when it is one LinkedIn can accept.
     *
     * Every LinkedIn id is a number, and every path built from one is
     * `rest/adAccounts/{number}`. bare() never checked: anything without a colon
     * came back unchanged, so a Meta-style `act_1950320145707342`, or an account
     * name the buyer typed instead of an id, went into the URL as it stood.
     *
     * LinkedIn's answer to that is `Failed to convert ... to java.lang.Long`,
     * which is what appeared in the chat. It names a Java type, says nothing about
     * what was wrong, and reads like a fault in the product rather than a value
     * that needs correcting - so the buyer had nothing to act on and neither did
     * anyone reading the log.
     *
     * Null rather than an exception, so the caller decides what to say. The tool
     * has a buyer to talk to; the transport does not.
     */
    public static function numericId(string $urn): ?string
    {
        $id = trim(self::bare(trim($urn)));

        return preg_match('/^\d+$/', $id) === 1 ? $id : null;
    }
}
