<?php

namespace Spatie\Emoji;

use Spatie\Emoji\Exceptions\CouldNotDetermineFlag;
use Spatie\Emoji\Exceptions\UnknownCharacter;

/**
 * Emoji class.
 *
 * @link {{ url }}
 * @version {{ version }}
 * loaded at: {{ loaded_at|date('Y-m-d H:i:s') }}
 *
{% for group, subgroups in groups %}
 * ##### Emoji group: {{ group|upper }} #####
{% for subgroup, emojis in subgroups %}
 * ##### Emoji subgroup: {{ subgroup|upper }} #####
{% for emoji in emojis %}
 * @method static string {{ emoji.method }}()
{% endfor %}
{% endfor %}
{% endfor %}
 */
class Emoji
{
{% for group, subgroups in groups %}
    // ##### Emoji group: {{ group|upper }} #####
{% for subgroup, emojis in subgroups %}
    // ##### Emoji subgroup: {{ subgroup|upper }} #####
{% for emoji in emojis %}
    public const {{ emoji.const }} = "{{ emoji.code }}";
{% endfor %}
{% endfor %}
{% endfor %}

    public static function getCharacter(string $characterName): string
    {
        $constantName = static::convertCharacterNameToConstantName($characterName);

        if (! defined("static::{$constantName}")) {
            throw UnknownCharacter::create($characterName);
        }

        return constant('static::'.$constantName);
    }

    public static function countryFlag(string $countryCode): string
    {
        if (strlen($countryCode) !== 2) {
            throw CouldNotDetermineFlag::countryCodeLenghtIsWrong($countryCode);
        }

        $countryCode = mb_strtoupper($countryCode);

        return static::encodeCountryCodeLetter($countryCode[0]).static::encodeCountryCodeLetter($countryCode[1]);
    }

    public static function all(): array
    {
        $reflectionClass = new \ReflectionClass(self::class);

        return $reflectionClass->getConstants();
    }

    public static function __callStatic(string $methodName, array $parameters): string
    {
        return static::getCharacter($methodName);
    }

    protected static function convertCharacterNameToConstantName(string $characterName): string
    {
        $partialConstantName = static::convertToSnakeCase($characterName);

        $constantName = 'CHARACTER_'.mb_strtoupper($partialConstantName);

        return $constantName;
    }

    protected static function convertToSnakeCase(string $value): string
    {
        if (! ctype_lower($value)) {
            $value = preg_replace('/\s+/', '', $value);

            $value = mb_strtolower(preg_replace('/([^0-9])(?=[0-9])/', '$1'.'_', preg_replace('/(.)(?=[A-Z])/', '$1'.'_', $value)));
        }

        return $value;
    }

    protected static function encodeCountryCodeLetter(string $letter): string
    {
        return mb_convert_encoding('&#'.(127397 + ord($letter)).';', 'UTF-8', 'HTML-ENTITIES');
    }
}
