#include <Display/WidgetDisplay/WorldCloneProgress/WorldCloneProgress.hpp>
#include <Version/Version.hpp>
#include <Widget/IconLabel/IconLabel.hpp>
#include <Widget/Layout/CompoundWidget/Deck/Deck.hpp>
#include <filesystem>
#include <Display/WidgetDisplay/WorldCloning/WorldCloning.hpp>
#include <Display/WidgetDisplay/WorldSelection/WorldSelection.hpp>
#include <Display/WidgetDisplay/WorldCreation/WorldCreation.hpp>
#include <Widget/Label/Label.hpp>
#include <Widget/Layout/Center/Center.hpp>
#include <Widget/Layout/Row/Row.hpp>
#include <Widget/Button/Button.hpp>
#include <Log/Log.hpp>
#include <Display/WidgetDisplay/WorldDisplay/WorldDisplay.hpp>
#include <Widget/Panel/Panel.hpp>
#include <Display/WidgetDisplay/MainMenuDisplay/MainMenuDisplay.hpp>
#include <Widget/TextField/TextField.hpp>
#include <Utilities/Utilities.hpp>
#include <World/LocalWorld/SinglePlayerWorld/SinglePlayerWorld.hpp>
#include <Widget/Layout/Column/HorizontalSeparator/HorizontalSeparator.hpp>
#include <Widget/Layout/CompoundWidget/Form/Form.hpp>
#include <Display/WidgetDisplay/MessageDisplay/MessageDisplay.hpp>
#include <Widget/Layout/CompoundWidget/FormSection/FormSection.hpp>
#include <Widget/Layout/CompoundWidget/FormField/FormField.hpp>
#include <Widget/Switch/Switch.hpp>
#include <Widget/Layout/CompoundWidget/WorldAvatarPicker/WorldAvatarPicker.hpp>
#include <Widget/Button/BackButton/BackButton.hpp>

void WorldCloning::doClone()
{
    std::string sourcePath = formatString("worlds/$+.voxelverse", existingWorldName);
    std::string destPath = formatString("worlds/$+.voxelverse", newWorldName);

    Display::setCurrent<WorldCloneProgress>(sourcePath, destPath, shouldEnableCheats, avatar);
}

std::string WorldCloning::getWorldNameError()
{
    if (newWorldName.size() == 0)
    {
        return "Please enter a world name.";
    }

    for (const char &c : newWorldName)
    {
        if (c == '/' || c == '\\')
        {
            return "Slashes are not allowed.";
        }
    }

    if (std::filesystem::exists(formatString("worlds/$+", newWorldName)))
    {
        return "Name already in use.";
    }

    return "";
}

WorldCloning::WorldCloning(std::string existingWorldName, const WorldIndex &existingIndex) :
    existingWorldName(existingWorldName),
    newWorldName(""),
    worldIndex(existingIndex),
    shouldEnableCheats(false),
    avatar(existingIndex.getAvatar())
{
    setWidget(
        new Center(
            new Form(
                "Clone world",

                new Column(
                    new Panel(glm::ivec2(170, 0)),

                    new FormSection(
                        new Column(
                            new Label("Existing world:"),
                            new Label(existingWorldName),
                            existingIndex.getGameVersion() == Version::ofThisBuild ?
                                (Widget*) new Panel() :
                                new Deck<Row, Center>(
                                    new Label(formatString("$+", existingIndex.getGameVersion()), Color::negativeStat),
                                    new IconLabel(Material::rightArrow),
                                    new Label(formatString("$+", Version::ofThisBuild), Color::positiveStat)
                                )
                        )
                    ),

                    new FormSection(
                        new Column(
                            new FormField(
                                "Name for the copy:",
                                newWorldName,
                                (Widget::focused = new TextField(newWorldName, [this](){ doClone(); })),
                                [this]()
                                {
                                    return getWorldNameError();
                                }
                            ),

                            new FormField(
                                "Cheats:",
                                shouldEnableCheats,
                                worldIndex.areCheatsEnabled() ?
                                    (Widget*) new Label("Already enabled.", Color::warning) :
                                    (Widget*) new Row(new Switch(shouldEnableCheats))
                            ),

                            new FormField(
                                "Avatar for the copy:",
                                avatar,
                                new WorldAvatarPicker(avatar)
                            )
                        )
                    )
                ),

                Layout::WithProportion<1>(),
                (new Button(
                    existingIndex.getGameVersion() == Version::ofThisBuild ? "Clone" : "Clone & Upgrade",
                    [this](){ doClone(); }
                ))
                    ->enabledIf([this]()
                        {
                            return getWorldNameError().size() == 0;
                        })
                    ->withIcon(Material::clone),

                Layout::WithProportion<1>(),
                new BackButton("Cancel")
            )
        )
    );
}