#pragma once

#include <filesystem>
#include <optional>
#include <string>
#include <string_view>
#include <vector>

#include "../resource/schema.hpp"
#include "editor.hpp"

namespace game::developer
{
  class Document
  {
  public:
    struct SchemaFile
    {
      std::string filename{};
      std::string label{};
      std::filesystem::path path{};
      resource::xml::Schema::Element::Type type{resource::xml::Schema::Element::UNKNOWN};
      resource::xml::Schema schema{};
      bool isExists{};
      bool isValid{};
    };

    struct Snapshot
    {
      resource::xml::Schema schema{};
      std::string message{};
    };

    std::filesystem::path path{};
    std::vector<SchemaFile> schemas{};
    Editor editor{};
    std::vector<Snapshot> undo{};
    std::vector<Snapshot> redo{};
    std::optional<resource::xml::Schema> pendingEditSnapshot{};
    bool isDirty{};

    SchemaFile* schema_file_get(std::string_view filename);
    const SchemaFile* schema_file_get(std::string_view filename) const;
    SchemaFile* dialogue_schema_get();
    const SchemaFile* dialogue_schema_get() const;
    bool can_undo() const;
    bool can_redo() const;
    void edit_snapshot_begin();
    resource::xml::Schema edit_snapshot_take_or(resource::xml::Schema);
    void edit_snapshot_clear();
    void snapshot_push(resource::xml::Schema, std::string);
    std::string undo_apply();
    std::string redo_apply();
    void history_clear();

    static std::string change_message_get(const resource::xml::Schema& before, const resource::xml::Schema& after);
  };
}
