import {
  additionalJournals,
  additionalMacros,
  additionalModulePacks,
  creaturePacks,
  DONT_REMIND_AGAIN_KEY,
  journalPacks,
  macroPacks,
  MODULE_ID,
  MODULE_LABEL,
  playlistPacks,
  TMFXOptions,
  welcomeJournal,
} from './constants.js';
import { registerSidebarTab } from './sidebar.js';
import { UnlimitedTerrain } from './UnlimitedTerrain.js';

(async () => {
  async function TMFXLibImport() {
    TokenMagic.importPresetLibraryFromPath('modules/baileywiki-nuts-and-bolts/json/bw-tmfx-presets.json', TMFXOptions);
    await game.settings.set(MODULE_ID, 'imported', true);
    return game.settings.set(MODULE_ID, 'module-version', game.modules.get(MODULE_ID).version);
  }

  class Settings extends FormApplication {
    static init() {
      game.settings.registerMenu(MODULE_ID, 'menu', {
        name: 'Import and Update TMFX Preset Library',
        icon: `fas fa-file-import`,
        label: `Import/Update Menu`,
        type: Settings,
        restricted: true,
      });
    }

    static get defaultOptions() {
      return {
        ...super.defaultOptions,
        template: `modules/${MODULE_ID}/templates/TMFXsettings.html`,
        height: 'auto',
        title: `Baileywiki TMFX Preset Library Importer`,
        width: 600,
        classes: ['settings'],
        tabs: [
          {
            navSelector: '.tabs',
            contentSelector: 'form',
            initial: 'info',
          },
        ],
        submitOnClose: false,
      };
    }

    constructor(object = {}, options) {
      super(object, options);
    }

    _getHeaderButtons() {
      return super._getHeaderButtons();
    }

    activateListeners(html) {
      let tmfx_import = html.find('.import');
      let dnr = html.find('.dnr');

      tmfx_import.click(() => {
        TMFXLibImport();
        this.close();
      });
      dnr.click(() => {
        game.settings.set(MODULE_ID, DONT_REMIND_AGAIN_KEY, true);
        this.close();
      });
    }
  }

  Hooks.once('init', () => {
    // Register settings
    game.settings.register(MODULE_ID, DONT_REMIND_AGAIN_KEY, {
      name: '',
      default: false,
      type: Boolean,
      scope: 'world',
      config: false,
    });
    game.settings.register(MODULE_ID, 'imported', {
      name: '',
      default: false,
      type: Boolean,
      scope: 'world',
      config: false,
    });
    game.settings.register(MODULE_ID, 'module-version', {
      scope: 'world',
      config: false,
      type: String,
      default: '',
    });
    game.settings.register(MODULE_ID, 'me-cache-file-register-disable', {
      name: 'Disable automatic loading of Mass Edit Virtual Directory',
      scope: 'world',
      config: true,
      type: Boolean,
      default: false,
    });
    // BW Tab settings to track tutorial read state
    game.settings.register(MODULE_ID, 'read-tutorials', {
      scope: 'world',
      config: false,
      type: Object,
      default: {},
    });
    game.settings.register(MODULE_ID, 'read-tutorials-display-category', {
      scope: 'world',
      config: false,
      type: Object,
      default: {},
    });
    game.settings.register(MODULE_ID, 'disable-sidebar', {
      name: 'Disable Sidebar Tab',
      hint: '( Requires re-load for changes to take effect )',
      scope: 'world',
      config: true,
      type: Boolean,
      default: false,
    });
    Settings.init();
    if (!game.settings.get(MODULE_ID, 'disable-sidebar')) registerSidebarTab();
  });

  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //Nothing past this point needs to be changed, in theory at least
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  Hooks.once('scenePackerReady', (ScenePacker) => {
    // Initialise the Scene Packer with your adventure name and module name
    ScenePacker.Initialise({
      adventureName: MODULE_LABEL,
      moduleName: MODULE_ID,
      creaturePacks,
      journalPacks,
      macroPacks: macroPacks,
      playlistPacks: playlistPacks,
      additionalModulePacks: additionalModulePacks,
      welcomeJournal,
      additionalJournals,
      additionalMacros: additionalMacros,
      allowImportPrompts: false, // Set to false if you don't want the initial popup
    });
  });

  Hooks.once('ready', () => {
    const FALLBACK_TMFX_MESSAGE_TITLE = 'Baileywiki TMFX Preset Library';
    const FALLBACK_TMFX_UPDATE_MESSAGE = `<p class="notification info">Baileywiki Nuts an Bolts Has Been Updated</p>
		<p>Would you like to update the Baileywiki TMFX Preset Library?</p>`;

    if (game.modules.get('tokenmagic')?.active) {
      if (!game.user.isGM) return;
      if (game.settings.get(MODULE_ID, DONT_REMIND_AGAIN_KEY)) return;
      if (!game.settings.get(MODULE_ID, 'imported')) {
        new Settings().render(true);
      } else if (game.settings.get(MODULE_ID, 'module-version') !== game.modules.get(MODULE_ID).version) {
        Dialog.confirm({
          title: FALLBACK_TMFX_MESSAGE_TITLE + ' Updater',
          content: FALLBACK_TMFX_UPDATE_MESSAGE,
          yes: () => TMFXLibImport(),
        });
      }
    }
  });

  let CONFIG = {};
  try {
    CONFIG = await (await fetch(`modules/${MODULE_ID}/json/config.json`)).json();
  } catch (e) {
    console.warn(`Unable to read ${MODULE_ID} configuration file.`);
  }

  globalThis.BW = {
    UnlimitedTerrain,
    CONFIG,
    updateConfig: async (update = {}) => {
      const config = await (await fetch(`modules/${MODULE_ID}/json/config.json`)).json();
      foundry.utils.mergeObject(config, update);
      BW.CONFIG = config;

      const file = new File([JSON.stringify(config, null, 2)], 'config.json');
      return foundry.applications.apps.FilePicker.implementation.upload(
        'data',
        `modules/${MODULE_ID}/json/`,
        file,
        {},
        { notify: true },
      );
    },
  };
})();

