#include "transliterator.h"
#include <unicode/unistr.h>
#include <unicode/translit.h>
#include <QDebug>

QString Transliterator::convert(const QString& input) {
    UErrorCode status = U_ZERO_ERROR;
    icu::UnicodeString uInput = icu::UnicodeString::fromUTF8(icu::StringPiece(input.toUtf8().constData()));

    if (U_FAILURE(status)) {
        qWarning() << "Transliterator creation failed: " << u_errorName(status);
        return input;
    }

    icu::Transliterator* translit = icu::Transliterator::createInstance("Any-Latin; Latin-ASCII", UTRANS_FORWARD, status);

    if (U_FAILURE(status)) {
        qWarning() << "Transliterator creation failed: " << u_errorName(status);
        delete translit;
        return input;
    }

    translit->transliterate(uInput);
    delete translit;

    std::string str_result;
    uInput.toUTF8String(str_result);

    return replaceEmojis(QString::fromStdString(str_result));
}


QString Transliterator::replaceEmojis(const QString &input) {
    const QMap<QString, QString> emojiTransliterator = {
        {"\xE2\x9D\xA4", "<3"},                   // â¤ heart
        {"\xE2\x98\xB9", ":-("},                  // â˜¹ frowning_face
        {"\xF0\x9F\x91\x8D", ":thumbs-up:"},      // ðŸ‘ thumbs-up
        {"\xF0\x9F\x91\x8E", ":thumbs-down:"},    // ðŸ‘Ž thumbs-down
        {"\xF0\x9F\x91\x8F", ":clap:"},           // ðŸ‘ clap
        {"\xF0\x9F\x94\xA5", ":fire:"},           // ðŸ”¥ fire
        {"\xF0\x9F\x99\x8F", ":praying:"},        // ðŸ™ praying
        {"\xF0\x9F\x98\x94", ":think:"},          // ðŸ˜” pensive
        {"\xF0\x9F\x91\x89", ":point:"},          // ðŸ‘‰ point
        {"\xF0\x9F\x91\x8B", ":wave:"},           // ðŸ‘‹ wave
        {"\xF0\x9F\x8E\x89", ":party:"},          // ðŸŽ‰ party
        {"\xF0\x9F\x98\x8D", ":heart_eyes:"},     // ðŸ˜ heart_eyes
        {"\xF0\x9F\xA4\x94", ":thinking:"},       // ðŸ¤” thinking
        {"\xF0\x9F\x98\x80", ":-D"},              // ðŸ˜€ grinning
        {"\xF0\x9F\x98\x81", ":-D"},              // ðŸ˜ grinning_face_with_smiling_eyes
        {"\xF0\x9F\x98\x82", ":'D"},              // ðŸ˜‚ face_with_tears_of_joy
        {"\xF0\x9F\x98\x83", ":-D"},              // ðŸ˜ƒ smiling_face_with_open_mouth
        {"\xF0\x9F\x98\x84", ":-D"},              // ðŸ˜„ smiling_face_with_open_mouth_and_smiling_eyes
        {"\xF0\x9F\x98\x85", ":'D"},              // ðŸ˜… smiling_face_with_open_mouth_and_cold_sweat
        {"\xF0\x9F\x98\x86", "X-D"},              // ðŸ˜† smiling_face_with_open_mouth_and_tightly-closed_eyes
        {"\xF0\x9F\x98\x87", "O:-)"},             // ðŸ˜‡ innocent
        {"\xF0\x9F\x98\x89", ";-)"},              // ðŸ˜‰ wink
        {"\xF0\x9F\x98\x8A", ":-)"},              // ðŸ˜Š blush
        {"\xF0\x9F\x98\x8B", ":-p"},              // ðŸ˜‹ yum
        {"\xF0\x9F\x98\x8E", "B-)"},              // ðŸ˜Ž sunglasses
        {"\xF0\x9F\x98\x95", ":-/"},              // ðŸ˜• confused
        {"\xF0\x9F\x98\x96", ":-S"},              // ðŸ˜– confounded_face
        {"\xF0\x9F\x98\x97", ":*"},               // ðŸ˜— kissing_face
        {"\xF0\x9F\x98\x98", ";-*"},              // ðŸ˜˜ face_throwing_a_kiss
        {"\xF0\x9F\x98\x99", ":-*"},              // ðŸ˜™ kissing_face_with_smiling_eyes
        {"\xF0\x9F\x98\x9A", ":-*"},              // ðŸ˜š kissing_closed_eyes
        {"\xF0\x9F\x98\x9B", ":-P"},              // ðŸ˜› stuck_out_tongue
        {"\xF0\x9F\x98\x9C", ";-P"},              // ðŸ˜œ stuck_out_tongue_winking_eye
        {"\xF0\x9F\x98\x9D", "X-P"},              // ðŸ˜ stuck_out_tongue_and_tightly-closed_eyes
        {"\xF0\x9F\x98\x9E", ":-S"},              // ðŸ˜ž disappointed
        {"\xF0\x9F\x98\xA0", ":-@"},              // ðŸ˜  angry_face
        {"\xF0\x9F\x98\xA1", ":-@"},              // ðŸ˜¡ pouting_face
        {"\xF0\x9F\x98\xA2", ":'("},              // ðŸ˜¢ cry
        {"\xF0\x9F\x98\xA3", ":'("},              // ðŸ˜£ persevering_face
        {"\xF0\x9F\x98\xA4", ":-O"},              // ðŸ˜¤ face_with_steam_from_nose
        {"\xF0\x9F\x98\xA5", ":'O"},              // ðŸ˜¥ face_with_cold_sweat
        {"\xF0\x9F\x98\xA8", ":-O"},              // ðŸ˜¨ fearful
        {"\xF0\x9F\x98\xA9", ":-O"},              // ðŸ˜© weary_face
        {"\xF0\x9F\x98\xAA", ":'("},              // ðŸ˜ª sleepy_face
        {"\xF0\x9F\x98\xAB", ":-|"},              // ðŸ˜« tired_face
        {"\xF0\x9F\x98\xAC", ":-|"},              // ðŸ˜¬ grimacing_face
        {"\xF0\x9F\x98\xAD", ":'("},              // ðŸ˜­ loudly_crying_face
        {"\xF0\x9F\x98\xAE", ":-O"},              // ðŸ˜® face_with_open_mouth
        {"\xF0\x9F\x98\xAF", ":-/"},              // ðŸ˜¯ hushed_face
        {"\xF0\x9F\x98\xB0", ":-/"},              // ðŸ˜° face_with_open_mouth_and_cold_sweat
        {"\xF0\x9F\x98\xB1", ":-O"},              // ðŸ˜± face_screaming_in_fear
        {"\xF0\x9F\x98\xB2", ":-/"},              // ðŸ˜² astonished_face
        {"\xF0\x9F\x98\xB3", ":-S"},              // ðŸ˜³ flushed_face
        {"\xF0\x9F\x98\xB4", ":-S"},              // ðŸ˜´ sleeping_face
        {"\xF0\x9F\x98\xB5", ":-P"},              // ðŸ˜µ dizzy_face
        {"\xF0\x9F\x98\xB7", ":-x"},              // ðŸ˜· face_with_medical_mask
        {"\xF0\x9F\x98\xB8", "O.o"},              // ðŸ˜¸ grinning_cat_face_with_smiling_eyes
        {"\xF0\x9F\x98\xB9", ":-)"},              // ðŸ˜¹ cat_face_with_tears_of_joy
        {"\xF0\x9F\x98\xBA", ":-("},              // ðŸ˜º grinning_cat_face
        {"\xF0\x9F\x98\xBB", ":-D"},              // ðŸ˜» heart_eyes_cat
        {"\xF0\x9F\x98\xBC", ":'-("},             // ðŸ˜¼ cat_face_with_wry_smile
        {"\xF0\x9F\x98\xBD", ":'("},              // ðŸ˜½ kissing_cat_face
        {"\xF0\x9F\x98\xBE", ":-@"},              // ðŸ˜¾ pouting_cat_face
        {"\xF0\x9F\x98\xBF", ":-@"},              // ðŸ˜¿ crying_cat_face
        {"\xF0\x9F\x99\x80", "O.O"},              // ðŸ™€ screaming_cat_face
        {"\xF0\x9F\x99\x83", "(-:"},              // ðŸ™ƒ upside-down_face
        {"\xF0\x9F\x91\x8C", ":ok:"},             // ðŸ‘Œ OK_hand
    };
    QString output(input);
    for (auto it = emojiTransliterator.begin(); it != emojiTransliterator.end(); ++it) {
        output.replace(it.key(), it.value());
    }
    return output;
}

