import { SYSTEM_RDD } from "../constants.js";
import { Misc } from "../misc.js";
import { DialogEncaissementTables } from "./dialog-encaissement-tables.js";

const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;

const listeReglesOptionnelles = [
  { group: 'Règles générales', name: 'appliquer-fatigue',           descr: "Appliquer les règles de fatigue"},
  { group: 'Règles générales', name: 'astrologie',                  descr: "Appliquer les ajustements astrologiques aux jets de chance et aux rituels"},
  { group: 'Récupération', name: 'transformation-stress',           descr: "Transformer le stress durant Château Dormant"},
  { group: 'Récupération', name: 'recuperation-chance',             descr: "Récupérer la chance durant Château Dormant"},
  { group: 'Récupération', name: 'recuperation-ethylisme',          descr: "Récupérer l'éthylisme"},
  { group: 'Récupération', name: 'recuperation-reve',               descr: "Récupérer le rêve pendant la nuit (les jets sont toujours faits pour les Rêves de Dragons)"},
  { group: 'Récupération', name: 'recuperation-moral',              descr: "Le moral revient vers 0 durant Château Dormant"},
  { group: 'Récupération', name: 'nouveau-mode-repos',             descr: "Utiliser le nouveau mode de repos (sélection heures + dialogue Château Dormant intégré)", default: false},

  { group: 'Règles de combat', name: 'armes-equipees',              descr: "Proposer uniquement les armes équipées au combat", default: false},
  { group: 'Règles de combat', name: 'localisation-aleatoire',      descr: "Proposer une localisation aléatoire des blessures" },
  { group: 'Règles de combat', name: 'recul',                       descr: "Appliquer le recul en cas de particulière en force ou de charge" },
  { group: 'Règles de combat', name: 'acrobatie-pour-recul',        descr: "L'acrobatie aide à ne pas chuter en cas de recul" , default: false },
  { group: 'Règles de combat', name: 'resistanceArmeParade',        descr: "Faire le jet de résistance des armes lors de parades pouvant les endommager" },
  { group: 'Règles de combat', name: 'deteriorationArmure',         descr: "Tenir compte de la détérioration des armures" },
  { group: 'Règles de combat', name: 'defenseurDesarme',            descr: "Le défenseur peut être désarmé en parant une particulière en force ou une charge avec une arme autre qu'un bouclier" },
  { group: 'Règles de combat', name: 'categorieParade',             descr: "Le défenseur doit obtenir une significative en cas de parade avec des armes de catégories différentes" },
  { group: 'Règles de combat', name: 'tripleSignificative',         descr: "En cas de demi-surprise, d'attaque particulière en finesse, et de catégories d'armes différentes, le défenseur doit obtenir 1/8 des chances de succès" },
  { group: 'Règles de combat', name: 'validation-encaissement-gr',  descr: "Le Gardien des Rêves doit valider les jets d'encaissement et peut les changer.", default: false },

  { group: 'Automatisation', name: 'chateau-dormant-gardien',       descr: "Saisie des heures de sommeil/jets de moral par le gardien des rêves", default: true },

  { group: 'Affichage', name: 'afficher-colonnes-reussite',         descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false },
  { group: 'Affichage', name: 'afficher-prix-joueurs',              descr: "Afficher le prix de l'équipement des joueurs", uniquementJoueur: true},
  { group: 'Affichage', name: 'afficher-table-source',              descr: "Afficher la table d'origine des tirages aléatoires", default: false },

  { group: 'Confirmations', name: 'confirmer-combat-sans-cible',         descr: "Confirmer avant une attaque sans cible", scope: "client"},
  { group: 'Confirmations', name: 'confirmation-tmr',                    descr: "Confirmer pour monter dans les TMR", scope: "client"},
  { group: 'Confirmations', name: 'confirmation-tmr-rencontre',          descr: "Confirmer pour monter dans les TMR avec rencontre en attente", scope: "client"},
  { group: 'Confirmations', name: 'confirmation-refouler',               descr: "Confirmer avant de refouler", scope: "client"},
  { group: 'Confirmations', name: 'confirmation-vider',                  descr: "Confirmer pour vider l'équipement", scope: "client"},
  { group: 'Confirmations', name: 'confirmation-supprimer-lien-acteur',  descr: "Confirmer pour détacher un animal/suivant/véhicule", scope: "client"},
  { group: 'Confirmations', name: 'confirmation-supprimer-equipement',   descr: "Confirmer la suppression des équipements", scope: "client"},
  { group: 'Confirmations', name: 'confirmation-supprimer-oeuvre',       descr: "Confirmer la suppression des oeuvres", scope: "client"},
  { group: 'Confirmations', name: 'confirmation-supprimer-connaissance', descr: "Confirmer la suppression des connaissances", scope: "client"},
  { group: 'Confirmations', name: 'confirmation-supprimer-draconique',   descr: "Confirmer la suppression des queues, souffles, têtes", scope: "client"},
  { group: 'Confirmations', name: 'confirmation-supprimer-effet',        descr: "Confirmer la suppression des effets", scope: "client"},
  { group: 'Confirmations', name: 'confirmation-supprimer-competence',   descr: "Confirmer la suppression des compétences", scope: "client"},
  { group: 'Confirmations', name: 'confirmation-supprimer-autres',       descr: "Confirmer la suppression des autres types d'Objets", scope: "client"},

  { group: 'Options alternatives', name: 'degat-minimum-malus-libre-simple',  descr: "Le malus libre d'attaque remplace une des valeurs de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, si le plus petit dé est inférieur à 4, alors il devient 4.", default: false },
  { group: 'Options alternatives', name: 'degat-minimum-malus-libre',         descr: "Le malus libre d'attaque remplace une valeur de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, tout résultat inférieur à 4 devient 4.", default: false },
  { group: 'Options alternatives', name: 'degat-ajout-malus-libre',           descr: "Le malus libre d'attaque s'ajoute au jet d'encaissement et aux autres bonus. Exemple : la difficulté libre de l'attaquant est de -4. Le jet d'encaissement est effectué à 2d10+4, plus les bonus de situation et d'armes.", default: false },
  { group: 'Options alternatives', name: 'plafonner-bonus-case-reve',        descr: "Plafonner le bonus de case à la carac Rêve", default: false },
  { group: 'Options alternatives', name: 'tables-encaissement-revisees',    descr: "Utiliser les tables révisées d'encaissement (paliers fins, pertes statiques)", default: false },
];

