#include "render/gui/UpdateMenu.h"

#include "render/gui/imgui/imgui.h"

#include <chrono>

namespace td {
namespace gui {

UpdateMenu::UpdateMenu(client::Client* client) : GuiWidget(client), m_Opened(true) {
    checkUpdates();
}

void UpdateMenu::render() {
    renderErrorPopup();
    if (m_Opened) {
        ImGui::Begin("Updater", &m_Opened);
        if (isUpdateChecked()) {

            bool updateAvailable = m_UpdateAvailable.get();
            if (updateAvailable) {

                if (m_Updater.isFileWrited()) {
                    ImGui::Text("The update is now installed");
                    ImGui::Text("The game needs to be restarted");
                } else if (m_Updater.isDownloadComplete()) {
                    ImGui::Text("Download done!");
                    if (ImGui::Button("Install")) {
                        if (!m_Updater.writeFile()) {
                            m_Error = "Failed to write file !\n";
                            ImGui::OpenPopup("UpdateError");
                        }
                    }
                    if (ImGui::Button("Cancel")) {
                        m_Updater.cancelDownload();
                        m_Updater.clearCache();
                    }
                } else {
                    if (m_Updater.getDownloadProgress() > 0) {
                        ImGui::Text("Downloading ...");
                        ImGui::ProgressBar(m_Updater.getDownloadProgress());
                        if (ImGui::Button("Cancel")) {
                            m_Updater.cancelDownload();
                        }
                    } else {
                        ImGui::Text("An update is available!");
                        ImGui::Separator();
                        ImGui::Text("Current version : %s", m_Updater.getCurrentVersion().c_str());
                        ImGui::Text("Last version : %s", m_Updater.getLastVersion().c_str());

                        bool canDownloadFile = m_Updater.canUpdate();

                        if (!canDownloadFile) ImGui::BeginDisabled();

                        if (ImGui::Button("Download")) {
                            m_Updater.downloadUpdate();
                        }

                        if (!canDownloadFile) ImGui::EndDisabled();

                        ImGui::SameLine();
                        if (ImGui::Button("Cancel")) {
                            m_Opened = false;
                        }
                    }
                }
            } else {
                ImGui::Text("No update available!");
                ImGui::Separator();
                ImGui::Text("Current version : %s", m_Updater.getCurrentVersion().c_str());
                ImGui::Text("Last version : %s", m_Updater.getLastVersion().c_str());
            }
        } else {
            ImGui::Text("Checking updates ...");
        }
        ImGui::End();
    }
}

void UpdateMenu::renderErrorPopup() {
    if (ImGui::BeginPopup("UpdateError")) {
        ImGui::Text("Error : %s", m_Error.c_str());
        ImGui::EndPopup();
    }
}

bool UpdateMenu::isUpdateChecked() {
    return m_UpdateAvailable.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
}

void UpdateMenu::checkUpdates() {
    m_UpdateAvailable = std::async(std::launch::async, [&]() { return m_Updater.checkUpdate();});
}

} // namespace gui
} // namespace td