void Transliterator::test() {

    QStringList inputStrings = {
        "The quick brown fox jumps over the lazy dog.", // English
        "Î¦Î¬Î»Î±Î¹Î½Î± ÏˆÎ·Î»Î¬ ÏƒÏ„Î· Î¶Î¿Ï…Î¼Ï€Î¿ÏÎ»Î¹Î± Î¾ÎµÏ†Ï„Î¹Î»Î¯Î¶ÎµÎ¹ ÎºÏ…ÏÎ¬ ÎšÎ»Î¯Ï„ÏƒÎ±.", // Greek
        "Victor jagt zwÃ¶lf BoxkÃ¤mpfer quer Ã¼ber den groÃŸen Sylter Deich.", // German
        "Albert edward kyllikki soili jalmari viktor suomela si jÃ¶nsson.", // Finnish
        "Frida var den skÃ¶naste kvinnan pÃ¥ Gotland.",           // Swedish
        "PÅ™Ã­liÅ¡ Å¾luÅ¥ouÄkÃ½ kÅ¯Åˆ ÃºpÄ›l ÄÃ¡belskÃ© Ã³dy", // Czech
        "Ð—Ð²Ð¾Ð½ÐºÐ¾ Ñ‡ÐµÐ¿ÑƒÑ…Ñƒ Ñ‰ÐµÐ³Ð¾Ð»Ñ Ð¿Ñ€ÑÐ¼Ð¾ Ñ„ÑŒÐ¾Ñ€Ð´Ð¾Ð¼ Ñ ÑÐºÐ·ÐµÐ¼Ð¿Ð»ÑÑ€Ð°Ð¼Ð¸ Ð¶Ð¸Ð²Ñ‹Ñ… Ð±ÐµÐ³ÐµÐ¼Ð¾Ñ‚Ð¾Ð².", // Russian
        "â¤ðŸ™ƒðŸ˜‚ðŸ˜ðŸ‘ðŸ™ðŸ‘ðŸ”¥ðŸ‘‰ðŸ¤”ðŸ˜ðŸ‘Œ", // emojis
    };

    // Iterate through the input strings and transliterate each one
    foreach (const QString& input, inputStrings) {
        QString transliterated = Transliterator::convert(input);
        qDebug() << input
            << "\n >>>" << transliterated;
    }

}
