#include "BannerWidget.h"

#include "Preferences.h"
#include "TokenizableItems/TokenPropertyNames.h"
#include "TokenParserWidgetManager.h"
#include "ui_BannerWidget.h"

#include <QStyle>
namespace
{
constexpr const char* TYPE_PROPERTY_NAME{"type"};
const std::map<BannerWidget::Type, QLatin1String> TYPE_MAP{
    {BannerWidget::Type::BANNER_WARNING, QLatin1String{"warning"}},
    {BannerWidget::Type::BANNER_ERROR, QLatin1String{"error"}},
    {BannerWidget::Type::BANNER_INFO, QLatin1String{"info"}},
    {BannerWidget::Type::BANNER_SUCCESS, QLatin1String{"success"}},
    {BannerWidget::Type::BANNER_MESSAGE, QLatin1String{"message"}}};
constexpr int MINIMU_BANNER_HEIGHT = 44;
}

BannerWidget::BannerWidget(QWidget* parent):
    QWidget(parent),
    mUi(new Ui::BannerWidget),
    mType(Type::NONE)
{
    mUi->setupUi(this);
    TokenParserWidgetManager::instance()->applyCurrentTheme(this);
    mUi->wLinkContainer->hide();
    mUi->lTitle->hide();
    mUi->lText->hide();

    connect(mUi->bLink,
            &QPushButton::clicked,
            this,
            &BannerWidget::linkActivated,
            Qt::UniqueConnection);

    checkLayoutOrientation();
}

BannerWidget::~BannerWidget()
{
    delete mUi;
}

void BannerWidget::setType(Type type, bool showIcon)
{
    mUi->lIcon->setVisible(showIcon);

    if (mType == type)
    {
        return;
    }

    mType = type;

    auto it = TYPE_MAP.find(mType);
    if (it == TYPE_MAP.end())
    {
        return;
    }

    QLatin1String typeString(it->second);
    mUi->wContent->setProperty(TYPE_PROPERTY_NAME, typeString);

    setLabelToken();

    // Force update the style of all child widgets.
    mUi->wContent->setStyleSheet(this->styleSheet());
}

void BannerWidget::setDescription(const QString& text)
{
    mUi->lText->setText(text);
    mUi->lText->show();
    updateTitleWeight();
    updateGeometry();
}

void BannerWidget::setAutoManageTextUrl(bool newValue)
{
    mUi->lText->setAutoManageUrl(newValue);
}

void BannerWidget::setLinkText(const QString& displayText)
{
    mUi->bLink->setText(displayText);
    mUi->wLinkContainer->show();
}

bool BannerWidget::event(QEvent* event)
{
    if (event->type() == QEvent::LanguageChange)
    {
        checkLayoutOrientation();
    }
    else if (event->type() == WordWrapLabel::HeightAdapted)
    {
        setMaximumHeight(sizeHint().height());
    }

    return QWidget::event(event);
}

void BannerWidget::setTitle(const QString& text)
{
    mUi->lTitle->setText(text);
    mUi->lTitle->show();
    updateTitleWeight();
    updateGeometry();
}

void BannerWidget::updateTitleWeight()
{
    const QVariant semibold(mUi->lText->toPlainText().isEmpty() ? QVariant() : QVariant(true));
    if (mUi->lTitle->property("semibold") != semibold)
    {
        mUi->lTitle->setProperty("semibold", semibold);
        TokenParserWidgetManager::instance()->polish(mUi->lTitle);
    }
}

void BannerWidget::checkLayoutOrientation()
{
    const QLocale current = QLocale(Preferences::instance()->language());

    // Arabic, for now
    if (current.textDirection() == Qt::RightToLeft)
    {
        // Move icon to the right
        mUi->gridLayout->addWidget(mUi->lIcon, 0, 2, 1, 1, Qt::AlignTop);

        // Move button to the left
        mUi->contentLayout->insertWidget(0, mUi->wLinkContainer);
    }
    else
    {
        // Move icon to the left
        mUi->gridLayout->addWidget(mUi->lIcon, 0, 0, 1, 1, Qt::AlignTop);

        // Move button to the right
        mUi->contentLayout->insertWidget(1, mUi->wLinkContainer);
    }
}

void BannerWidget::setLabelToken()
{
    switch (mType)
    {
        case Type::BANNER_WARNING:
        {
            mUi->lIcon->setProperty(TOKEN_PROPERTIES::normalOff, QLatin1String("text-warning"));
            break;
        }
        case Type::BANNER_ERROR:
        {
            mUi->lIcon->setProperty(TOKEN_PROPERTIES::normalOff, QLatin1String("text-error"));
            break;
        }
        case Type::BANNER_INFO:
        {
            mUi->lIcon->setProperty(TOKEN_PROPERTIES::normalOff, QLatin1String("text-info"));
            break;
        }
        case Type::BANNER_SUCCESS:
        {
            mUi->lIcon->setProperty(TOKEN_PROPERTIES::normalOff, QLatin1String("text-success"));
            break;
        }
        case Type::BANNER_MESSAGE:
        {
            mUi->lIcon->setProperty(TOKEN_PROPERTIES::normalOff, QLatin1String("icon-primary"));
            break;
        }
        default:
        {
            mUi->lIcon->setProperty(TOKEN_PROPERTIES::normalOff, QString());
        }
    }
}

QSize BannerWidget::sizeHint() const
{
    // Force layout to calculate with current constraints
    auto hint = QWidget::sizeHint();

    // Ensure minimum reasonable height
    if (hint.height() < MINIMU_BANNER_HEIGHT)
    {
        hint.setHeight(MINIMU_BANNER_HEIGHT);
    }

    return hint;
}
