import { Debordement } from "./debordement.js";
import { FermetureCites } from "./fermeture-cites.js";
import { QueteEaux } from "./quete-eaux.js";
import { TerreAttache } from "./terre-attache.js";
import { ReserveExtensible } from "./reserve-extensible.js";
import { DemiReve } from "./demi-reve.js";
import { TrouNoir } from "./trou-noir.js";
import { Rencontre } from "./rencontre.js";
import { SortReserve } from "./sort-reserve.js";
import { CarteTmr } from "./carte-tmr.js";
import { PontImpraticable } from "./pont-impraticable.js";
import { Draconique } from "./draconique.js";
import { PresentCites } from "./present-cites.js";
import { Desorientation } from "./desorientation.js";
import { Conquete } from "./conquete.js";
import { Pelerinage } from "./pelerinage.js";
import { Periple } from "./periple.js";
import { UrgenceDraconique } from "./urgence-draconique.js";
import { Misc } from "../misc.js";


export class EffetsDraconiques {
  static carteTmr = new CarteTmr();
  static demiReve = new DemiReve();
  static rencontre = new Rencontre();
  static sortReserve = new SortReserve();
  static debordement = new Debordement();
  static presentCites = new PresentCites();
  static fermetureCites = new FermetureCites();
  static queteEaux = new QueteEaux();
  static reserveExtensible = new ReserveExtensible();
  static terreAttache = new TerreAttache();
  static trouNoir = new TrouNoir();
  static pontImpraticable = new PontImpraticable();
  static desorientation = new Desorientation();
  static conquete = new Conquete();
  static pelerinage = new Pelerinage();
  static periple = new Periple();
  static urgenceDraconique = new UrgenceDraconique();

  static init() {
    Draconique.register(EffetsDraconiques.carteTmr);
    Draconique.register(EffetsDraconiques.demiReve);
    Draconique.register(EffetsDraconiques.rencontre);
    Draconique.register(EffetsDraconiques.sortReserve);
    Draconique.register(EffetsDraconiques.debordement);
    Draconique.register(EffetsDraconiques.fermetureCites);
    Draconique.register(EffetsDraconiques.queteEaux);
    Draconique.register(EffetsDraconiques.reserveExtensible);
    Draconique.register(EffetsDraconiques.terreAttache);
    Draconique.register(EffetsDraconiques.trouNoir);
    Draconique.register(EffetsDraconiques.pontImpraticable);
    Draconique.register(EffetsDraconiques.presentCites);
    Draconique.register(EffetsDraconiques.desorientation);
    Draconique.register(EffetsDraconiques.conquete);
    Draconique.register(EffetsDraconiques.pelerinage);
    Draconique.register(EffetsDraconiques.periple);
    Draconique.register(EffetsDraconiques.urgenceDraconique);
  }

  /* -------------------------------------------- */
  static isCaseInondee(caseTMR, coord) {
    return EffetsDraconiques.debordement.isCase(caseTMR, coord) ||
      EffetsDraconiques.pontImpraticable.isCase(caseTMR, coord);
  }

  static isInnaccessible(caseTMR, coord) {
    return EffetsDraconiques.trouNoir.isCase(caseTMR, coord) ||
      EffetsDraconiques.desorientation.isCase(caseTMR, coord);
  }

  static isCaseTrouNoir(caseTMR, coord) {
    return EffetsDraconiques.trouNoir.isCase(caseTMR, coord);
  }

  static isCasePelerinage(caseTMR, coord) {
    return EffetsDraconiques.pelerinage.isCase(caseTMR, coord);
  }

  static isReserveExtensible(caseTMR, coord) {
    return EffetsDraconiques.reserveExtensible.isCase(caseTMR, coord);
  }

  static isTerreAttache(caseTMR, coord) {
    return EffetsDraconiques.terreAttache.isCase(caseTMR, coord);
  }

  static isCiteFermee(caseTMR, coord) {
    return EffetsDraconiques.fermetureCites.isCase(caseTMR, coord);
  }

