<?php

namespace Intgrtn\Lib;

class Stripper
{

    private $replaceWithSpace = [
        '.',
        ',',
    ];
    private $titles = [
        'Mr',
        'Mrs',
        'Ms',
        'Miss',
        'Dr',
        'Sir',
        'Md',
        'Ma',
        'Minister',
    ];
    private $initialsForCapitalCase = [
        'jo',
        'si',
        'al',
        'bo',
        'di',
        'fi',
        'jo',
        'mo',
        'vi',
        'te',
        'ko',
    ];
    private $predefinedNames = [
        ['output' => 'AJ', 'input' => 'A J'],
        ['output' => 'Le Quoc Toan', 'input' => 'Le Quoc Toan'],
        ['output' => 'Ho Wui Lee', 'input' => 'Ho Wui Lee']
    ];
    private $nobiliarityParticles = [
        'De'
    ];
    private $surnamePrefixes = [
    ];
    private $capitalizeWords = [
        'Mc',
    ];

    public function capitalize($name)
    {
        if (!in_array(strtolower($name), $this->initialsForCapitalCase)) {
            return strtoupper($name);
        } else {
            return $name;
        }
    }

    public function surnamePrefixCapitalizer($name)
    {
        //check if name begins with some prefix
        foreach ($this->surnamePrefixes as $prefix) {
            $regex = '/' . $prefix . '/A';
            if (preg_match($regex, $name)) {
                // remove prefix
                $prefixlessName = str_replace($prefix, '', $name);
                return $prefix . ucwords($prefixlessName);
            }
        }

        return $name;
    }

    public function capitalizeWord($word)
    {
        foreach ($this->capitalizeWords as $cWord) {
            if ($pos = stripos($word, $cWord) !== false) {
                if ($pos == 1) {
                    $explodeWord = substr($word, ($pos + 1), strlen($word));
                    $explodedWord = explode($explodeWord, $word);
                    return strtoupper($explodedWord[0]) . ucfirst($explodeWord);
                }
            }
        }
        return $word;
    }

    public function stripBadName($name)
    {
        $regExp = '/[^a-zA-Z.\s-]([^@].*)/';
        $result = preg_replace($regExp, '', $name);
        $result = strtolower($result);

        if (preg_match('/-/', $result)) {
            $explodeName = explode('-', $result);

            $result = ucwords($explodeName[0]) . '-' . ucwords($explodeName[1]);

            return $this->capitalizeWord($result);
        }

        return $this->capitalizeWord($result);
    }

    public function strippedName($name)
    {

        if ((int) $name) {
            return $name;
        }

        $result = $this->stripBadName($name);

        //replace certain characters with space
        foreach ($this->replaceWithSpace as $value) {
            $result = str_replace($value, ' ', $result);
        }

        //TODO get only alpha characters
        //trim
        $result = trim($result);

        //remove apostrophe from the end of string
        $result = rtrim($result, "'");

        //replace double space with single space
        $result = str_replace('  ', ' ', $result);

        //upper case each word
        $result = ucwords($result);

        foreach ($this->predefinedNames as $value) {
            if ($value['input'] == $result) {
                return $value['output'];
            }
        }

        // check for name prefix
        $result = $this->surnamePrefixCapitalizer($result);


        //explode the string on spaces
        $parts = explode(' ', $result);

        if (strlen($parts[0]) == 1 && isset($parts[1]) && strlen($parts[1]) == 1) {
            return $result;
        }

        if (!in_array($parts[0], $this->titles) && !in_array($parts[0], $this->nobiliarityParticles) && strlen($parts[0]) == 2) {
            return $this->capitalize($parts[0]);
        }


        for ($i = 0; $i < count($parts); $i++) {
            if (in_array($parts[$i], $this->titles) || in_array($parts[$i], $this->nobiliarityParticles)) {
                if (isset($parts[$i + 1]) && strlen($parts[$i + 1]) == 2) {
                    return $this->capitalize($parts[$i + 1]);
                } else if (isset($parts[$i + 1]) && strlen($parts[$i + 1]) > 2 && !in_array($parts[$i], $this->nobiliarityParticles)) {
                    return $parts[$i + 1];
                } else {
                    for ($ii = $i + 1; $ii < count($parts); $ii++) {
                        if (strlen($parts[$ii]) > 2) {
                            if ($ii == 2 && count($parts) == 4 && strlen($parts[1]) == 1) {
                                return $parts[$ii];
                            } else {
                                return $parts[$i] . ' ' . $parts[$ii];
                            }
                        }
                    }
                }
            } else if (strlen($parts[$i]) > 1) {
                return $parts[$i];
            }
        }


        return $name;
    }

}
