from collections import OrderedDict
from typing import Dict, Optional

from faker.typing import SexLiteral

from .. import ElementsType
from .. import Provider as PersonProvider


def translit(text: str) -> str:
    translit_dict: Dict[str, str] = {
        "а": "a",
        "б": "b",
        "в": "v",
        "г": "h",
        "ґ": "g",
        "д": "d",
        "е": "e",
        "є": "ie",
        "ж": "zh",
        "з": "z",
        "и": "y",
        "і": "i",
        "ї": "i",
        "й": "i",
        "к": "k",
        "л": "l",
        "м": "m",
        "н": "n",
        "о": "o",
        "п": "p",
        "р": "r",
        "с": "s",
        "т": "t",
        "у": "u",
        "ф": "f",
        "х": "kh",
        "ц": "ts",
        "ч": "ch",
        "ш": "sh",
        "щ": "shch",
        "ь": "",
        "ю": "iu",
        "я": "ia",
        "'": "",
        "ʼ": "",
        "-": "-",
        "А": "A",
        "Б": "B",
        "В": "V",
        "Г": "H",
        "Ґ": "G",
        "Д": "D",
        "Е": "E",
        "Є": "Ye",
        "Ж": "Zh",
        "З": "Z",
        "И": "Y",
        "І": "I",
        "Ї": "Yi",
        "Й": "Y",
        "К": "K",
        "Л": "L",
        "М": "M",
        "Н": "N",
        "О": "O",
        "П": "P",
        "Р": "R",
        "С": "S",
        "Т": "T",
        "У": "U",
        "Ф": "F",
        "Х": "Kh",
        "Ц": "Ts",
        "Ч": "Ch",
        "Ш": "Sh",
        "Щ": "Shch",
        "Ь": "",
        "Ю": "Yu",
        "Я": "Ya",
    }
    for letter in text:
        if letter.isalpha():
            text = text.replace(letter, translit_dict[letter])
    return text