  static isPresentCite(caseTMR, coord) {
    return EffetsDraconiques.presentCites.isCase(caseTMR, coord);
  }
  /* -------------------------------------------- */
  static isMauvaiseRencontre(item) {
    return EffetsDraconiques.isMatching(item, it => Draconique.isQueueSouffle(it) && it.name.toLowerCase().includes('mauvaise rencontre'));
  }

  static isMonteeLaborieuse(item) {
    return EffetsDraconiques.isMatching(item, it => Draconique.isQueueSouffle(it) && it.name.toLowerCase().includes('montée laborieuse'));
  }

  /* -------------------------------------------- */
  static isFermetureCite(item) {
    return EffetsDraconiques.isMatching(item, it => EffetsDraconiques.fermetureCites.match(it));
  }

  static isPontImpraticable(item) {
    return EffetsDraconiques.isMatching(item, it => EffetsDraconiques.pontImpraticable.match(it));
  }

  static isDoubleResistanceFleuve(item) {
    return EffetsDraconiques.isMatching(item, it => Draconique.isSouffleDragon(it) && it.name.toLowerCase().includes('résistance du fleuve'));
  }

  static isPeage(item) {
    return EffetsDraconiques.isMatching(item, it => Draconique.isSouffleDragon(it) && it.name.toLowerCase().includes('péage'));
  }

  static isPeriple(item) {
    return EffetsDraconiques.isMatching(item, it => EffetsDraconiques.periple.match(it));
  }

  static isDesorientation(item) {
    return EffetsDraconiques.isMatching(item, it => EffetsDraconiques.desorientation.match(it));    // TODO
  }

  /* -------------------------------------------- */
  static isSortImpossible(item) {
    return EffetsDraconiques.isMatching(item, it =>
      EffetsDraconiques.conquete.match(it) ||
      EffetsDraconiques.periple.match(it) ||
      EffetsDraconiques.urgenceDraconique.match(it) ||
      EffetsDraconiques.pelerinage.match(it)
    );
  }

  static isSortReserveImpossible(item) {
    return EffetsDraconiques.isMatching(item, it =>
      EffetsDraconiques.conquete.match(it) ||
      EffetsDraconiques.periple.match(it) ||
      EffetsDraconiques.pelerinage.match(it)
    );
  }

  static isConquete(item) {
    return EffetsDraconiques.isMatching(item, it => EffetsDraconiques.conquete.match(it));
  }

  static isPelerinage(item) {
    return EffetsDraconiques.isMatching(item, it => EffetsDraconiques.pelerinage.match(it));
  }
  
  static countInertieDraconique(item) {
    return EffetsDraconiques.count(item, it => Draconique.isQueueDragon(it) && it.name.toLowerCase().includes('inertie draconique'));
  }
  
  static isUrgenceDraconique(item) {
    return EffetsDraconiques.isMatching(item, it => EffetsDraconiques.urgenceDraconique.match(it));
  }
  
  /* -------------------------------------------- */
  static isDonDoubleReve(item) {
    return EffetsDraconiques.isMatching(item, it => Draconique.isTeteDragon(it) && it.name == 'Don de double-rêve');
  }
  
  static isConnaissanceFleuve(item) {
    return EffetsDraconiques.isMatching(item, it => Draconique.isTeteDragon(it) && it.name.toLowerCase().includes('connaissance du fleuve'));
  }
  
  static isReserveEnSecurite(item) {
    return EffetsDraconiques.isMatching(item, it => Draconique.isTeteDragon(it) && it.name.toLowerCase().includes(' en sécurité'));
  }
  
  static isDeplacementAccelere(item) {
    item = Misc.data(item);
    return EffetsDraconiques.isMatching(item, it => Draconique.isTeteDragon(it) && it.name.toLowerCase().includes(' déplacement accéléré'));
  }
  
  static isMatching(item, matcher) {
    return EffetsDraconiques.toItems(item).find(matcher);
  }
  static count(item, matcher) {
    return EffetsDraconiques.toItems(item).filter(matcher).length;
  }

  static toItems(item) {
    return (item?.documentName === 'Actor') ? item.data.items : (item?.documentName === 'Item') ? [Misc.data(item)] : [];
  }

}