<?php
declare(strict_types=1);

if (!function_exists('veiculo_modelo_base')) {
    function veiculo_modelo_base(string $nome): string
    {
        $nome = html_entity_decode($nome, ENT_QUOTES | ENT_HTML5, 'UTF-8');
        $nome = str_replace(["\t", "\n", "\r"], ' ', $nome);
        $nome = preg_replace('/\([^)]*\)/u', ' ', $nome) ?? $nome;
        $nome = preg_replace('/\bSed\./iu', 'Sedan ', $nome) ?? $nome;
        $nome = preg_replace('/\bSed\b/iu', 'Sedan', $nome) ?? $nome;
        $nome = preg_replace('/\bHat\./iu', 'Hatch ', $nome) ?? $nome;
        $nome = preg_replace('/\bHat\b/iu', 'Hatch', $nome) ?? $nome;
        $nome = preg_replace('/\bP[-.]?Up\b/iu', 'Pick-Up', $nome) ?? $nome;
        $nome = preg_replace('/\s+\/\s*Sedan\b/iu', ' Sedan', $nome) ?? $nome;
        $nome = preg_replace('/\bS\.W\.?\b/iu', 'SW', $nome) ?? $nome;
        $nome = preg_replace('/\bFurg\./iu', 'Furgão ', $nome) ?? $nome;
        $nome = preg_replace('/\bSportb\./iu', 'Sportback ', $nome) ?? $nome;
        $nome = preg_replace('/\bSport\./iu', 'Sport ', $nome) ?? $nome;
        $nome = preg_replace('/\bPerf\./iu', 'Performance ', $nome) ?? $nome;
        $nome = preg_replace('/\bAmbit\./iu', 'Ambition ', $nome) ?? $nome;
        $nome = preg_replace('/\bAttra\./iu', 'Attraction ', $nome) ?? $nome;
        $nome = preg_replace('/\s+/', ' ', trim($nome)) ?? '';

        if ($nome === '') {
            return '';
        }

        $tokens = preg_split('/\s+/', $nome) ?: [];
        $base = [];

        foreach ($tokens as $token) {
            $limpo = veiculo_modelo_token_normalizado($token);
            if ($limpo === '') {
                continue;
            }

            if (
                $base !== []
                && veiculo_modelo_base_tem_carroceria($base)
                && !veiculo_modelo_token_carroceria($limpo)
            ) {
                break;
            }

            if ($base !== [] && veiculo_modelo_token_para_versao($token, $limpo, count($base))) {
                break;
            }

            if ($base !== [] && veiculo_modelo_token_acabamento($limpo) && !veiculo_modelo_token_carroceria($limpo)) {
                break;
            }

            $base[] = $token;

            if (count($base) >= 4 && !veiculo_modelo_token_carroceria($limpo)) {
                break;
            }
        }

        if ($base === []) {
            $base[] = $tokens[0] ?? $nome;
        }

        while (count($base) > 1) {
            $ultimo = veiculo_modelo_token_normalizado((string) end($base));
            if (!veiculo_modelo_token_acabamento($ultimo) || veiculo_modelo_token_carroceria($ultimo)) {
                break;
            }
            array_pop($base);
        }

        $modelo = implode(' ', $base);
        $modelo = preg_replace('/\s+/', ' ', trim($modelo)) ?? '';
        $modelo = preg_replace('/\b(Sedan|Hatch|Hatchback|Pick-Up|SW|Weekend|Variant|Cargo|Furgão|Van|Minibus)\s+\1\b/iu', '$1', $modelo) ?? $modelo;
        $modelo = trim($modelo, " \t\n\r\0\x0B./,-");

        return $modelo;
    }

    function veiculo_modelo_token_normalizado(string $token): string
    {
        $token = function_exists('mb_strtolower') ? mb_strtolower($token, 'UTF-8') : strtolower($token);
        $transliterado = function_exists('iconv') ? @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $token) : false;
        if (is_string($transliterado) && $transliterado !== '') {
            $token = $transliterado;
        }
        return preg_replace('/[^a-z0-9-]/', '', $token) ?? '';
    }

    function veiculo_modelo_token_carroceria(string $token): bool
    {
        static $tokens = [
            'sedan' => true,
            'hatch' => true,
            'hatchback' => true,
            'sportback' => true,
            'spb' => true,
            'sb' => true,
            'cabriolet' => true,
            'coupe' => true,
            'ev' => true,
            'euv' => true,
            'hb' => true,
            'avant' => true,
            'wagon' => true,
            'weekend' => true,
            'cross' => true,
            'sw' => true,
            'pickup' => true,
            'pick-up' => true,
            'p-up' => true,
            'cabine' => true,
            'dupla' => true,
            'simples' => true,
            'cd' => true,
            'cs' => true,
            'ce' => true,
            'cab' => true,
            'cargo' => true,
            'chassi' => true,
            'furgao' => true,
            'van' => true,
            'roadster' => true,
            'minibus' => true,
        ];

        return isset($tokens[$token]);
    }

    function veiculo_modelo_base_tem_carroceria(array $tokens): bool
    {
        foreach ($tokens as $token) {
            if (veiculo_modelo_token_carroceria(veiculo_modelo_token_normalizado((string) $token))) {
                return true;
            }
        }

        return false;
    }

    function veiculo_modelo_token_acabamento(string $token): bool
    {
        static $tokens = [
            'active' => true,
            'advance' => true,
            'advanc' => true,
            'advanced' => true,
            'adventure' => true,
            'allure' => true,
            'ambiente' => true,
            'ambition' => true,
            'auth' => true,
            'authent' => true,
            'authentic' => true,
            'authentique' => true,
            'attraction' => true,
            'attractive' => true,
            'autobio' => true,
            'autobiography' => true,
            'audace' => true,
            'black' => true,
            'blackmotion' => true,
            'bluemotion' => true,
            'business' => true,
            'busin' => true,
            'campus' => true,
            'carbon' => true,
            'celeb' => true,
            'classic' => true,
            'cl' => true,
            'collection' => true,
            'comfort' => true,
            'comfortline' => true,
            'comf' => true,
            'compet' => true,
            'confort' => true,
            'connect' => true,
            'country' => true,
            'cplus' => true,
            'cstyle' => true,
            'drive' => true,
            'dyna' => true,
            'dynamique' => true,
            'ed' => true,
            'edx' => true,
            'edition' => true,
            'edit' => true,
            'eleg' => true,
            'elegance' => true,
            'elite' => true,
            'el' => true,
            'elx' => true,
            'endurance' => true,
            'entry' => true,
            'essence' => true,
            'evolution' => true,
            'ex' => true,
            'exclusive' => true,
            'exp' => true,
            'expres' => true,
            'expression' => true,
            'feel' => true,
            'first' => true,
            'full' => true,
            'freedom' => true,
            'fun' => true,
            'gl' => true,
            'gli' => true,
            'gls' => true,
            'glx' => true,
            'griffe' => true,
            'graphite' => true,
            'gt' => true,
            'gts' => true,
            'gsi' => true,
            'high' => true,
            'highline' => true,
            'hig' => true,
            'hl' => true,
            'hlx' => true,
            'iconic' => true,
            'imotion' => true,
            'impetus' => true,
            'impulse' => true,
            'intense' => true,
            'laredo' => true,
            'launch' => true,
            'launching' => true,
            'limited' => true,
            'lim' => true,
            'live' => true,
            'loc' => true,
            'ls' => true,
            'lt' => true,
            'ltz' => true,
            'lx' => true,
            'luxury' => true,
            'm' => true,
            'maxx' => true,
            'modern' => true,
            'nokia' => true,
            'opening' => true,
            'outsider' => true,
            'pepper' => true,
            'performance' => true,
            'perfo' => true,
            'perfor' => true,
            'performa' => true,
            'performace' => true,
            'perfornace' => true,
            'plus' => true,
            'pplus' => true,
            'precision' => true,
            'prem' => true,
            'premier' => true,
            'prestige' => true,
            'prest' => true,
            'premium' => true,
            'prime' => true,
            'privil' => true,
            'privilege' => true,
            'protection' => true,
            'ranch' => true,
            'rallye' => true,
            'rline' => true,
            'robust' => true,
            'route' => true,
            'rs' => true,
            's' => true,
            's-line' => true,
            'security' => true,
            'selection' => true,
            'seleao' => true,
            'sense' => true,
            'spirit' => true,
            'special' => true,
            'sport' => true,
            'sporting' => true,
            'sportway' => true,
            'stepway' => true,
            'sublime' => true,
            'tech' => true,
            'techrun' => true,
            'titanium' => true,
            'top' => true,
            'tributo' => true,
            'track' => true,
            'trekking' => true,
            'trendline' => true,
            'urban' => true,
            'urbantech' => true,
            'vibe' => true,
            'volcano' => true,
            'way' => true,
            'wind' => true,
            'working' => true,
            'xtreme' => true,
            'xle' => true,
            'xli' => true,
            'xls' => true,
            'xlt' => true,
            'xre' => true,
            'xrs' => true,
            'xrv' => true,
            'abarth' => true,
            'absolute' => true,
            'action' => true,
            'activ' => true,
            'activa' => true,
            'advan' => true,
            'advant' => true,
            'advantage' => true,
            'air' => true,
            'attrac' => true,
            'attracti' => true,
            'barretos' => true,
            'blackjack' => true,
            'branco' => true,
            'champ' => true,
            'celebration' => true,
            'ciao' => true,
            'citymatic' => true,
            'city' => true,
            'colina' => true,
            'comodoro' => true,
            'conquest' => true,
            'cult' => true,
            'dark' => true,
            'diamond' => true,
            'diplomata' => true,
            'effect' => true,
            'exec' => true,
            'executive' => true,
            'exclus' => true,
            'excl' => true,
            'ext' => true,
            'extreme' => true,
            'fifty' => true,
            'flash' => true,
            'freeride' => true,
            'fx4' => true,
            'ghia' => true,
            'gtx' => true,
            'hard' => true,
            'horse' => true,
            'image' => true,
            'intensive' => true,
            'italia' => true,
            'joy' => true,
            'junior' => true,
            'life' => true,
            'locker' => true,
            'lollapalooza' => true,
            'lounge' => true,
            'luxe' => true,
            'mach-e' => true,
            'midnight' => true,
            'milenium' => true,
            'multiair' => true,
            'off' => true,
            'origem' => true,
            'origine' => true,
            'ouro' => true,
            'personnalite' => true,
            'personalite' => true,
            'platinum' => true,
            'pure' => true,
            'racer' => true,
            'raptor' => true,
            'rodeo' => true,
            'run' => true,
            'salomon' => true,
            'seduction' => true,
            'shark' => true,
            'shine' => true,
            'silver' => true,
            'smart' => true,
            'std' => true,
            'storm' => true,
            'street' => true,
            'style' => true,
            'supercharger' => true,
            'surf' => true,
            'tendance' => true,
            'tetrafuel' => true,
            'tornado' => true,
            'tremor' => true,
            'tryon' => true,
            'victoria' => true,
            'wolverine' => true,
            'xingu' => true,
            'young' => true,
            'z71' => true,
            'custom' => true,
            'de' => true,
            'dti' => true,
            'l' => true,
            'ss' => true,
            'touring' => true,
            'carat' => true,
            'cli' => true,
            'comfor' => true,
            'crossover' => true,
            'escolar' => true,
            'evidenc' => true,
            'evidence' => true,
            'exclusiv' => true,
            'gti' => true,
            'glsi' => true,
            'highli' => true,
            'i' => true,
            'last' => true,
            'lotacao' => true,
            'next' => true,
            'r-line' => true,
            'rio' => true,
            'rock' => true,
            'selecao' => true,
            'sportline' => true,
            'startline' => true,
            'standard' => true,
            'super' => true,
            'tropical' => true,
            'trooper' => true,
            'utility' => true,
            'wolfsburg' => true,
        ];

        return isset($tokens[$token]);
    }

    function veiculo_modelo_token_para_versao(string $original, string $token, int $posicao): bool
    {
        if (
            $posicao > 0
            && !veiculo_modelo_token_carroceria($token)
            && (str_contains($original, '/') || str_contains($original, '.'))
        ) {
            return true;
        }

        if (
            $posicao > 0
            && !veiculo_modelo_token_carroceria($token)
            && preg_match('/^[A-Z]{2,5}$/', trim($original, '.'))
        ) {
            return true;
        }

        if (preg_match('/\d+[.,]\d+/', $original)) {
            return true;
        }

        if (preg_match('/^\d+(?:v|cv|hp|kw|cc)$/i', $original)) {
            return true;
        }

        if (preg_match('/^\d+p$/i', $original)) {
            return true;
        }

        if ($posicao > 0 && preg_match('/^\d+[a-z]{1,3}$/i', $original)) {
            return true;
        }

        if ($posicao > 0 && preg_match('/^[a-z]{1,3}-\d+$/i', $original)) {
            return true;
        }

        if (preg_match('/^\d+$/', $token) && $posicao > 0 && (int) $token > 20) {
            return true;
        }

        static $tokens = [
            '4x2' => true,
            '4x4' => true,
            'awd' => true,
            'aut' => true,
            'automatico' => true,
            'cdi' => true,
            'cvt' => true,
            'diesel' => true,
            'dualogic' => true,
            'ecoboost' => true,
            'eletrico' => true,
            'flex' => true,
            'fwd' => true,
            'gas' => true,
            'gasolina' => true,
            'gnv' => true,
            'hib' => true,
            'hibrido' => true,
            'hybrid' => true,
            'mec' => true,
            'multijet' => true,
            'multitronic' => true,
            'mpi' => true,
            'powershift' => true,
            'quattro' => true,
            's-tronic' => true,
            'stronic' => true,
            'tce' => true,
            'tdi' => true,
            'tfsi' => true,
            'thp' => true,
            'tip' => true,
            'tiptronic' => true,
            'tsi' => true,
            'turbo' => true,
            'vtec' => true,
            'vvt' => true,
        ];

        if (isset($tokens[$token])) {
            return true;
        }

        foreach (['flex', 'hiflex', 'flexpower', 'mpfi', 'diesel', 'tdiesel', 'dual', 'dualogic', 'easyr', 'fire', 'evo', 'turbo', 'power', 'motion'] as $parte) {
            if (str_contains($token, $parte)) {
                return true;
            }
        }

        return false;
    }
}