const uniquementJoueur = listeReglesOptionnelles.filter(it => it.uniquementJoueur).map(it=>it.name);

export class ReglesOptionnelles extends HandlebarsApplicationMixin(ApplicationV2) {
  static initSettings() {
    for (const regle of listeReglesOptionnelles) {
      const name = regle.name;
      const id = ReglesOptionnelles._getIdRegle(name);
      game.settings.register(SYSTEM_RDD, id, { name: id, scope: regle.scope ?? "world", config: false, default: regle.default == undefined ? true : regle.default, type: Boolean });
    }

    game.settings.registerMenu(SYSTEM_RDD, "rdd-options-regles", {
      name: "Choisir les règles optionnelles",
      label: "Règles optionnelles",
      hint: "Ouvre la fenêtre de sélection des règles optionnelles",
      icon: "fas fa-bars",
      type: ReglesOptionnelles
    });
  }

  static DEFAULT_OPTIONS = {
    tag: "form",
    id: "regles-optionnelles",
    classes: ["regles-optionnelles"],
    form: { submitOnChange: false, closeOnSubmit: true },
    position: { width: 550, height: 650 },
    window: { title: "Règles optionnelles", icon: "fa-solid fa-bars" }
  }

  static PARTS = {
    form: { template: "systems/foundryvtt-reve-de-dragon/templates/settings/regles-optionnelles.hbs" }
  }

  static _getIdRegle(name) {
    return `rdd-option-${name}`;
  }

  async _prepareContext() {
    const regles = listeReglesOptionnelles.filter(it => game.user.isGM || it.scope == "client").map(it => {
      it = foundry.utils.deepClone(it);
      it.id = ReglesOptionnelles._getIdRegle(it.name);
      it.active = ReglesOptionnelles.isSet(it.name);
      return it;
    });
    return {
      regles,
      groups: Misc.classify(regles, it => it.group),
      isGM: game.user.isGM,
    }
  }

  static isUsing(name) {
    if (game.user.isGM && uniquementJoueur.includes(name)) {
      return true;
    }
    return ReglesOptionnelles.isSet(name);
  }

  static isSet(name) {
    return game.settings.get(SYSTEM_RDD, ReglesOptionnelles._getIdRegle(name));
  }

  static set(name, value) {
    return game.settings.set(SYSTEM_RDD, ReglesOptionnelles._getIdRegle(name), value ? true: false);
  }

  async _onRender(context, options) {
    this.element.querySelectorAll(".select-option").forEach(el => {
      el.addEventListener("click", async event => {
        const id = event.currentTarget.getAttribute("name");
        if (id) {
          const isChecked = event.currentTarget.checked;
          await game.settings.set(SYSTEM_RDD, id, isChecked);
        }
      });
    });
    const btn = this.element.querySelector(".btn-voir-tables-encaissement");
    if (btn) {
      btn.addEventListener("click", () => {
        new DialogEncaissementTables().render(true);
      });
    }
  }
}
