<?php

namespace App\Services\Meta;

/**
 * Finds the id of a newly created object.
 *
 * Meta uses a different key depending on the transport: the Graph API returns
 * `id`, the MCP returns `campaign_id`, `ad_set_id` and so on. Missing it is not
 * cosmetic, it means a rollback has nothing to roll back, so every known shape
 * is checked.
 */
class ObjectId
{
    private const KEYS = ['id', 'campaign_id', 'ad_set_id', 'adset_id', 'ad_id', 'creative_id', 'ad_creative_id'];

    public static function find(array $response): ?string
    {
        foreach (self::KEYS as $key) {
            if (! empty($response[$key]) && is_scalar($response[$key])) {
                return (string) $response[$key];
            }
        }

        foreach ($response as $value) {
            if (is_array($value) && ($nested = self::find($value)) !== null) {
                return $nested;
            }
        }

        return null;
    }

    /** @throws MetaException when the id cannot be found, rather than failing silently. */
    public static function require(array $response, string $what): string
    {
        return self::find($response) ?? throw new MetaException(sprintf(
            'Created the %s but could not find its id in the response: %s',
            $what,
            mb_substr(json_encode($response), 0, 300),
        ));
    }
}
