import { RDD_CONFIG, SYSTEM_RDD } from "../constants.js";
import { Misc } from "../misc.js";
import { RdDBonus } from "../rdd-bonus.js";

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

export const STATUSES = {
  StatusGrappling: 'grappling',
  StatusGrappled: 'grappled',
  StatusRestrained: 'restrain',
  StatusStunned: 'stun',
  StatusProne: 'prone',
  StatusUnconscious: 'unconscious',
  StatusBlind: 'blind',
  StatusComma: 'comma',
  StatusBleeding: 'bleeding',
  StatusDead: 'dead',
  StatusDemiReve: 'demi-reve',
  StatusSurEnc: 'sur-encombrement',
  StatusForceWeak: 'force insuffisante',
  StatusMalade: 'malade',
}

export const forceWeakStatusEffect = { rdd: true, id: STATUSES.StatusForceWeak, name: 'EFFECT.StatusForceWeak', img: RDD_CONFIG.icons.forceWeak };
export const surEncEffect = { rdd: true, id: STATUSES.StatusSurEnc, name: 'EFFECT.StatusSurEnc', img: RDD_CONFIG.icons.surenc };
export const demiReveStatusEffect = { rdd: true, id: STATUSES.StatusDemiReve, name: 'EFFECT.StatusDemiReve', img: RDD_CONFIG.icons.demiReve };

const rddStatusEffects = [
  { rdd: true, id: STATUSES.StatusGrappling, name: 'EFFECT.StatusGrappling', img: RDD_CONFIG.icons.empoignade },
  { rdd: true, id: STATUSES.StatusGrappled, tint: '#d5633d', name: 'EFFECT.StatusGrappled', img: RDD_CONFIG.icons.empoignade },

  { rdd: true, id: STATUSES.StatusRestrained, name: 'EFFECT.StatusRestrained', img: 'icons/svg/net.svg' },
  { rdd: true, id: STATUSES.StatusStunned, name: 'EFFECT.StatusStunned', img: 'icons/svg/stoned.svg', "duration.rounds": 1 },
  { rdd: true, id: STATUSES.StatusProne, name: 'EFFECT.StatusProne', img: 'icons/svg/falling.svg' },

  { rdd: true, id: STATUSES.StatusUnconscious, name: 'EFFECT.StatusUnconscious', img: 'icons/svg/unconscious.svg' },
  { rdd: true, id: STATUSES.StatusBlind, name: 'EFFECT.StatusBlind', img: 'icons/svg/blind.svg' },
  { rdd: true, id: STATUSES.StatusComma, name: 'EFFECT.StatusComma', img: 'icons/svg/skull.svg' },

  { rdd: true, id: STATUSES.StatusBleeding, name: 'EFFECT.StatusBleeding', img: 'icons/svg/blood.svg' },
  { rdd: true, id: STATUSES.StatusMalade, name: 'EFFECT.StatusMalade', img: RDD_CONFIG.icons.malade },
  { rdd: true, id: STATUSES.StatusDead, name: 'EFFECT.StatusDead', img: 'icons/svg/skull.svg' },
  surEncEffect,
  demiReveStatusEffect,
  forceWeakStatusEffect,
]

const statusDemiSurprise = new Set([STATUSES.StatusStunned, STATUSES.StatusProne, STATUSES.StatusRestrained, STATUSES.StatusForceWeak])
const statusSurpriseTotale = new Set([STATUSES.StatusUnconscious, STATUSES.StatusBlind, STATUSES.StatusComma])

export class StatusEffects extends HandlebarsApplicationMixin(ApplicationV2) {

