<?PHP
/**
 * Class containing static functions for splitting an actor name into given name and family name.
 *
 * @author Joshua Ramon Enslin <joshua@museum-digital.de>
 */
declare(strict_types = 1);

/**
 * Class for splitting actor names.
 */
final class NodaNameSplitter {

    const LANGS_FAMILY_NAME_FIRST = [
        'hu'
    ];

    /** @var string */
    private string $_lang;

    /**
     * Returns assumed given name and family name based on an input string.
     *
     * @param string $fullName Input string.
     *
     * @return array{family_name: string, given_name: string}
     */
    public function givenNameFamilyNameFromString(string $fullName):array {

        $words = array_diff(explode(' ', $fullName), ['']);
        if (count($words) <= 1) {
            return [
                'family_name' => '',
                'given_name' => $fullName,
            ];
        }

        // Languages, which have names starting with the family name, need to have a special
        // way of splitting up the full name as follows.
        if (in_array($this->_lang, self::LANGS_FAMILY_NAME_FIRST, true)) {
            $familyName = array_shift($words);
            $givenName = implode(' ', $words);
            return [
                'family_name' => $familyName,
                'given_name' => $givenName,
            ];
        }

        // If the first "word" / name part of the name ends with a comma, it is assumed to be
        // a family name.

        if (substr($words[0], -1) === ',') {

            $familyName = substr(array_shift($words), 0, -1);
            $givenName = implode(' ', $words);
            return [
                'family_name' => $familyName,
                'given_name' => $givenName,
            ];

        }

        $familyName = array_pop($words);
        $givenName = implode(' ', $words);
        return [
            'family_name' => $familyName,
            'given_name' => $givenName,
        ];

    }

    /**
     * Assembles first name and given name into a common name as pronounced in the given language.
     *
     * @param string $givenName  Given name of the actor.
     * @param string $familyName Family name of the actor.
     * @param string $toAdd      Additional information to add to the name.
     *
     * @return string
     */
    public function assembleNameParts(string $givenName, string $familyName, string $toAdd = ''):string {

        if (in_array($this->_lang, self::LANGS_FAMILY_NAME_FIRST, true)) {
            return trim($familyName) . ' ' . trim($givenName) . $toAdd;
        }

        return trim($givenName . ' ' . $familyName) . $toAdd;

    }

    /**
     * Constructor.
     *
     * @param string $lang The user's language.
     *
     * @return void
     */
    public function __construct(string $lang) {

        $this->_lang = $lang;

    }
}
