// MassBuilderSaveTool
// Copyright (C) 2021 Guillaume Jacquemin
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#include "SaveTool.h"

#include <Magnum/ImGuiIntegration/Integration.h>

#include "../FontAwesome/IconsFontAwesome5.h"

extern const ImVec2 center_pivot;

void SaveTool::drawProfileManager() {
    static std::size_t profile_index = 0;

    ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f}}, ImGuiCond_Always, center_pivot);
    if(ImGui::Begin("Profile management##ProfileManager", nullptr,
                    ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoBringToFrontOnFocus|
                    ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_MenuBar))
    {
        if(ImGui::BeginMenuBar()) {
            ImGui::TextUnformatted("Profile manager");
            ImGui::EndMenuBar();
        }

        static ImGuiID backup_list_popup_id = drawBackupListPopup();
        static ImGuiID backup_popup_id = drawBackupProfilePopup(profile_index);
        static ImGuiID delete_popup_id = drawDeleteProfilePopup(profile_index);

        if(ImGui::BeginTable("##ManagerLayout", 2)) {
            ImGui::TableSetupColumn("##Label", ImGuiTableColumnFlags_WidthStretch);
            ImGui::TableSetupColumn("##Refresh", ImGuiTableColumnFlags_WidthFixed);

            ImGui::TableNextRow();
            ImGui::TableSetColumnIndex(0);
            ImGui::TextUnformatted("Here are the detected profiles:");

            ImGui::TableSetColumnIndex(1);
            if(ImGui::SmallButton("Refresh")) {
                if(!_profileManager->refreshProfiles()) {
                    SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error in ProfileManager", _profileManager->lastError().c_str(), window());
                    exit(EXIT_FAILURE);
                }
            }
            ImGui::SameLine();
            if(ImGui::SmallButton("Backups")) {
                _profileManager->refreshBackups();
                ImGui::OpenPopup(backup_list_popup_id);
            }

            ImGui::EndTable();
        }

        if(ImGui::BeginTable("##Profiles", 3, ImGuiTableFlags_BordersOuter|ImGuiTableFlags_RowBg)) {
            ImGui::TableSetupColumn("Company name", ImGuiTableColumnFlags_WidthStretch);
            ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed);
            ImGui::TableSetupColumn("##Buttons", ImGuiTableColumnFlags_WidthFixed);

            ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
            ImGui::TableSetColumnIndex(0);
            ImGui::TextUnformatted("Company name");
            ImGui::TableSetColumnIndex(1);
            ImGui::TextUnformatted("Type");
            ImGui::TableSetColumnIndex(2);
            ImGui::TextUnformatted("Actions");

            for(std::size_t i = 0; i < _profileManager->profiles().size(); ++i) {
                ImGui::TableNextRow();

                ImGui::TableSetColumnIndex(0);
                ImGui::PushID(i);
                if(ImGui::Selectable(_profileManager->profiles()[i].companyName().c_str(), false,
                                     ImGuiSelectableFlags_SpanAllColumns|ImGuiSelectableFlags_AllowItemOverlap))
                {
                    _currentProfile = _profileManager->getProfile(i);
                    initialiseMassManager();
                    _uiState = UiState::MainManager;
                }

                ImGui::TableSetColumnIndex(1);
                ImGui::TextUnformatted(_profileManager->profiles()[i].type() == ProfileType::Demo ? "Demo" : "Full");

                ImGui::TableSetColumnIndex(2);
                if(ImGui::SmallButton(ICON_FA_FILE_ARCHIVE)) {
                    profile_index = i;
                    ImGui::OpenPopup(backup_popup_id);
                }
                ImGui::SameLine(0.0f, 2.0f);
                if(drawUnsafeWidget(ImGui::SmallButton, ICON_FA_TRASH_ALT)) {
                    profile_index = i;
                    ImGui::OpenPopup(delete_popup_id);
                }
                ImGui::PopID();
            }
            ImGui::EndTable();
        }

        ImGui::TextUnformatted("Click a profile to manage it.");
    }

    drawBackupListPopup();
    drawBackupProfilePopup(profile_index);
    drawDeleteProfilePopup(profile_index);

    ImGui::End();
}