  static onReady() {
    const rddEffectIds = rddStatusEffects.map(it => it.id)
    rddStatusEffects.forEach(it => {
      it.name = game.i18n.localize(it.name)
      it.statuses = new Set([it.id])
    })
    const defaultStatusEffectIds = CONFIG.statusEffects.map(it => it.id);
    game.settings.register(SYSTEM_RDD, "use-status-effects", {
      name: "use-status-effects",
      scope: "world",
      config: false,
      default: defaultStatusEffectIds.join(),
      type: String
    });

    game.settings.registerMenu(SYSTEM_RDD, "select-status-effect", {
      name: "Choisir les effets disponibles",
      label: "Choix des effets",
      hint: "Ouvre la fenêtre de sélection des effets/status appliqués aux acteurs",
      icon: "fas fa-bars",
      type: StatusEffects,
      restricted: true
    });

    CONFIG.RDD.allEffects = rddStatusEffects.concat(CONFIG.statusEffects.filter(it => !rddEffectIds.includes(it.id)))

    StatusEffects._setUseStatusEffects(StatusEffects._getUseStatusEffects());
  }

  static isSurprise(effect) {
    return StatusEffects.niveauSurprise(effect, true) > 0
  }

  static getSurprise(effects, isCombat = undefined) {
    return StatusEffects.typeSurprise(
      effects.map(it => StatusEffects.niveauSurprise(it, isCombat))
        .reduce(Misc.sum(), 0)
    )
  }

  static getActorEffetSurprise(actor) {
    const effets = actor?.getEffects(StatusEffects.isSurprise) ?? []
    return {
      effets: effets,
      surprise: effets.length > 0
        ? RdDBonus.find(StatusEffects.getSurprise(effets, true))
        : undefined
    }
  }

  static niveauSurprise(effect, isCombat) {
    if (statusSurpriseTotale.intersects(effect.statuses)) {
      return 2
    }
    if (statusDemiSurprise.intersects(effect.statuses)) {
      return 1
    }
    if (isCombat && StatusEffects.isDemiReve(effect)) {
      return 1
    }
    return 0
  }

  static typeSurprise(niveauSurprise) {
    switch (niveauSurprise) {
      case 0: return ''
      case 1: return 'demi'
      default: return 'totale'
    }
  }

  static isDemiReve(effect) {
    return effect.statuses.has(STATUSES.StatusDemiReve)
  }

  static _getUseStatusEffects() {
    return game.settings.get(SYSTEM_RDD, "use-status-effects")?.split(',') ?? [];
  }

  static _setUseStatusEffects(effectIds) {
    if (game.user.isGM) {
      game.settings.set(SYSTEM_RDD, "use-status-effects", effectIds.join());
    }

    for (let effect of CONFIG.RDD.allEffects) {
      effect.active = effect.rdd || effectIds.includes(effect.id);
    }
    CONFIG.statusEffects = CONFIG.RDD.allEffects.filter(it => it.active);
  }

  static prepareActiveEffect(effectId) {
    let status = rddStatusEffects.find(it => it.statuses? it.statuses.has(effectId) : it.id == effectId)
    if (status) {
      status = foundry.utils.deepClone(status)
      status.statuses = new Set([effectId])
    }
    return status;
  }

  static demiReve() {
    return demiReveStatusEffect;
  }

  static DEFAULT_OPTIONS = {
    tag: "form",
    id: "status-effects",
    classes: ["rdd-dialog", "status-effects"],
    form: { submitOnChange: false, closeOnSubmit: true },
    position: { width: 350, height: 800 },
    window: { title: "Choix des status/effets", icon: "fa-solid fa-bars" }
  }

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

  async _prepareContext() {
    const used = StatusEffects._getUseStatusEffects();
    const effects = foundry.utils.deepClone(CONFIG.RDD.allEffects);
    effects.forEach(it => it.active = used.includes(it.id))
    return { effects }
  }

  async _onRender(context, options) {
    this.element.querySelectorAll(".select-effect").forEach(el => {
      el.addEventListener("click", async event => {
        let id = event.currentTarget.getAttribute("name");
        if (id) {
          let selected = StatusEffects._getUseStatusEffects();
          let isChecked = event.currentTarget.checked;
          if (isChecked) {
            selected.push(id);
          } else {
            selected = selected.filter(it => it != id)
          }
          StatusEffects._setUseStatusEffects(selected);
        }
      });
    });
  }
}
