import { ChangeDetectorRef, OnDestroy, ElementRef } from '@angular/core';
import { BaseResourceComponent } from '@memberjunction/ng-shared';
import { ResourceData, MJListCategoryEntity } from '@memberjunction/core-entities';
import { MJListEntity } from '@memberjunction/core-entities';
import { Subject } from 'rxjs';
import { TabService } from '@memberjunction/ng-base-application';
import { MJNotificationService } from '@memberjunction/ng-notifications';
import { ListSharingService, ListSharingSummary, ListShareDialogConfig, ListShareDialogResult } from '@memberjunction/ng-list-management';
import { type ListCapabilities } from '@memberjunction/lists-base';
import { FilterFieldConfig } from '@memberjunction/ng-ui-components';
import * as i0 from "@angular/core";
interface BrowseListItem {
    list: MJListEntity;
    itemCount: number;
    entityName: string;
    ownerName: string;
    isOwner: boolean;
    sharingInfo?: ListSharingSummary;
}
interface CategoryNode {
    category: MJListCategoryEntity | null;
    lists: BrowseListItem[];
    children: CategoryNode[];
    isExpanded: boolean;
}
type ViewMode = 'table' | 'card' | 'hierarchy';
export declare class ListsBrowseResource extends BaseResourceComponent implements OnDestroy {
    private cdr;
    private tabService;
    private notificationService;
    private elementRef;
    private listSharingService;
    protected destroy$: Subject<void>;
    isLoading: boolean;
    searchTerm: string;
    viewMode: ViewMode;
    selectedEntity: string;
    selectedOwner: string;
    selectedSort: string;
    /**
     * Active tag filters (Phase 4.3). Multi-tag = AND — a list must have
     * every active tag to appear. URL state mirrors this via the `tags`
     * query param (comma-separated tag IDs).
     */
    tagFilters: Array<{
        TagID: string;
        Name: string;
    }>;
    /**
     * Set of List IDs that match the current `tagFilters` (intersection).
     * `null` means "no tag filter active" — pass-through. Populated by
     * `recomputeTagMembership` whenever `tagFilters` changes; consumed by
     * `applyFilters` to narrow the visible list.
     */
    private tagFilteredListIds;
    /**
     * Favorite-list IDs for the current user (Phase 5.3). Backed by the
     * existing `MJ: User Favorites` entity. `null` while loading; a Set
     * once populated so card-side toggling is O(1).
     */
    favoriteListIds: Set<string>;
    /** When true, only favorited lists appear in the grid. */
    showOnlyFavorites: boolean;
    allLists: BrowseListItem[];
    filteredLists: BrowseListItem[];
    categories: MJListCategoryEntity[];
    categoryTree: CategoryNode[];
    flatCategories: Array<{
        ID: string;
        displayName: string;
    }>;
    availableEntities: Array<{
        ID: string;
        Name: string;
    }>;
    filteredEntitiesList: Array<{
        ID: string;
        Name: string;
    }>;
    entityOptions: Array<{
        name: string;
        value: string;
    }>;
    ownerOptions: Array<{
        name: string;
        value: string;
    }>;
    sortOptions: Array<{
        name: string;
        value: string;
    }>;
    showContextMenu: boolean;
    contextMenuX: number;
    contextMenuY: number;
    selectedContextItem: BrowseListItem | null;
    showCreateDialog: boolean;
    editingList: MJListEntity | null;
    newListName: string;
    newListDescription: string;
    selectedEntityId: string;
    selectedCategoryId: string | null;
    entitySearchTerm: string;
    showEntityDropdown: boolean;
    entityDropdownPosition: {
        top: number;
        left: number;
        width: number;
        openAbove: boolean;
    };
    showDeleteConfirm: boolean;
    deleteListName: string;
    listToDelete: MJListEntity | null;
    isSaving: boolean;
    isDeleting: boolean;
    showShareDialog: boolean;
    shareDialogConfig: ListShareDialogConfig | null;
    contextItemCapabilities: ListCapabilities;
    private capabilityCache;
    private categoriesDirty;
    showInvitationsDialog: boolean;
    showAuditLogDialog: boolean;
    activeShareListId: string | null;
    activeShareListName: string | null;
    private entityColorMap;
    private entityIconMap;
    private categoryMap;
    private currentUserId;
    constructor(cdr: ChangeDetectorRef, tabService: TabService, notificationService: MJNotificationService, elementRef: ElementRef, listSharingService: ListSharingService);
    onDocumentClick(event: MouseEvent): void;
    onEscapeKey(): void;
    ngOnInit(): Promise<void>;
    /**
     * Report the Browse surface's salient state to the AI agent. Re-called
     * on every meaningful state change (search / filter / view / sort /
     * data load) so the chat agent and realtime co-agent stay in sync with
     * what the user is looking at.
     */
    private publishAgentContext;
    /**
     * Resolve an agent-supplied reference (a list ID or a list NAME, exact or
     * partial) to one of the loaded Browse list items. Delegates the matching to
     * the pure {@link resolveNamedRecord} helper over the filtered lists' rows.
     */
    private resolveBrowseListItem;
    /**
     * Register the Browse surface's agent-actionable tools. SAFE tools are
     * navigation / search / filter / selection; the single bounded-mutation
     * tool (CreateList) only opens the dialog-validated create flow.
     */
    private registerAgentTools;
    /**
     * Mark the in-memory categories list dirty whenever any BaseEntity
     * raises a save / delete event for `MJ: List Categories`. The
     * Create/Edit dialog uses this flag to skip the per-open RunView
     * unless something has actually changed since last load — keeps the
     * dialog snappy without showing stale categories.
     *
     * Subscribes to MJGlobal's event bus rather than wiring each
     * category entity's per-instance listener, because the Categories
     * tab creates fresh BaseEntity instances we can't see from here.
     */
    private subscribeToCategoryChanges;
    ngOnDestroy(): void;
    loadData(): Promise<void>;
    private buildFlatCategories;
    private buildCategoryTree;
    setViewMode(mode: ViewMode): void;
    /** View-mode options for the shared <mj-view-toggle>. */
    readonly listViewOptions: {
        key: string;
        icon: string;
        title: string;
    }[];
    /** Values record consumed by the centralized <mj-filter-panel>. */
    get listFilterValues(): Record<string, unknown>;
    /** Field config consumed by the centralized <mj-filter-panel>. */
    get listFilterFields(): FilterFieldConfig[];
    /** Receive popover updates and apply them. */
    onFilterValuesChange(values: Record<string, unknown>): void;
    /** Reset the popover's own fields (Owner · Entity · Favorites); leaves search + tags alone. */
    resetPopoverFilters(): void;
    /** Active popover-field count for the badge (Owner + Entity; excludes search). */
    get ActiveFilterCount(): number;
    /** Total active filters (Owner + Entity + Favorites + Tags) — drives the Filter button badge. */
    get TotalActiveFilterCount(): number;
    /** Clear every filter (Owner · Entity · Favorites · Tags). Leaves search. */
    clearAllAppliedFilters(): void;
    onSearchChange(term: string): void;
    onEntityFilterChange(_value: string): void;
    onOwnerFilterChange(_value: string): void;
    onSortChange(_value: string): void;
    clearSearch(): void;
    clearFilters(): void;
    private applyFilters;
    toggleCategory(node: CategoryNode): void;
    getListCountInCategory(node: CategoryNode): number;
    getEntityColor(entityName: string): string;
    getEntityIcon(entityName: string): string;
    private generateEntityColor;
    formatDate(date: Date): string;
    openList(item: BrowseListItem): void;
    /**
     * Handle a tag chip click on a list card — adds the tag to the
     * filter row (multi-tag = AND). Wired by Phase 4.3; the chip
     * component emits the (TagID, Name) pair so we can both display
     * the chip name and filter by ID.
     */
    onCardTagClicked(payload: {
        TagID: string;
        Name: string;
    }): void;
    /** Remove a tag from the filter row. */
    removeTagFilter(tagId: string): void;
    /** Clear all active tag filters. */
    clearTagFilters(): void;
    /**
     * Resolve which lists have ALL active tags. Done server-side so the
     * filter works regardless of which lists the user has scrolled past.
     * Result is cached on `tagFilteredListIds`; `applyFilters` consumes it.
     */
    private recomputeTagMembership;
    /**
     * Load the current user's favorite lists into `favoriteListIds`.
     * Cheap — typically <100 rows per user. Driven by the `MJ: User
     * Favorites` entity scoped by the Lists EntityID. Best-effort: on
     * failure the star icons just stay dim.
     */
    private loadFavorites;
    /**
     * Toggle a list's favorite state. Optimistic: flips the local Set
     * first, then writes through. Reverts on failure.
     */
    toggleFavorite(event: Event, item: BrowseListItem): Promise<void>;
    isFavorite(listId: string): boolean;
    toggleShowOnlyFavorites(): void;
    openListMenu(event: Event, item: BrowseListItem): void;
    /** Resolve the current user's permission level for a list and update
     *  the open context menu in place. Cached so re-opening the same menu
     *  doesn't re-hit the resolver. */
    private refineContextCapabilities;
    closeContextMenu(): void;
    createNewList(): void;
    editList(): void;
    /** Re-pull MJ: List Categories so the dropdown reflects any
     *  newly-created categories. Skips the round trip when nothing has
     *  changed since the last load — `categoriesDirty` is flipped on
     *  by the BaseEntity event subscription whenever a category row
     *  is saved/deleted, so the only times this actually fetches are
     *  (a) the first dialog open, and (b) after the user touched a
     *  category somewhere else. */
    private refreshCategoriesForDialog;
    selectEntity(entity: {
        ID: string;
        Name: string;
    }): void;
    filterEntities(term: string): void;
    openEntityDropdown(inputElement: HTMLInputElement): void;
    closeEntityDropdown(): void;
    duplicateList(): Promise<void>;
    confirmDeleteList(): void;
    cancelDelete(): void;
    deleteList(): Promise<void>;
    /** Delete every MJ: List Details row for a given list in a single
     *  transaction group. Returns true if everything succeeded (including
     *  the trivial "no members" case). */
    private cascadeDeleteListMembers;
    closeCreateDialog(): void;
    saveList(): Promise<void>;
    openShareDialog(): void;
    onShareComplete(_result: ListShareDialogResult): void;
    onShareCancel(): void;
    /** "Manage Invitations" clicked inside the share dialog — opens a
     *  modal hosting `<mj-list-invitations>` for the same list. The
     *  share dialog is closed so dialogs don't visually stack. */
    onManageInvitations(): void;
    closeInvitationsDialog(): void;
    /** "View audit log" link in share dialog. */
    onViewAuditLog(): void;
    closeAuditLogDialog(): void;
    private loadSharingInfo;
    GetResourceDisplayName(_data: ResourceData): Promise<string>;
    GetResourceIconClass(_data: ResourceData): Promise<string>;
    static ɵfac: i0.ɵɵFactoryDeclaration<ListsBrowseResource, never>;
    static ɵcmp: i0.ɵɵComponentDeclaration<ListsBrowseResource, "mj-lists-browse-resource", never, {}, {}, never, never, false, never>;
}
export {};
//# sourceMappingURL=lists-browse-resource.component.d.ts.map