#include "toasts.hpp"

#include <imgui.h>
#include <ranges>
#include <string>

namespace game::state::play
{
  void Toasts::update()
  {
    for (int i = 0; i < (int)items.size(); i++)
    {
      auto& item = items[i];

      item.lifetime--;

      if (item.lifetime <= 0)
      {
        items.erase(items.begin() + i--);
        continue;
      }
    }

    if (items.empty()) return;

    auto viewport = ImGui::GetMainViewport();
    auto& style = ImGui::GetStyle();

    auto windowBgColor = ImGui::GetStyleColorVec4(ImGuiCol_WindowBg);
    auto borderColor = ImGui::GetStyleColorVec4(ImGuiCol_Border);
    auto textColor = ImGui::GetStyleColorVec4(ImGuiCol_Text);

    for (int i = 0; i < (int)items.size(); i++)
    {
      auto& item = items[i];
      auto height = ImGui::GetTextLineHeightWithSpacing() + style.WindowPadding.y * 2.0f;
      auto posY = viewport->WorkPos.y + viewport->WorkSize.y - style.WindowPadding.y -
                  (height * (items.size() - i));

      auto textSize = ImGui::CalcTextSize(item.message.c_str());
      auto pos = ImVec2(viewport->WorkPos.x + style.WindowPadding.x, posY);
      auto size = ImVec2(textSize.x + (style.WindowPadding.x * 2), height);

      auto alpha = (float)item.lifetime / Item::LIFETIME;

      windowBgColor.w = alpha;
      borderColor.w = alpha;
      textColor.w = alpha;

      auto* drawList = ImGui::GetForegroundDrawList();
      drawList->AddRectFilled(pos, ImVec2(pos.x + size.x, pos.y + size.y), ImGui::GetColorU32(windowBgColor),
                              style.WindowRounding);
      drawList->AddRect(pos, ImVec2(pos.x + size.x, pos.y + size.y), ImGui::GetColorU32(borderColor),
                        style.WindowRounding);
      drawList->AddText(ImVec2(pos.x + style.WindowPadding.x, pos.y + style.WindowPadding.y),
                        ImGui::GetColorU32(textColor), item.message.c_str());
    }
  }

  void Toasts::push(const std::string& message) { items.push_back({message, Item::LIFETIME}); }
}
