<?php

namespace classes;

class customer_name_cache_payload_builder
{
    /**
     * @return array{name:string}|null
     */
    public static function build(mixed $cached_name, ?string $fallback_name): ?array
    {
        $cached_name = self::normalizePayload($cached_name);
        $name = self::extractName($cached_name);
        if ($name !== null) {
            return ['name' => $name];
        }

        $fallback_name = self::normalizeName($fallback_name);
        if ($fallback_name !== null) {
            return ['name' => $fallback_name];
        }

        return null;
    }

    private static function normalizePayload(mixed $payload): mixed
    {
        if (!is_string($payload)) {
            return $payload;
        }

        $trimmed = trim($payload);
        if ($trimmed === '') {
            return null;
        }

        $decoded = json_decode($trimmed);
        if (json_last_error() === JSON_ERROR_NONE) {
            return $decoded;
        }

        return $trimmed;
    }

    private static function extractName(mixed $payload): ?string
    {
        if (is_string($payload)) {
            return self::normalizeName($payload);
        }

        if (!is_object($payload) && !is_array($payload)) {
            return null;
        }

        foreach (['name', 'customerName', 'customer_name', 'displayName', 'display_name'] as $key) {
            $name = self::normalizeName(self::payloadValue($payload, $key));
            if ($name !== null) {
                return $name;
            }
        }

        foreach (['customer', 'data', 'economic_customer'] as $key) {
            $name = self::extractName(self::payloadValue($payload, $key));
            if ($name !== null) {
                return $name;
            }
        }

        return null;
    }

    private static function payloadValue(mixed $payload, string $key): mixed
    {
        if (is_object($payload) && property_exists($payload, $key)) {
            return $payload->{$key};
        }

        if (is_array($payload) && array_key_exists($key, $payload)) {
            return $payload[$key];
        }

        return null;
    }

    private static function normalizeName(mixed $name): ?string
    {
        if (!is_string($name)) {
            return null;
        }

        $name = trim($name);
        return $name === '' ? null : $name;
    }
}
