#include <Widget/IconLabel/IconLabel.hpp>
#include <Widget/Label/Label.hpp>
#include <Widget/Layout/Center/Center.hpp>
#include <Widget/Layout/Column/Column.hpp>
#include <Widget/Layout/CompoundWidget/Deck/Deck.hpp>
#include <Widget/Layout/CompoundWidget/MilestoneView/MilestoneView.hpp>
#include <Widget/Layout/Frame/Frame.hpp>
#include <Widget/Layout/Margin/Margin.hpp>
#include <Widget/Layout/MenuButton/MenuButton.hpp>
#include <Widget/Layout/Row/Row.hpp>
#include <Widget/Panel/Panel.hpp>

MilestoneView::MilestoneView(
    Player &player,
    Milestone &milestone,
    std::function<void(std::string, int)> onAchievementSelected,
    AchievementFilter &filter
)
{
    int achievementsDone = 0;

    std::vector<Widget*> achievementItems;
    for (int achievementId : milestone.sortedAchievements)
    {
        auto &achievement = milestone.achievements[achievementId];
    
        if (!player.isAchievementReachable(milestone.id, achievementId))
        {
            continue;
        }

        bool done = player.hasCompletedAchievement(milestone.id, achievementId);
        if (done)
        {
            achievementsDone++;
            if (!filter.showCompleted)
            {
                continue;
            }
        }

        if (!achievement->matchesQuery(filter.query))
        {
            continue;
        }

        Widget *tick;
        if (done)
        {
            tick = new IconLabel(Material::accept);
        }
        else
        {
            tick = new Panel();
        }

        achievementItems.push_back(
            new MenuButton(
                new Deck<Row, Center>(
                    new IconLabel(done ? achievement->doneIcon : achievement->todoIcon),
                    new Panel(glm::ivec2(2, 0)),
                    new Label(achievement->title),

                    Layout::WithProportion<1>(),
                    new Panel(),

                    tick
                ),
                [onAchievementSelected, &milestone, achievementId]()
                {
                    onAchievementSelected(milestone.id, achievementId);
                }
            )
        );
    }

    bool done = player.hasCompletedMilestone(milestone.id);
    int donePercentage = 100 * achievementsDone / milestone.achievements.size();

    addChildren(
        new Margin<2>(
            new Frame(
                Color::sectionBackground,
                new Column(
                    new Deck<Row, Center>(
                        (new Frame(
                            done ? Color::progressDone : Color::progressTodo,
                            new IconLabel(done ? milestone.doneIcon : milestone.todoIcon)
                        ))->withMargin(1),
                        new Panel(glm::ivec2(2, 0)),
                        new Label(milestone.label),

                        Layout::WithProportion<1>(),
                        new Panel(),

                        new Label(
                            formatString("$+%", donePercentage),
                            done ? Color::success : Color::faded
                        )
                    ),
                    new Panel(glm::ivec2(0, 2)),
                    new Margin<0, 5>(
                        (new Frame(
                            Color::sectionBackground,
                            new Column(achievementItems)
                        ))->withMargin(0)
                    )
                )
            )
        )
    );
}