/**
 * Configure Mass Edit
 */
Hooks.on('MassEdit.ready', () => {
  // Register virtual caches to be automatically loaded
  if (!game.settings.get(MODULE_ID, 'me-cache-file-register-disable') && typeof ForgeVTT === 'undefined') {
    const cacheContainingModules = [MODULE_ID, 'baileywiki-cabal-dungeon'];
    for (const id of cacheContainingModules) {
      if (game.modules.get(id)) MassEdit.registers.registerVirtualDirectoryCache(`modules/${id}/mass_edit_cache.json`);
    }
  }

  if (BW.CONFIG.MassEdit) {
    // Register virtual caches to be automatically loaded
    if (!game.settings.get(MODULE_ID, 'me-cache-file-register-disable') && typeof ForgeVTT === 'undefined') {
      BW.CONFIG.MassEdit.virtualDirectoryModules?.forEach((id) => {
        if (game.modules.get(id))
          MassEdit.registers.registerVirtualDirectoryCache(`modules/${id}/mass_edit_cache.json`);
      });
    }

    // Register a dialog message to be shown when a BW FauxScene import fails
    if (BW.CONFIG.MassEdit.sceneNotFoundMessage)
      MassEdit.registers.registerSceneNotFoundMessage(BW.CONFIG.MassEdit.sceneNotFoundMessage);

    // Register macros to be shown upon clicking MassEdit scene control button
    BW.CONFIG.MassEdit.sceneControlMacros?.forEach((macro) => {
      if (!macro.module || game.modules.get(macro.module)?.active) {
        MassEdit.registers.registerSceneControlMacro(macro);
      }
    });
  }
});
