import { stringifyEntityRef, parseEntityRef, RELATION_OWNED_BY } from '@backstage/catalog-model';
import { getEntityRelations } from './utils/getEntityRelations.esm.js';

class EntityKindFilter {
  constructor(value, label) {
    this.value = value;
    this.label = label;
  }
  getCatalogFilters() {
    return { kind: this.value };
  }
  toQueryValue() {
    return this.value;
  }
}
class EntityTypeFilter {
  constructor(value) {
    this.value = value;
  }
  // Simplify `string | string[]` for consumers, always returns an array
  getTypes() {
    return Array.isArray(this.value) ? this.value : [this.value];
  }
  getCatalogFilters() {
    return { "spec.type": this.getTypes() };
  }
  toQueryValue() {
    return this.getTypes();
  }
}
class EntityTagFilter {
  constructor(values) {
    this.values = values;
  }
  filterEntity(entity) {
    return this.values.every((v) => (entity.metadata.tags ?? []).includes(v));
  }
  getCatalogFilters() {
    return { "metadata.tags": this.values };
  }
  toQueryValue() {
    return this.values;
  }
}
class EntityTextFilter {
  constructor(value) {
    this.value = value;
  }
  filterEntity(entity) {
    const words = this.toUpperArray(this.value.split(/\s/));
    const exactMatch = this.toUpperArray([entity.metadata.tags]);
    const partialMatch = this.toUpperArray([
      entity.metadata.name,
      entity.metadata.title,
      entity.spec?.profile?.displayName
    ]);
    for (const word of words) {
      if (exactMatch.every((m) => m !== word) && partialMatch.every((m) => !m.includes(word))) {
        return false;
      }
    }
    return true;
  }
  getFullTextFilters() {
    return {
      term: this.value,
      // Update this to be more dynamic based on table columns.
      fields: ["metadata.name", "metadata.title", "spec.profile.displayName"]
    };
  }
  toQueryValue() {
    return this.value;
  }
  toUpperArray(value) {
    return value.flat().filter((m) => Boolean(m)).map((m) => m.toLocaleUpperCase("en-US"));
  }
}
class EntityOwnerFilter {
  values;
  constructor(values) {
    this.values = values.reduce((fullRefs, ref) => {
      try {
        fullRefs.push(
          stringifyEntityRef(parseEntityRef(ref, { defaultKind: "Group" }))
        );
        return fullRefs;
      } catch (err) {
        return fullRefs;
      }
    }, []);
  }
  getCatalogFilters() {
    return { "relations.ownedBy": this.values };
  }
  filterEntity(entity) {
    return this.values.some(
      (v) => getEntityRelations(entity, RELATION_OWNED_BY).some(
        (o) => stringifyEntityRef(o) === v
      )
    );
  }
  /**
   * Get the URL query parameter value. May be a mix of full and humanized entity refs.
   * @returns list of entity refs.
   */
  toQueryValue() {
    return this.values;
  }
}
class EntityLifecycleFilter {
  constructor(values) {
    this.values = values;
  }
  getCatalogFilters() {
    return { "spec.lifecycle": this.values };
  }
  filterEntity(entity) {
    return this.values.some((v) => entity.spec?.lifecycle === v);
  }
  toQueryValue() {
    return this.values;
  }
}
class EntityNamespaceFilter {
  constructor(values) {
    this.values = values;
  }
  getCatalogFilters() {
    return { "metadata.namespace": this.values };
  }
  filterEntity(entity) {
    return this.values.some((v) => entity.metadata.namespace === v);
  }
  toQueryValue() {
    return this.values;
  }
}
class EntityUserFilter {
  constructor(value, refs) {
    this.value = value;
    this.refs = refs;
  }
  static owned(ownershipEntityRefs) {
    return new EntityUserFilter("owned", ownershipEntityRefs);
  }
  static all() {
    return new EntityUserFilter("all");
  }
  static starred(starredEntityRefs) {
    return new EntityUserFilter("starred", starredEntityRefs);
  }
  getCatalogFilters() {
    if (this.value === "owned") {
      return { "relations.ownedBy": this.refs ?? [] };
    }
    if (this.value === "starred") {
      return {
        "metadata.name": this.refs?.map((e) => parseEntityRef(e).name) ?? []
      };
    }
    return {};
  }
  filterEntity(entity) {
    if (this.value === "starred") {
      return this.refs?.includes(stringifyEntityRef(entity)) ?? true;
    }
    if (this.value === "owned") {
      const relations = getEntityRelations(entity, RELATION_OWNED_BY);
      return this.refs?.some(
        (v) => relations.some((o) => stringifyEntityRef(o) === v)
      ) ?? false;
    }
    return true;
  }
  toQueryValue() {
    return this.value;
  }
}
class UserListFilter {
  constructor(value, isOwnedEntity, isStarredEntity) {
    this.value = value;
    this.isOwnedEntity = isOwnedEntity;
    this.isStarredEntity = isStarredEntity;
  }
  filterEntity(entity) {
    switch (this.value) {
      case "owned":
        return this.isOwnedEntity(entity);
      case "starred":
        return this.isStarredEntity(entity);
      default:
        return true;
    }
  }
  toQueryValue() {
    return this.value;
  }
}
class EntityOrphanFilter {
  constructor(value) {
    this.value = value;
  }
  getCatalogFilters() {
    if (this.value) {
      return { "metadata.annotations.backstage.io/orphan": String(this.value) };
    }
    return {};
  }
  filterEntity(entity) {
    const orphan = entity.metadata.annotations?.["backstage.io/orphan"];
    return orphan !== void 0 && this.value.toString() === orphan;
  }
}
class EntityErrorFilter {
  constructor(value) {
    this.value = value;
  }
  filterEntity(entity) {
    const error = entity?.status?.items?.length > 0;
    return error !== void 0 && this.value === error;
  }
}
class EntityOrderFilter {
  constructor(values) {
    this.values = values;
  }
  getOrderFilters() {
    return this.values.map(([field, order]) => ({ field, order }));
  }
  toQueryValue() {
    return this.values.flat();
  }
}

export { EntityErrorFilter, EntityKindFilter, EntityLifecycleFilter, EntityNamespaceFilter, EntityOrderFilter, EntityOrphanFilter, EntityOwnerFilter, EntityTagFilter, EntityTextFilter, EntityTypeFilter, EntityUserFilter, UserListFilter };
//# sourceMappingURL=filters.esm.js.map
