import { DialogItemAchat } from "./dialog-item-achat.js";
import { RdDItem } from "./item.js";
import { Misc } from "./misc.js";

export class RdDItemService extends RdDItem {

  static get defaultIcon() {
    return "systems/foundryvtt-reve-de-dragon/icons/items/services.webp";
  }

  /** @override*/
  getUserLevel(user) {
    const level = super.getUserLevel(user);
    if (level == CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE) {
      // si quelqu'un a accès au lien d'un service, il peut le voir
      return CONST.DOCUMENT_OWNERSHIP_LEVELS.LIMITED;
    }
    return level;
  }

  isService() { return true; }
  getChatItemTemplate() { return 'systems/foundryvtt-reve-de-dragon/templates/post-item-service.html'; }
  getProprietes() { return []; }

  getServiceItem(itemRef) {
    if (itemRef && this.isService()) {
      return this.system.items.find(it => it.id == itemRef.id && it.pack == itemRef.pack);
    }
    return undefined;
  }

  getQuantiteDisponible(itemRef, max) {
    if (this.system.illimite) {
      return max;
    }
    const subItem = this.getServiceItem(itemRef);
    return subItem?.system.quantite ?? 0;
  }

  async venteRefItem(ref, quantite, cout) {
    if (this.actor) {
      await this.actor.ajouterSols(cout);
    }
    await this.increaseRefItemQuantite(ref, -quantite);
  }

  async vendre(subItem) {
    const item = await RdDItem.getCorrespondingItem(subItem);
    const quantiteMax = this.system.illimite ? undefined : subItem.system.quantite;
    await item.proposerVente(quantiteMax);
  }

  async acheter(acheteur, subItem) {
    if (!acheteur) {
      ui.notifications.warn(`Pas d'acheteur sélectionné`);
      return;
    }
    const nbLots = this.system.illimite ? 1 : subItem.system.quantite;
    if (nbLots <= 0) {
      ui.notifications.warn(`${this.name} n'a plus de ${subItem.name} en vente`);
      return;
    }

    await DialogItemAchat.onAcheter({
      item: await RdDItem.getCorrespondingItem(subItem),
      acheteur,
      serviceSubItem: subItem,
      service: this,
      quantiteIllimite: this.system.illimite,
      nbLots,
      tailleLot: 1,
      prixLot: subItem.system.cout
    });
  }

  static createSubItem(linkedItem) {
    return {
      id: linkedItem.id,
      pack: linkedItem.pack,
      name: linkedItem.name,
      img: linkedItem.img,
      system: {
        quantite: 1,
        cout: linkedItem.system.cout ?? 0
      }
    };
  }

  static matchRefItem({ id, pack }) {
    return it => it.id == id && (pack ? (it.pack == pack) : (!it.pack));
  }

  findRefItem(ref) {
    return this.system.items.find(RdDItemService.matchRefItem(ref));
  }

  async increaseRefItemQuantite(ref, quantite) {
    await this.updateRefItem(ref,
      it => it.system.quantite = Math.max(0, it.system.quantite + quantite)
    );
  }

  async updateRefItem(ref, update = it => { }) {
    await this.updateRefItems(RdDItemService.matchRefItem(ref), update);
  }

  async addRefItem(newItem) {
    if (!newItem.id) {
      ui.notifications.warn(`${newItem?.name ?? '??'} n'a pas d'identifiant`);
      return;
    }
    if (this.system.items.find(RdDItemService.matchRefItem(newItem))) {
      ui.notifications.warn(`${newItem?.name ?? newItem.id} est déjà présent ici`);
      return;
    }
    await this.setRefItems([...this.system.items, newItem]);
  }

  async removeRefItem(ref) {
    await this.removeRefItems(RdDItemService.matchRefItem(ref));
  }

  async removeRefItems(matcher = it => false) {
    await this.setRefItems(this.system.items.filter(it => !matcher(it)));
  }

  async updateRefItems(matcher = it => false, update = it => { }) {
    const updatedList = this.system.items.map(it => {
      if (matcher(it)) {
        update(it);
      }
      return it;
    });
    await this.setRefItems(updatedList);
  }

  async setRefItems(newItems) {
    await this.update({ 'system.items': newItems.sort(Misc.ascending(it => it.type + ':' + it.name)) });
  }

}