#include "ArenaWidget.h"

#include <QHBoxLayout>
#include <QVBoxLayout>

#include "ArenaInspectRequestedEvent.h"
#include "ArenaStartRequestedEvent.h"
#include "EventManager.h"

ArenaWidget::ArenaWidget(int arenaIndex, const std::string& arenaName, QWidget* parent)
    : QFrame(parent)
    , m_arenaIndex(arenaIndex)
    , m_running(false)
    , m_wasFinished(false)
{
    buildLayout(arenaName);
    setFrameStyle(QFrame::Box | QFrame::Plain);
    setLineWidth(2);
    setStyleSheet("ArenaWidget { border: 2px solid #999999; padding: 8px; }");
}

void ArenaWidget::buildLayout(const std::string& arenaName)
{
    QVBoxLayout* outerLayout = new QVBoxLayout(this);
    outerLayout->setContentsMargins(8, 8, 8, 8);
    outerLayout->setSpacing(4);

    QHBoxLayout* titleRow = new QHBoxLayout();
    m_titleLabel = new QLabel(QString::fromStdString(arenaName), this);
    QFont titleFont = m_titleLabel->font();
    titleFont.setBold(true);
    titleFont.setPointSize(titleFont.pointSize() + 2);
    m_titleLabel->setFont(titleFont);
    titleRow->addWidget(m_titleLabel);

    m_durationLabel = new QLabel(this);
    titleRow->addWidget(m_durationLabel);

    titleRow->addStretch();

    m_inspectButton = new QPushButton(tr("Inspect"), this);
    connect(m_inspectButton, &QPushButton::clicked, this, [this]() {
        EventManager::getInstance()->sendEventImmediately(
            std::make_shared<ArenaInspectRequestedEvent>(m_arenaIndex));
    });
    titleRow->addWidget(m_inspectButton);

    m_startButton = new QPushButton(tr("Start"), this);
    connect(m_startButton, &QPushButton::clicked, this, [this]() {
        EventManager::getInstance()->sendEventImmediately(
            std::make_shared<ArenaStartRequestedEvent>(m_arenaIndex));
    });
    titleRow->addWidget(m_startButton);

    outerLayout->addLayout(titleRow);

    QHBoxLayout* teamsLayout = new QHBoxLayout();
    teamsLayout->setSpacing(16);

    // Team 1 column.
    QVBoxLayout* team1Layout = new QVBoxLayout();
    m_team1Header = new QLabel(this);
    QFont headerFont = m_team1Header->font();
    headerFont.setBold(true);
    m_team1Header->setFont(headerFont);
    team1Layout->addWidget(m_team1Header);
    m_team1Threat = new QLabel(this);
    team1Layout->addWidget(m_team1Threat);
    m_team1Ehp = new QLabel(this);
    team1Layout->addWidget(m_team1Ehp);
    m_team1Content = new QLabel(this);
    team1Layout->addWidget(m_team1Content);
    team1Layout->addStretch();
    teamsLayout->addLayout(team1Layout);

    // Team 2 column.
    QVBoxLayout* team2Layout = new QVBoxLayout();
    m_team2Header = new QLabel(this);
    m_team2Header->setFont(headerFont);
    team2Layout->addWidget(m_team2Header);
    m_team2Threat = new QLabel(this);
    team2Layout->addWidget(m_team2Threat);
    m_team2Ehp = new QLabel(this);
    team2Layout->addWidget(m_team2Ehp);
    m_team2Content = new QLabel(this);
    team2Layout->addWidget(m_team2Content);
    team2Layout->addStretch();
    teamsLayout->addLayout(team2Layout);

    outerLayout->addLayout(teamsLayout);
}

void ArenaWidget::startSimulation()
{
    m_running = true;
    m_wasFinished = false;
    m_startButton->setEnabled(false);
    setStyleSheet("ArenaWidget { border: 2px solid #3366ff; padding: 8px; }");
}

void ArenaWidget::resetToGrey()
{
    m_running = false;
    m_wasFinished = false;
    m_startButton->setEnabled(true);
    setStyleSheet("ArenaWidget { border: 2px solid #999999; padding: 8px; }");
}

ArenaWidget::State ArenaWidget::getState() const
{
    if (m_wasFinished)
    {
        return State::Ended;
    }
    if (m_running)
    {
        return State::Running;
    }
    return State::NotStarted;
}

void ArenaWidget::updateStatus(const ArenaStatus& status)
{
    m_lastStatus = status;

    for (int ti = 0; ti < 2; ++ti)
    {
        const ArenaStatus::TeamStatus& team = status.teams[ti];
        QLabel* header = (ti == 0) ? m_team1Header : m_team2Header;
        QLabel* threat = (ti == 0) ? m_team1Threat : m_team2Threat;
        QLabel* ehp = (ti == 0) ? m_team1Ehp : m_team2Ehp;
        QLabel* content = (ti == 0) ? m_team1Content : m_team2Content;

        if (status.finished && status.winnerTeam == ti)
        {
            header->setText(tr("[WON] %1").arg(QString::fromStdString(team.name)));
        }
        else
        {
            header->setText(QString::fromStdString(team.name));
        }

        threat->setText(tr("Threat: %1").arg(QString::number(team.threatLevel, 'f', 0)));
        ehp->setText(tr("EHP: %1").arg(QString::fromStdString(team.getEhpPercentText())));

        QString lines;
        for (const ArenaStatus::Entry& entry : team.entries)
        {
            if (!lines.isEmpty())
            {
                lines += "\n";
            }
            lines += QString("%1/%2 %3")
                         .arg(entry.surviving)
                         .arg(entry.total)
                         .arg(QString::fromStdString(entry.displayName));
            if (entry.level.has_value())
            {
                lines += QString(" L%1").arg(entry.level.value());
            }
        }
        content->setText(lines);
    }

    m_durationLabel->setText(status.finished
        ? tr("Duration: %1 s").arg(QString::number(status.durationSeconds, 'f', 1))
        : QString());

    if (status.finished && !m_wasFinished)
    {
        m_wasFinished = true;
        m_running = false;
        m_startButton->setEnabled(true);
        setStyleSheet("ArenaWidget { border: 2px solid #33cc33; padding: 8px; }");
    }
}