auto SaveTool::drawBackupListPopup() -> ImGuiID {
    ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f}}, ImGuiCond_Always, center_pivot);
    if(!ImGui::BeginPopupModal("Backups##BackupsModal", nullptr,
                               ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
    {
        return ImGui::GetID("Backups##BackupsModal");
    }

    static std::size_t backup_index;

    if(ImGui::BeginPopupModal("Restore backup", nullptr,
                              ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize))
    {
        ImGui::PushTextWrapPos(windowSize().x() * 0.40f);
        ImGui::Text("Are you sure you want to restore the %s backup from %.4i-%.2i-%.2i %.2i:%.2i:%.2i ? Any existing data will be overwritten.",
                    _profileManager->backups()[backup_index].company.c_str(),
                    _profileManager->backups()[backup_index].timestamp.year,
                    _profileManager->backups()[backup_index].timestamp.month,
                    _profileManager->backups()[backup_index].timestamp.day,
                    _profileManager->backups()[backup_index].timestamp.hour,
                    _profileManager->backups()[backup_index].timestamp.minute,
                    _profileManager->backups()[backup_index].timestamp.second);
        ImGui::PopTextWrapPos();

        if(ImGui::BeginTable("##RestoreBackupLayout", 2)) {
            ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch);
            ImGui::TableSetupColumn("##YesNo", ImGuiTableColumnFlags_WidthFixed);

            ImGui::TableNextRow();

            ImGui::TableSetColumnIndex(1);
            if(ImGui::Button("Yes")) {
                if(!_profileManager->restoreBackup(backup_index)) {
                    SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error when restoring backup",
                                             _profileManager->lastError().c_str(), window());
                }
                _profileManager->refreshProfiles();
                ImGui::CloseCurrentPopup();
            }
            ImGui::SameLine();
            if(ImGui::Button("No", ImGui::GetItemRectSize())) {
                ImGui::CloseCurrentPopup();
            }

            ImGui::EndTable();
        }

        ImGui::EndPopup();
    }

    if(ImGui::BeginPopupModal("Delete backup", nullptr,
                              ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize))
    {
        ImGui::PushTextWrapPos(windowSize().x() * 0.40f);
        ImGui::Text("Are you sure you want to delete the %s backup from %.4i-%.2i-%.2i %.2i:%.2i:%.2i ? This operation is irreversible.",
                    _profileManager->backups()[backup_index].company.c_str(),
                    _profileManager->backups()[backup_index].timestamp.year,
                    _profileManager->backups()[backup_index].timestamp.month,
                    _profileManager->backups()[backup_index].timestamp.day,
                    _profileManager->backups()[backup_index].timestamp.hour,
                    _profileManager->backups()[backup_index].timestamp.minute,
                    _profileManager->backups()[backup_index].timestamp.second);
        ImGui::PopTextWrapPos();

        if(ImGui::BeginTable("##DeleteBackupLayout", 2)) {
            ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch);
            ImGui::TableSetupColumn("##YesNo", ImGuiTableColumnFlags_WidthFixed);

            ImGui::TableNextRow();

            ImGui::TableSetColumnIndex(1);
            if(ImGui::Button("Yes")) {
                if(!_profileManager->deleteBackup(backup_index)) {
                    SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error when deleting backup",
                                             _profileManager->lastError().c_str(), window());
                }
                ImGui::CloseCurrentPopup();
            }
            ImGui::SameLine();
            if(ImGui::Button("No", ImGui::GetItemRectSize())) {
                ImGui::CloseCurrentPopup();
            }

            ImGui::EndTable();
        }

        ImGui::EndPopup();
    }

    static ImGuiID restore_backup_popup_id = ImGui::GetID("Restore backup");
    static ImGuiID delete_backup_popup_id = ImGui::GetID("Delete backup");

    if(ImGui::BeginTable("##BackupsLabelLayout", 2)) {
        ImGui::TableSetupColumn("##Label", ImGuiTableColumnFlags_WidthStretch);
        ImGui::TableSetupColumn("##Refresh", ImGuiTableColumnFlags_WidthFixed);

        ImGui::TableNextRow();
        ImGui::TableSetColumnIndex(0);
        ImGui::TextUnformatted("Here's a list of detected backups:");

        ImGui::TableSetColumnIndex(1);
        if(ImGui::SmallButton("Refresh")) {
            _profileManager->refreshBackups();
        }

        ImGui::EndTable();
    }

    if(_profileManager->backups().empty()) {
        ImGui::TextDisabled("No backups were found.");
    }
    else if(ImGui::BeginTable("##Backups", 4,
                         ImGuiTableFlags_BordersOuter|ImGuiTableFlags_RowBg))
    {
        ImGui::TableSetupScrollFreeze(0, 1);
        ImGui::TableSetupColumn("##CompanyName", ImGuiTableColumnFlags_WidthFixed);
        ImGui::TableSetupColumn("##BackupDate", ImGuiTableColumnFlags_WidthFixed);
        ImGui::TableSetupColumn("##Type", ImGuiTableColumnFlags_WidthFixed);
        ImGui::TableSetupColumn("##Actions", ImGuiTableColumnFlags_WidthFixed);

        ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
        ImGui::TableSetColumnIndex(0);
        ImGui::TextUnformatted("Company name");
        ImGui::TableSetColumnIndex(1);
        ImGui::TextUnformatted("Backup date");
        ImGui::TableSetColumnIndex(2);
        ImGui::TextUnformatted("Type");
        ImGui::TableSetColumnIndex(3);
        ImGui::TextUnformatted("Actions");

        for(std::size_t i = 0; i < _profileManager->backups().size(); ++i) {
            ImGui::TableNextRow();

            ImGui::TableSetColumnIndex(0);
            ImGui::TextUnformatted(_profileManager->backups()[i].company.c_str());
            if(ImGui::IsItemHovered()) {
                ImGui::BeginTooltip();
                for(const auto& file : _profileManager->backups()[i].includedFiles) {
                    ImGui::TextUnformatted(file.c_str());
                }
                ImGui::EndTooltip();
            }

            ImGui::TableSetColumnIndex(1);
            ImGui::Text("%.4i-%.2i-%.2i %.2i:%.2i:%.2i",
                        _profileManager->backups()[i].timestamp.year,
                        _profileManager->backups()[i].timestamp.month,
                        _profileManager->backups()[i].timestamp.day,
                        _profileManager->backups()[i].timestamp.hour,
                        _profileManager->backups()[i].timestamp.minute,
                        _profileManager->backups()[i].timestamp.second);

            ImGui::TableSetColumnIndex(2);
            ImGui::TextUnformatted(_profileManager->backups()[i].type == ProfileType::Demo ? "Demo" : "Full");

            ImGui::TableSetColumnIndex(3);
            ImGui::PushID(i);
            if(ImGui::SmallButton(ICON_FA_UNDO)) {
                backup_index = i;
                ImGui::OpenPopup(restore_backup_popup_id);
            }
            ImGui::SameLine(0.0f, 2.0f);
            if(ImGui::SmallButton(ICON_FA_TRASH_ALT)) {
                backup_index = i;
                ImGui::OpenPopup(delete_backup_popup_id);
            }
            ImGui::PopID();
        }
        ImGui::EndTable();
    }

    ImGui::PushTextWrapPos(ImGui::GetWindowContentRegionWidth());
    ImGui::TextUnformatted("Hover over a company name to see which files are included in the backup.");
    ImGui::PopTextWrapPos();

    if(ImGui::BeginTable("##BackupListCloseLayout", 2)) {
        ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch);
        ImGui::TableSetupColumn("##Close", ImGuiTableColumnFlags_WidthFixed);

        ImGui::TableNextRow();

        ImGui::TableSetColumnIndex(1);
        if(ImGui::Button("Close")) {
            ImGui::CloseCurrentPopup();
        }

        ImGui::EndTable();
    }

    ImGui::EndPopup();

    return 0;
}