class Provider(PersonProvider):
    formats_female = OrderedDict(
        (
            ("{{first_name_female}} {{last_name}}", 0.8),
            ("{{prefix_female}} {{first_name_female}} {{last_name}}", 0.1),
            ("{{last_name}} {{first_name_female}} {{middle_name_female}}", 0.1),
        )
    )

    formats_male = OrderedDict(
        (
            ("{{first_name_male}} {{last_name}}", 0.8),
            ("{{prefix_male}} {{first_name_male}} {{last_name}}", 0.1),
            ("{{last_name}} {{first_name_male}} {{middle_name_male}}", 0.1),
        )
    )

    formats = formats_female.copy()
    formats.update(formats_male)

    language_names: ElementsType[str] = [
        "Афарська",
        "Абхазька",
        "Авестійська",
        "Африкаанс",
        "Акан (мова)",
        "Амхара",
        "Арагонська",
        "Арабська",
        "Ассамська",
        "Аварська",
        "Аймара",
        "Азербайджанська",
        "Башкирська",
        "Білоруська",
        "Болгарська",
        "Біхарі",
        "Біслама",
        "Бамбара",
        "Бенгальська",
        "Тибетська",
        "Бретонська",
        "Боснійська",
        "Каталонська",
        "Чеченська",
        "Себуанська",
        "Чаморро",
        "Корсиканська",
        "Мова крі",
        "Чеська",
        "Церковнослов’янська",
        "Чуваська",
        "Валлійська",
        "Данська",
        "Німецька",
        "Дівехі",
        "Дзонґ-ке",
        "Еве",
        "Грецька",
        "Англійська",
        "Есперанто",
        "Іспанська",
        "Естонська",
        "Баскська",
        "Перська",
        "Фула",
        "Фінська",
        "Фіджі",
        "Фарерська",
        "Французька",
        "Західно-фризька",
        "Ірландська",
        "Шотландська гельська",
        "Галісійська",
        "Гуарані",
        "Гуджараті",
        "Менська",
        "Хауса",
        "Гавайська",
        "Іврит",
        "Гінді",
        "Гірі-моту",
        "Хорватська",
        "Гаїтянська",
        "Угорська",
        "Вірменська",
        "Гереро",
        "Інтерлінгва",
        "Індонезійська",
        "Окциденталь",
        "Ігбо",
        "Сичуань Йї",
        "Інупіак (мова)",
        "Ідо",
        "Ісландська",
        "Італійська",
        "Інуктітут",
        "Японська",
        "Яванська",
        "Грузинська",
        "Конголезька",
        "Кікуйю",
        "Кунама",
        "Казахська",
        "Гренландська",
        "Кхмерська",
        "Каннада",
        "Корейська",
        "Канурі",
        "Кашмір",
        "Курдська",
        "Комі",
        "Корнська",
        "Киргизька",
        "Латинська",
        "Люксембурзька",
        "Луганда",
        "Лімбурзька",
        "Лінґала",
        "Лаоська",
        "Литовська",
        "Луба-катанга",
        "Латиська",
        "Малагасійська",
        "Маршальська",
        "Маорі",
        "Македонська",
        "Малаялам",
        "Монгольська",
        "Маратхі",
        "Малайська",
        "Мальтійська",
        "Бірманська",
        "Науру",
        "Букмол",
        "Північна ндебеле",
        "Непальська",
        "Ндонга",
        "Нідерландська",
        "Нюношк",
        "Норвезька",
        "Південна ндебеле",
        "Навахо",
        "Ньянджа",
        "Окситанська",
        "Оджибве",
        "Орома",
        "Орія",
        "Осетинська",
        "Панджабі",
        "Палі",
        "Польська",
        "Пушту",
        "Португальська",
        "Кечуа",
        "Ретороманська",
        "Кірундійська",
        "Румунська;Молдовська",
        "Російська",
        "Кінаруанда",
        "Русинська",
        "Санскрит",
        "Сардинська",
        "Сіндхі",
        "Північносаамська",
        "Санго",
        "Сербохорватська",
        "Сингальська",
        "Словацька",
        "Словенська",
        "Самоанська",
        "Шона",
        "Сомалійська",
        "Албанська",
        "Сербська",
        "Сваті",
        "Сесото",
        "Сунданська",
        "Шведська",
        "Суахілі",
        "Тамільська",
        "Телугу",
        "Таджицька",
        "Тайська",
        "Тигрінья",
        "Туркменська",
        "Тагалог",
        "Сетсвана",
        "Тонганська",
        "Турецька",
        "Тсонґа",
        "Татарська",
        "Чві",
        "Таїтянська",
        "Уйгурська",
        "Українська",
        "Урду",
        "Узбецька",
        "Венда",
        "В'єтнамська",
        "Волапюк",
        "Валлонська",
        "Волоф",
        "Коса",
        "Їдиш",
        "Йоруба",
        "Чжуан",
        "Китайська",
        "Зулу",
    ]

    # Source: uk.wikipedia.org/wiki/Українські_імена
    first_names_male = (
        "Аарон",
        "Августин",
        "Аврелій",
        "Адам",
        "Азар",
        "Алевтин",
        "Альберт",
        "Амвросій",
        "Андрій",
        "Антон",
        "Аркадій",
        "Арсен",
        "Артем",
        "Орхип",
        "Богдан",
        "Богодар",
        "Богуслав",
        "Болеслав",
        "Борис",
        "Борислав",
        "Вадим",
        "Валентин",
        "Валерій",
        "Варфоломій",
        "Василь",
        "Венедикт",
        "Веніямин",
        "Віктор",
        "Віталій",
        "Владислав",
        "Володимир",
        "Вʼячеслав",
        "Гаврило",
        "Геннадій",
        "Георгій",
        "Герман",
        "Гордій",
        "Григорій",
        "Гліб",
        "Данило",
        "Давид",
        "Дан",
        "Демид",
        "Демʼян",
        "Дмитро",
        "Захар",
        "Зиновій",
        "Зорян",
        "Іван",
        "Ігнат",
        "Ігор",
        "Ілля",
        "Едуард",
        "Євген",
        "Єлисей",
        "Єфрем",
        "Йосип",
        "Климент",
        "Костянтин",
        "Левко",
        "Лесь",
        "Леон",
        "Леонід",
        "Леонтій",
        "Леопольд",
        "Лукʼян",
        "Кирило",
        "Макар",
        "Максим",
        "Марко",
        "Мартин",
        "Микита",
        "Миколай",
        "Мирон",
        "Мирослав",
        "Михайло",
        "Назар",
        "Нестор",
        "Олег",
        "Олекса",
        "Олександр",
        "Олесь",
        "Омелян",
        "Онисим",
        "Опанас",
        "Орест",
        "Остап",
        "Охрім",
        "Петро",
        "Павло",
        "Панас",
        "Пантелеймон",
        "Пармен",
        "Пилип",
        "Прохір",
        "Роман",
        "Ростислав",
        "Руслан",
        "Святослав",
        "Семен",
        "Сергій",
        "Симон",
        "Соломон",
        "Спас",
        "Станіслав",
        "Степан",
        "Стефан",
        "Тарас",
        "Теодор",
        "Тимофій",
        "Трохим",
        "Устим",
        "Федір",
        "Феофан",
        "Франц",
        "Хома",
        "Юстим",
        "Юхим",
        "Яків",
        "Ярема",
        "Ярослав",
    )

    first_names_female = (
        "Ада",
        "Аліна",
        "Алла",
        "Альбіна",
        "Амалія",
        "Анастасія",
        "Аніта",
        "Анжела",
        "Ганна",
        "Богуслава",
        "Богданна",
        "Валентина",
        "Варвара",
        "Василина",
        "Вікторія",
        "Віолетта",
        "Віра",
        "Володимира",
        "Галина",
        "Данна",
        "Дарина",
        "Едита",
        "Єва",
        "Єлисавета",
        "Емілія",
        "Еріка",
        "Ірина",
        "Ірена",
        "Златослава",
        "Камілла",
        "Клавдія",
        "Лариса",
        "Ліза",
        "Лілія",
        "Людмила",
        "Любов",
        "Марія",
        "Марина",
        "Марта",
        "Марʼяна",
        "Маруся",
        "Михайлина",
        "Мілена",
        "Надія",
        "Наталія",
        "Пріска",
        "Розалія",
        "Святослава",
        "Сніжана",
        "Соломія",
        "Софія",
        "Одарка",
        "Оксана",
        "Оксенія",
        "Олена",
        "Ольга",
        "Орина",
        "Орися",
        "Роксолана",
        "Світлана",
        "Тереза",
        "Тетяна",
        "Юстина",
        "Христина",
        "Ярина",
        "Ярослава",
    )

    first_names = first_names_male + first_names_female

    # Source: uk.wikipedia.org/wiki/Категорія:Українські_прізвища
    last_names = (
        "Абрагамовський",
        "Абраменко",
        "Абрамчук",
        "Авдєєнко",
        "Аверченко",
        "Авраменко",
        "Аврамчук",
        "Адаменко",
        "Адамчук",
        "Ажажа",
        "Акименко",
        "Акуленко",
        "Александренко",
        "Алексеєнко",
        "Алексійчук",
        "Алексюк",
        "Андрейко",
        "Андрієвич",
        "Андрієнко",
        "Андріїшин",
        "Андрійович",
        "Андрійчук",
        "Андрощук",
        "Андрусенко",
        "Аронець",
        "Арсенич",
        "Артеменко",
        "Артим",
        "Артимишин",
        "Артимович",
        "Артюх",
        "Артюшенко",
        "Архимович",
        "Архипенко",
        "Асаула",
        "Атаманчук",
        "Атаманюк",
        "Атрощенко",
        "Бабʼюк",
        "Бабʼяк",
        "Бабак",
        "Бабариченко",
        "Бабенко",
        "Бабич",
        "Бабиченко",
        "Бабій",
        "Бабійчук",
        "Бабко",
        "Базавлученко",
        "Базилевич",
        "Базилевський",
        "Байда",
        "Байдак",
        "Байрак",
        "Баклан",
        "Бакуменко",
        "Балабан",
        "Бандера",
        "Бандура",
        "Бандурка",
        "Барабаш",
        "Баран",
        "Баранець",
        "Бараник",
        "Баранник",
        "Батіг",
        "Батуринець",
        "Батюк",
        "Башполченко",
        "Баштан",
        "Бгиденко",
        "Бебешко",
        "Бевз",
        "Бевзенко",
        "Безбородьки",
        "Безбородько",
        "Бездітко",
        "Вакарчук",
        "Вакуленко",
        "Валенко",
        "Ванченко",
        "Василашко",
        "Василевич",
        "Василенко",
        "Василечко",
        "Ватаманюк",
        "Вахній",
        "Ващенко",
        "Ващенко-Захарченко",
        "Ващук",
        "Вдовенко",
        "Вдовиченко",
        "Величко",
        "Венгринович",
        "Вергун",
        "Верес",
        "Верменич",
        "Вернигора",
        "Вернидуб",
        "Вертипорох",
        "Верховинець",
        "Верхола",
        "Височан",
        "Вишиваний",
        "Вишняк",
        "Вівчаренко",
        "Вітер",
        "Вітрук",
        "Власенко",
        "Власюк",
        "Влох",
        "Воблий",
        "Вовк",
        "Габелко",
        "Гавриленко",
        "Гаврилець",
        "Гаврилишин",
        "Гаврилів",
        "Гаврилюк",
        "Гавриш",
        "Гавришкевич",
        "Гаврюшенко",
        "Гаєвський",
        "Гайворонський",
        "Гайда",
        "Гайдабура",
        "Гайдай",
        "Гайдамака",
        "Гайденко",
        "Гоголь",
        "Гоголь-Яновський",
        "Годунок",
        "Голик",
        "Голобородько",
        "Гресь",
        "Гречаник",
        "Гречко",
        "Гриценко",
        "Гузенко",
        "Гузій",
        "Гузь",
        "Гук",
        "Гунько",
        "Гупало",
        "Гуцуляк",
        "Ґалаґан",
        "Ґереґа",
        "Ґерета",
        "Ґерус",
        "Ґжицький",
        "Ґоляш",
        "Давиденко",
        "Давимука",
        "Даниленко",
        "Данилюк",
        "Данильчук",
        "Данченко",
        "Данчук",
        "Данькевич",
        "Даньків",
        "Данько",
        "Дараган",
        "Дахно",
        "Даценко",
        "Дацюк",
        "Дашенко",
        "Дашкевич",
        "Девдюк",
        "Дейнека",
        "Дейнеко",
        "Дейсун",
        "Демʼяненко",
        "Демʼянчук",
        "Демʼянюк",
        "Демиденко",
        "Дергач",
        "Деревʼянко",
        "Дерегус",
        "Деркач",
        "Деряжний",
        "Джунь",
        "Джус",
        "Дробʼязко",
        "Дробаха",
        "Дрозд",
        "Дрозденко",
        "Дубас",
        "Дубенко",
        "Дубина",
        "Дзиндра",
        "Дзюба",
        "Доценко",
        "Дуплій",
        "Дурдинець",
        "Дутка",
        "Ейбоженко",
        "Євдокименко",
        "Євтушенко",
        "Євтушок",
        "Ємельяненко",
        "Ємець",
        "Єременко",
        "Єресько",
        "Єрмоленко",
        "Єрошенко",
        "Єрченко",
        "Єрьоменко",
        "Єсипенко",
        "Єфименко",
        "Єщенко",
        "Жадан",
        "Жайворон",
        "Жаліло",
        "Жарко",
        "Жук",
        "Журавель",
        "Журба",
        "Жученко",
        "Забара",
        "Забарний",
        "Забашта",
        "Забіла",
        "Заєць",
        "Заїка",
        "Зайченко",
        "Закусило",
        "Запорожець",
        "Заруба",
        "Зарудний",
        "Засенко",
        "Засуха",
        "Засядько",
        "Затовканюк",
        "Затула",
        "Захаренко",
        "Захарченко",
        "Зінкевич",
        "Зінченко",
        "Зінчук",
        "Зубко",
        "Іваненко",
        "Іваничук",
        "Іванченко",
        "Івасюк",
        "Іващенко",
        "Ільєнко",
        "Ільченко",
        "Ірванець",
        "Ісаєвич",
        "Ісаєнко",
        "Іщак",
        "Іщенко",
        "Їжак",
        "Їжакевич",
        "Кабалюк",
        "Кабаненко",
        "Каденюк",
        "Калениченко",
        "Кальченко",
        "Канівець",
        "Карась",
        "Кармалюк",
        "Карпа",
        "Карпенко",
        "Кащенко",
        "Кибкало",
        "Килимник",
        "Кириленко",
        "Коваленко",
        "Ковалюк",
        "Ковпак",
        "Козак",
        "Козаченко",
        "Колесниченко",
        "Колісниченко",
        "Колодуб",
        "Комар",
        "Конопленко",
        "Конопля",
        "Копитко",
        "Корбут",
        "Корж",
        "Короленко",
        "Корпанюк",
        "Корсун",
        "Лаба",
        "Лавренко",
        "Лагода",
        "Лазаренко",
        "Левченко",
        "Лемешко",
        "Лесик",
        "Лисенко",
        "Литвин",
        "Литвиненко",
        "Лубенець",
        "Лукаш",
        "Лупій",
        "Луценко",
        "Ляшко",
        "Мазепа",
        "Мазур",
        "Макаренко",
        "Макогон",
        "Малик",
        "Малишко",
        "Мамчур",
        "Масляк",
        "Масоха",
        "Матвієнко",
        "Матяш",
        "Медведенко",
        "Микитюк",
        "Михайличенко",
        "Михайлюк",
        "Михалюк",
        "Мірошниченко",
        "Міщенко",
        "Москаль",
        "Назаренко",
        "Наливайко",
        "Негода",
        "Непорожній",
        "Нестайко",
        "Нестеренко",
        "Ніколюк",
        "Носаченко",
        "Носенко",
        "Оберемко",
        "Овсієнко",
        "Овчаренко",
        "Олійник",
        "Оліфіренко",
        "Онищенко",
        "Оніщук",
        "Онуфрієнко",
        "Опанасенко",
        "Орлик",
        "Оробець",
        "Остапчук",
        "Охримович",
        "Охріменко",
        "Пʼятаченко",
        "Павленко",
        "Павлик",
        "Павличенко",
        "Палій",
        "Панчук",
        "Парасюк",
        "Пелех",
        "Перебийніс",
        "Перепелиця",
        "Петлюра",
        "Петренко",
        "Петрик",
        "Пилипенко",
        "Піддубний",
        "Полтавець",
        "Приймак",
        "Примаченко",
        "Притула",
        "Приходько",
        "Прокопович",
        "Проценко",
        "Пустовіт",
        "Пушкар",
        "Радченко",
        "Рак",
        "Ребрик",
        "Рева",
        "Редько",
        "Романенко",
        "Романець",
        "Романчук",
        "Рубан",
        "Рубець",
        "Рудик",
        "Рудько",
        "Рябець",
        "Рябовіл",
        "Рябошапка",
        "Рябченко",
        "Савенко",
        "Сагаль",
        "Саєнко",
        "Салій",
        "Самойленко",
        "Сацюк",
        "Саченко",
        "Свириденко",
        "Свистун",
        "Семенченко",
        "Симоненко",
        "Сиротенко",
        "Сич",
        "Сімашкевич",
        "Сірко",
        "Сіробаба",
        "Сірченко",
        "Скиба",
        "Скирда",
        "Скопенко",
        "Скорик",
        "Скоробогатько",
        "Смик",
        "Слюсар",
        "Сомко",
        "Стельмах",
        "Стець",
        "Стус",
        "Супруненко",
        "Талан",
        "Таран",
        "Тарасенко",
        "Твердохліб",
        "Теличенко",
        "Теліженко",
        "Терещенко",
        "Терещук",
        "Тесленко",
        "Тесля",
        "Тимченко",
        "Тимчук",
        "Титаренко",
        "Тихий",
        "Тичина",
        "Ткач",
        "Ткаченко",
        "Товстоліс",
        "Товстуха",
        "Токар",
        "Тригуб",
        "Туркало",
        "Тягнибок",
        "Удовенко",
        "Удовиченко",
        "Уманець",
        "Усик",
        "Устенко",
        "Фаренюк",
        "Фартушняк",
        "Фастенко",
        "Фесенко",
        "Філіпенко",
        "Фоменко",
        "Франко",
        "Франчук",
        "Фурс",
        "Харченко",
        "Хмара",
        "Хоменко",
        "Хомик",
        "Хорішко",
        "Христенко",
        "Христич",
        "Худобʼяк",
        "Худяк",
        "Царенко",
        "Цибуленко",
        "Цимбал",
        "Цимбалюк",
        "Цісик",
        "Цушко",
        "Цюпа",
        "Цюцюра",
        "Чабан",
        "Чайка",
        "Чаленко",
        "Чалий",
        "Чарниш",
        "Чекалюк",
        "Червоненко",
        "Чередник",
        "Черінько",
        "Черненко",
        "Чміль",
        "Чорновіл",
        "Чубай",
        "Чуйко",
        "Чумак",
        "Чумаченко",
        "Чуприна",
        "Шаблій",
        "Шамрай",
        "Шаповал",
        "Шахрай",
        "Швайка",
        "Швачка",
        "Швачко",
        "Шведченко",
        "Шеремета",
        "Шевченко",
        "Шелест",
        "Шеремет",
        "Шило",
        "Шинкаренко",
        "Шиян",
        "Шморгун",
        "Шовкопляс",
        "Штепа",
        "Штокало",
        "Шутько",
        "Шухевич",
        "Щербак",
        "Щербань",
        "Щириця",
        "Щорс",
        "Юрченко",
        "Юрчишин",
        "Юрчук",
        "Юхименко",
        "Ющенко",
        "Якименко",
        "Якимчук",
        "Яковенко",
        "Ярема",
        "Яременко",
        "Яремків",
        "Яремко",
        "Яремчук",
        "Ярош",
        "Яценко",
        "Яценюк",
        "Ященко",
        "Ящук",
    )

    middle_names_male = (
        "Ааронович",
        "Августинович",
        "Аврелійович",
        "Адамович",
        "Азарович",
        "Алевтинович",
        "Альбертович",
        "Амвросійович",
        "Андрійович",
        "Антонович",
        "Аркадійович",
        "Арсенович",
        "Артемович",
        "Орхипович",
        "Богданович",
        "Богодарович",
        "Богуславович",
        "Болеславович",
        "Борисович",
        "Бориславович",
        "Вадимович",
        "Валентинович",
        "Валерійович",
        "Варфоломійович",
        "Васильович",
        "Венедиктович",
        "Веніяминович",
        "Вікторович",
        "Віталійович",
        "Владиславович",
        "Володимирович",
        "Вʼячеславович",
        "Гаврилович",
        "Геннадійович",
        "Георгійович",
        "Гордійович",
        "Григорійович",
        "Глібович",
        "Данилович",
        "Давидович",
        "Демидович",
        "Демʼянович",
        "Дмитрович",
        "Захарович",
        "Зиновійович",
        "Зорянович",
        "Іванович",
        "Ігнатович",
        "Ігорович",
        "Едуардович",
        "Євгенійович",
        "Єлисейович",
        "Єфремович",
        "Йосипович",
        "Климентович",
        "Костянтинович",
        "Леонідович",
        "Леонтійович",
        "Леопольдович",
        "Лукʼянович",
        "Кирилович",
        "Макарович",
        "Максимович",
        "Мартинович",
        "Микитович",
        "Миколайович",
        "Миронович",
        "Мирославович",
        "Михайлович",
        "Назарович",
        "Несторович",
        "Олегович",
        "Олексович",
        "Олександрович",
        "Олесьович",
        "Омелянович",
        "Опанасович",
        "Орестович",
        "Остапович",
        "Охрімович",
        "Петрович",
        "Павлович",
        "Панасович",
        "Пантелеймонович",
        "Пилипович",
        "Прохорович",
        "Романович",
        "Ростиславович",
        "Русланович",
        "Святославович",
        "Семенович",
        "Сергійович",
        "Симонович",
        "Соломонович",
        "Станіславович",
        "Степанович",
        "Стефанович",
        "Тарасович",
        "Теодорович",
        "Тимофійович",
        "Трохимович",
        "Устимович",
        "Федорович",
        "Хомович",
        "Юстимович",
        "Юхимович",
        "Яковович",
        "Яремович",
        "Ярославович",
    )
    middle_names_female = (
        "Ааронівна",
        "Августинівна",
        "Аврелійовна",
        "Адамівна",
        "Азарівна",
        "Алевтинівна",
        "Альбертівна",
        "Амвросійовна",
        "Андріївна",
        "Антонівна",
        "Аркадіївна",
        "Арсенівна",
        "Артемівна",
        "Орхипівна",
        "Богданівна",
        "Богодарівна",
        "Богуславівна",
        "Болеславівна",
        "Борисівна",
        "Бориславівна",
        "Вадимівна",
        "Валентинівна",
        "Валеріївна",
        "Варфоломіївна",
        "Васильівна",
        "Венедиктівна",
        "Веніяминівна",
        "Вікторівна",
        "Віталіївна",
        "Владиславівна",
        "Володимирівна",
        "Вʼячеславівна",
        "Гаврилівна",
        "Геннадіївна",
        "Георгіївна",
        "Германівна",
        "Гордіївна",
        "Григоріївна",
        "Глібівна",
        "Данилівна",
        "Давидівна",
        "Данівна",
        "Демидівна",
        "Демʼянівна",
        "Дмитріївна",
        "Захарівна",
        "Зорянівна",
        "Іванівна",
        "Ігнатівна",
        "Ігорівна",
        "Іллівна",
        "Едуардівна",
        "Євгенівна",
        "Єлисеївна",
        "Єфремівна",
        "Йосипівна",
        "Климентівна",
        "Костянтинівна",
        "Лесівна",
        "Леонідівна",
        "Леонтіївна",
        "Леопольдівна",
        "Лукʼянівна",
        "Кирилівна",
        "Макарівна",
        "Максимівна",
        "Марківна",
        "Мартинівна",
        "Микитівна",
        "Миколаївна",
        "Миронівна",
        "Мирославівна",
        "Михайлівна",
        "Назарівна",
        "Несторівна",
        "Олегівна",
        "Олександрівна",
        "Омелянівна",
        "Опанасівна",
        "Орестівна",
        "Остапівна",
        "Охрімівна",
        "Петрівна",
        "Павлівна",
        "Панасівна",
        "Пантелеймонівна",
        "Пилипівна",
        "Прохорівна",
        "Романівна",
        "Ростиславівна",
        "Русланівна",
        "Святославівна",
        "Семенівна",
        "Сергіївна",
        "Симонівна",
        "Соломонівна",
        "Спасівна",
        "Станіславівна",
        "Степанівна",
        "Стефанівна",
        "Тарасівна",
        "Теодорівна",
        "Тимофіївна",
        "Трохимівна",
        "Устимівна",
        "Федорівна",
        "Феофанівна",
        "Францівна",
        "Юстимівна",
        "Юхимівна",
        "Яремівна",
        "Ярославівна",
    )
    middle_names = middle_names_male + middle_names_female

    prefixes_male = OrderedDict(
        (
            ("пан", 0.8),
            ("добродій", 0.2),
        )
    )

    prefixes_female = OrderedDict(
        (
            ("пані", 0.8),
            ("панна", 0.1),
            ("добродійка", 0.1),
        )
    )

    def middle_name(self) -> str:
        """
        Generate random middle name.
        :sample:
        """
        return self.random_element(self.middle_names)

    def middle_name_male(self) -> str:
        """
        Generate random male middle name.
        :sample:
        """
        return self.random_element(self.middle_names_male)

    def middle_name_female(self) -> str:
        """
        Generate random female middle name.
        :sample:
        """
        return self.random_element(self.middle_names_female)

    def full_name(self, gender: Optional[SexLiteral] = None, short: Optional[bool] = False) -> str:
        """
        Generate Full Name
            - gender = 'M' or 'F' optional params
            - short: bool optional params. default is False

        :example: 'Петриченко Петро Сергійович'
        :example: 'Петриченко П.С.'

        :sample:
        :sample: gender='F'
        :sample: gender='M'
        :sample: short=True
        """
        if gender and gender not in ("M", "F"):
            raise ValueError('Gender must be "m" or "f" or None')

        gender_ = gender if gender else self.random_element(elements=["M", "F"])

        if gender_ == "M":
            first_name = self.first_name_male()
            last_name = self.last_name_male()
            middle_name = self.middle_name_male()
        else:
            first_name = self.first_name_female()
            last_name = self.last_name_female()
            middle_name = self.middle_name_female()

        if short:
            return f"{last_name} {first_name[0]}.{middle_name[0]}."

        return f"{last_name} {first_name} {middle_name}"
