<?php

namespace App\Classes\General\Services;


class GeneratesInitials
{
    protected $length = 3;
    protected $initials = 'CWW';
    protected $keepCase = false;
    protected $name = 'CIEF Worldwide';

    /**
     * Set the name used for generating initials.
     *
     * @param string $nameOrInitials
     *
     * @return GeneratesInitials
     */
    public function name($nameOrInitials)
    {
        $this->generate($nameOrInitials);

        return $this;
    }

    /**
     * Set if should keep lettercase on name.
     * Setting this to false (default) will uppercase the name.
     *
     * @param boolean $keepCase
     *
     * @return GeneratesInitials
     */
    public function keepCase($keepCase = true)
    {
        $this->keepCase = $keepCase;

        return $this;
    }

    /**
     * Set the length of the generated initials.
     *
     * @param int $length
     *
     * @return GeneratesInitials
     */
    public function length($length = 2)
    {
        $this->length = (int) $length;
        $this->initials = $this->generateInitials();

        return $this;
    }

    /**
     * Generate the initials.
     *
     * @param null|string $name
     *
     * @return string
     */
    public function generate($name = null)
    {
        if ($name !== null) {
            $this->name = $name;
            $this->initials = $this->generateInitials();
        }

        return (string) $this;
    }

    /**
     * Will return the generated initials.
     *
     * @return string
     */
    public function getInitials()
    {
        return $this->initials;
    }

    /**
     * Return the initials.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->getInitials();
    }

    /**
     * Generate a two-letter initial from a name,
     * and if no name, assume its already initials.
     * For safety, we limit it to two characters,
     * in case its a single, but long, name.
     *
     * @return string
     */
    protected function generateInitials()
    {
        $nameOrInitials = trim($this->name);

        if( !$this->keepCase ) {
            $nameOrInitials = mb_strtoupper($nameOrInitials);
        }

        $nameOrInitials = trim( trim( $nameOrInitials, '-' ) );

        $names = explode(' ', $nameOrInitials);

        // Get names with dash (-) between into separate names
        $names = array_map( static function ($namePart) { return explode('-', $namePart); }, $names );
        $realNames = [];

        foreach( new \RecursiveIteratorIterator( new \RecursiveArrayIterator($names) ) as $namePart ) {
            $realNames[] = $namePart;
        }

        $names = $realNames;

        $initials = $nameOrInitials;
        $assignedNames = 0;

        if (count($names) > 1) {
            $initials = '';
            $start = 0;

            for ($i = 0; $i < $this->length; $i++) {
                $index = $i;

                if (($index === ($this->length - 1) && $index > 0) || ($index > (count($names) - 1))) {
                    $index = count($names) - 1;
                }

                if ($assignedNames >= count($names)) {
                    $start++;
                }

                $initials .= mb_substr($names[$index], $start, 1);
                $assignedNames++;
            }
        }

        $initials = mb_substr($initials, 0, $this->length);

        return $initials;
    }

}