auto SaveTool::drawBackupProfilePopup(std::size_t profile_index) -> ImGuiID {
    if(!ImGui::BeginPopupModal("Include builds ?##IncludeBuildsDialog", nullptr,
                               ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
    {
        return ImGui::GetID("Include builds ?##IncludeBuildsDialog");
    }

    ImGui::TextUnformatted("Should builds be added to the backup ?");

    if(ImGui::BeginTable("##NameBackupLayout", 2)) {
        ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch);
        ImGui::TableSetupColumn("##YesNo", ImGuiTableColumnFlags_WidthFixed);

        ImGui::TableNextRow();

        ImGui::TableSetColumnIndex(1);
        if(ImGui::Button("Yes")) {
            _profileManager->backupProfile(profile_index, true);
            ImGui::CloseCurrentPopup();
        }
        ImGui::SameLine();
        if(ImGui::Button("No", ImGui::GetItemRectSize())) {
            _profileManager->backupProfile(profile_index, false);
            ImGui::CloseCurrentPopup();
        }
        ImGui::SameLine();
        if(ImGui::Button("Cancel")) {
            ImGui::CloseCurrentPopup();
        }

        ImGui::EndTable();
    }

    ImGui::EndPopup();

    return 0;
}

auto SaveTool::drawDeleteProfilePopup(std::size_t profile_index) -> ImGuiID {
    if(!ImGui::BeginPopupModal("Confirmation##DeleteProfileConfirmation", nullptr,
                               ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
    {
        return ImGui::GetID("Confirmation##DeleteProfileConfirmation");
    }

    static bool delete_builds = false;
    if(ImGui::IsWindowAppearing()) {
        delete_builds = false;
    }

    ImGui::PushTextWrapPos(windowSize().x() * 0.40f);
    ImGui::Text("Are you sure you want to delete the %s %s profile ? This operation is irreversible.",
                _profileManager->profiles()[profile_index].companyName().c_str(),
                _profileManager->profiles()[profile_index].type() == ProfileType::Demo ? "demo" : "full game");
    ImGui::PopTextWrapPos();

    if(ImGui::BeginTable("##DeleteProfileLayout", 2)) {
        ImGui::TableSetupColumn("##Checkbox", ImGuiTableColumnFlags_WidthStretch);
        ImGui::TableSetupColumn("##YesNo", ImGuiTableColumnFlags_WidthFixed);

        ImGui::TableNextRow();
        ImGui::TableSetColumnIndex(0);
        ImGui::Checkbox("Delete builds", &delete_builds);

        ImGui::TableSetColumnIndex(1);
        if(ImGui::Button("Yes")) {
            if(!_profileManager->deleteProfile(profile_index, delete_builds)) {
                SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error when deleting profile",
                                         _profileManager->lastError().c_str(), window());
            }
            ImGui::CloseCurrentPopup();
        }
        ImGui::SameLine();
        if(ImGui::Button("No", ImGui::GetItemRectSize())) {
            ImGui::CloseCurrentPopup();
        }

        ImGui::EndTable();
    }

    ImGui::EndPopup();

    return 0;
}