#pragma once

#include <filesystem>

#include <SDL3/SDL.h>
#include <SDL3/SDL_dialog.h>

namespace game::util
{
  class Dialog
  {
  public:
#define GAME_DIALOG_FILTERS(X)                                                                                     \
  X(NO_FILTER, {})                                                                                                  \
  X(ZIP_FILTER, {"ZIP archive", "zip;ZIP"})                                                                        \
  X(TEXTURE_FILTER, {"Texture", "png;PNG"})                                                                        \
  X(SOUND_FILTER, {"Sound", "wav;WAV;ogg;OGG;mp3;MP3"})

    enum Filter
    {
#define GAME_DIALOG_FILTER_ENUM(SYMBOL, ...) SYMBOL,
      GAME_DIALOG_FILTERS(GAME_DIALOG_FILTER_ENUM)
#undef GAME_DIALOG_FILTER_ENUM
    };

    static constexpr SDL_DialogFileFilter FILTERS[][1] = {
#define GAME_DIALOG_FILTER_VALUE(SYMBOL, ...) {__VA_ARGS__},
        GAME_DIALOG_FILTERS(GAME_DIALOG_FILTER_VALUE)
#undef GAME_DIALOG_FILTER_VALUE
    };

#undef GAME_DIALOG_FILTERS

#define GAME_DIALOG_TYPES(X)                                                                                       \
  X(NONE, NO_FILTER)                                                                                               \
  X(SCHEMA_FOLDER_OPEN, NO_FILTER)                                                                                 \
  X(DOCUMENT_EXPORT, ZIP_FILTER)                                                                                   \
  X(SCHEMA_RESOURCE_FOLDER_OPEN, NO_FILTER)                                                                        \
  X(SCHEMA_SOUND_OPEN, SOUND_FILTER)                                                                               \
  X(SCHEMA_TEXTURE_OPEN, TEXTURE_FILTER)

    enum Type
    {
#define GAME_DIALOG_TYPE_ENUM(SYMBOL, FILTER) SYMBOL,
      GAME_DIALOG_TYPES(GAME_DIALOG_TYPE_ENUM)
#undef GAME_DIALOG_TYPE_ENUM
    };

    static constexpr Filter TYPE_FILTERS[]{
#define GAME_DIALOG_TYPE_FILTER(SYMBOL, FILTER) FILTER,
        GAME_DIALOG_TYPES(GAME_DIALOG_TYPE_FILTER)
#undef GAME_DIALOG_TYPE_FILTER
    };

#undef GAME_DIALOG_TYPES

    SDL_Window* window{};
    std::filesystem::path path{};
    Type type{NONE};
    int selectedFilter{-1};

    Dialog() = default;
    explicit Dialog(SDL_Window*);

    void window_set(SDL_Window*);
    void file_open(Type);
    void file_save(Type);
    void folder_open(Type);
    bool is_selected(Type) const;
    void reset();
  };
}
