<?php

namespace classes;

final class workfeed_employee_name_formatter
{
    /**
     * @param array<int,string> $firstNamePaths
     * @param array<int,string> $lastNamePaths
     * @param array<int,string> $fallbackNamePaths
     */
    public static function fromRecord(
        mixed $record,
        array $firstNamePaths,
        array $lastNamePaths,
        array $fallbackNamePaths = [],
        ?string $employeeId = null
    ): ?string {
        $firstName = self::firstTextValueByPath($record, $firstNamePaths);
        $lastName = self::firstTextValueByPath($record, $lastNamePaths);

        $schemaName = self::joinNameParts($firstName, $lastName);
        if ($schemaName !== null) {
            return $schemaName;
        }

        foreach ($fallbackNamePaths as $path) {
            $name = self::normalizeTextValue(self::valueByPath($record, $path));
            if ($name !== null && !self::isMissingDisplayName($name, $employeeId)) {
                return $name;
            }
        }

        return null;
    }

    public static function isMissingDisplayName(?string $employeeName, ?string $employeeId = null): bool
    {
        if ($employeeName === null) {
            return true;
        }

        if ($employeeId !== null && strcasecmp($employeeName, 'Employee ' . $employeeId) === 0) {
            return true;
        }

        return strcasecmp($employeeName, 'Unknown employee') === 0;
    }

    /**
     * @param array<int,string> $paths
     */
    private static function firstTextValueByPath(mixed $record, array $paths): ?string
    {
        foreach ($paths as $path) {
            $value = self::normalizeTextValue(self::valueByPath($record, $path));
            if ($value !== null) {
                return $value;
            }
        }

        return null;
    }

    private static function joinNameParts(?string $firstName, ?string $lastName): ?string
    {
        $name = trim((string)($firstName ?? '') . ' ' . (string)($lastName ?? ''));

        return $name !== '' ? $name : null;
    }

    private static function valueByPath(mixed $record, string $path): mixed
    {
        $segments = explode('.', $path);
        $value = $record;
        foreach ($segments as $segment) {
            if (is_array($value) && array_key_exists($segment, $value)) {
                $value = $value[$segment];
                continue;
            }

            if (is_object($value) && isset($value->{$segment})) {
                $value = $value->{$segment};
                continue;
            }

            return null;
        }

        return $value;
    }

    private static function normalizeTextValue(mixed $value): ?string
    {
        if (!is_scalar($value)) {
            return null;
        }

        $normalized = trim((string)$value);

        return $normalized !== '' ? $normalized : null;
    }
}
