import PlaceableTab from "./placeable-tab.mjs";
import RegionFilter from "../filters/region-filter.mjs";

/**
 * The Region-specific placeables tab.
 * @extends {PlaceableTab}
 */
export default class RegionTab extends PlaceableTab {
  constructor(...args) {
    super(...args);
    Object.assign(this._filterState, { behaviorType: "" });
  }

  /* -------------------------------------------- */

  /** @override */
  static ENTRY_PARTIAL = "templates/sidebar/tabs/placeable/region.hbs";

  /* -------------------------------------------- */

  /** @override */
  static FILTER_CLASS = RegionFilter;

  /* -------------------------------------------- */
  /*  Rendering                                   */
  /* -------------------------------------------- */

  /** @inheritDoc */
  async _prepareEntry(entry, context) {
    context = await super._prepareEntry(entry, context);
    const { ALWAYS, OBSERVER } = CONST.REGION_VISIBILITY;
    const { color, elevation, shapes, visibility, hidden } = entry;
    if ( game.user.isGM ) {
      const hasPlayerObserver = game.users.some(u => !u.isGM && entry.testUserPermission(u, "OBSERVER"));
      context.isVisible = !hidden && ((visibility === ALWAYS) || ((visibility === OBSERVER) && hasPlayerObserver));
    }
    const hasElevation = Number.isFinite(elevation.bottom) || Number.isFinite(elevation.top);
    foundry.utils.mergeObject(context, { color, elevation, empty: !shapes.length });
    context.elevation.bottom = Number.isFinite(elevation.bottom)
      ? elevation.bottom.toNearest(.01).toLocaleString(game.i18n.lang)
      : "−∞";
    context.elevation.top = Number.isFinite(elevation.top)
      ? elevation.top.toNearest(.01).toLocaleString(game.i18n.lang)
      : "+∞";
    if ( !hasElevation ) context.elevation.label = "";
    else if ( elevation.topInclusive || (elevation.bottom === elevation.top) ) {
      context.elevation.label = `[${context.elevation.bottom}, ${context.elevation.top}]`;
    } else {
      context.elevation.label = `[${context.elevation.bottom}, ${context.elevation.top})`;
    }
    return context;
  }

  /* -------------------------------------------- */
  /*  Event Listeners & Handlers                  */
  /* -------------------------------------------- */

  /** @inheritDoc */
  _getEntryContextOptions() {
    const options = super._getEntryContextOptions();
    const editIndex = options.findIndex(o => o.label === "SIDEBAR.Edit");
    options.splice(editIndex + 1, 0, {
      label: "OWNERSHIP.Configure",
      icon: "fa-solid fa-user-lock",
      visible: () => game.user.isGM,
      onClick: (event, li) => this.#onConfigureOwnership(li)
    });
    return options;
  }

  /* -------------------------------------------- */

  /**
   * Handle configuring the region's ownership.
   * @param {HTMLElement} li  The context menu target.
   */
  #onConfigureOwnership(li) {
    const { top, left, width } = li.getBoundingClientRect();
    const doc = this._getPlaceableFromElement(li);
    const { width: sheetWidth } = foundry.applications.apps.DocumentOwnershipConfig.DEFAULT_OPTIONS.position;
    this.renderChild(new foundry.applications.apps.DocumentOwnershipConfig({
      document: doc,
      position: {
        top: top + 40,
        left: left + ((width - sheetWidth) / 2)
      }
    }));
  }

  /* -------------------------------------------- */
  /*  Filtering                                   */
  /* -------------------------------------------- */

  /** @inheritDoc */
  _clearFilters() {
    super._clearFilters();
    this._filterState.behaviorType = "";
  }

  /* -------------------------------------------- */

  /** @inheritDoc */
  _hasAdvancedFilters() {
    return super._hasAdvancedFilters() || (this._filterState.behaviorType.length > 0);
  }

  /* -------------------------------------------- */

  /** @inheritDoc */
  _matchesFilter(entry) {
    const { behaviorType } = this._filterState;
    if ( behaviorType.length && !entry.behaviors.some(b => b.type === behaviorType) ) return false;
    return true;
  }
}
