import { OnInit, OnDestroy, ChangeDetectorRef, EventEmitter, OnChanges, SimpleChanges, ElementRef, NgZone } from '@angular/core';
import { Subject } from 'rxjs';
import { BaseDashboard } from '@memberjunction/ng-shared';
import { RecentAccessService } from '@memberjunction/ng-shared-generic';
import { EntityInfo } from '@memberjunction/core';
import { ResourceData } from '@memberjunction/core-entities';
import { RecordSelectedEvent, RecordOpenedEvent, DataLoadedEvent, FilteredCountChangedEvent, EntityViewerConfig, NavigateToRelatedEvent, ViewWorkspaceComponent, ViewRelatedRecordNavigation } from '@memberjunction/ng-entity-viewer';
import { MJUserViewEntityExtended } from '@memberjunction/core-entities';
import { ExplorerStateService } from './services/explorer-state.service';
import { DataExplorerState, DataExplorerFilter, BreadcrumbItem, DataExplorerDeepLink, RecentRecordAccess, FavoriteRecord, AppEntityGroup } from './models/explorer-state.interface';
import { OpenRecordEvent, SelectRecordEvent } from './components/navigation-panel/navigation-panel.component';
import * as i0 from "@angular/core";
/**
 * Data Explorer Dashboard - Power user interface for exploring data across entities
 * Combines card-based browsing with grid views and relationship visualization
 *
 * Uses mj-entity-viewer composite component for the main content area,
 * which handles data loading, filtering, and view mode switching.
 */
export declare class DataExplorerDashboardComponent extends BaseDashboard implements OnInit, OnDestroy, OnChanges {
    stateService: ExplorerStateService;
    private cdr;
    private recentAccessService;
    private ngZone;
    protected destroy$: Subject<void>;
    private metadata;
    /** Reference to the filter input for keyboard shortcuts */
    filterInputRef: ElementRef<HTMLInputElement> | undefined;
    /** Reference to the view workspace (owns view CRUD + the inner data renderer) */
    viewWorkspaceRef: ViewWorkspaceComponent | undefined;
    /**
     * Optional filter to constrain which entities are shown in the explorer.
     * Can filter by applicationId, schemaNames, or explicit entityNames.
     */
    entityFilter: DataExplorerFilter | null;
    /**
     * Optional deep link to navigate to a specific entity/record on load.
     * Parsed from URL query parameters (e.g., ?entity=Users&record=123)
     */
    deepLink: DataExplorerDeepLink | null;
    /**
     * Optional context name to display in the header instead of "Data Explorer".
     * Use this to customize the explorer for specific applications (e.g., "CRM", "Association Demo").
     */
    contextName: string | null;
    /**
     * Optional context icon (Font Awesome class) to display in the header.
     * Use this alongside contextName for a fully customized header (e.g., "fa-solid fa-users" for CRM).
     */
    contextIcon: string | null;
    /**
     * Initial query params forwarded from the resource wrapper.
     * On hard refresh, the shell delivers params to the wrapper (which has Data.Configuration.queryParams),
     * not to this inner dashboard component. This input bridges that gap.
     */
    initialQueryParams: Record<string, string>;
    /**
     * Emitted when the display title should change (entity selected, record opened, etc.)
     */
    DisplayNameChanged: EventEmitter<string>;
    state: DataExplorerState;
    private allEntities;
    entities: EntityInfo[];
    appEntityGroups: AppEntityGroup[];
    private applicationEntityIds;
    selectedEntity: EntityInfo | null;
    totalRecordCount: number;
    filteredRecordCount: number;
    selectedRecord: Record<string, unknown> | null;
    detailPanelEntity: EntityInfo | null;
    private loadedRecords;
    selectedViewEntity: MJUserViewEntityExtended | null;
    liveFilterText: string;
    debouncedFilterText: string;
    private filterInput$;
    entityFilterText: string;
    breadcrumbs: BreadcrumbItem[];
    isLoadingEntities: boolean;
    recentRecords: RecentRecordAccess[];
    favoriteRecords: FavoriteRecord[];
    isLoadingRecentRecords: boolean;
    recentRecordsEntityFilter: string | null;
    GetResourceDisplayName(data: ResourceData): Promise<string>;
    /**
     * Get app entity groups filtered by current entityFilterText and homeViewMode.
     * When searching, auto-expands groups that contain matches.
     */
    get filteredAppEntityGroups(): AppEntityGroup[];
    /**
     * Filter a single group's entities by text and favorites mode.
     * Returns a new group with filtered entities and auto-expansion when searching.
     */
    private filterGroupEntities;
    /**
     * Get a flat filtered entity list for single-application mode.
     * Used when entityFilter.applicationId is set, bypassing app grouping.
     */
    get flatFilteredEntities(): EntityInfo[];
    /**
     * Total count of entities matching current filters (across all groups or flat list)
     */
    get filteredEntityCount(): number;
    /**
     * Count of applications that have at least one visible entity
     */
    get applicationCount(): number;
    /**
     * Get recent entities for home screen display (max 5)
     */
    get recentEntities(): EntityInfo[];
    /**
     * Get favorite entities for home screen display
     */
    get favoriteEntities(): EntityInfo[];
    /**
     * Recent records limited to 3 for the quick access panel
     */
    get quickAccessRecentRecords(): RecentRecordAccess[];
    /**
     * Recent entities limited to 3 for the quick access panel
     */
    get quickAccessRecentEntities(): EntityInfo[];
    /**
     * Favorite records limited to 3 for the quick access panel
     */
    get quickAccessFavoriteRecords(): FavoriteRecord[];
    /**
     * Check if a quick access section is expanded
     */
    isQuickAccessSectionExpanded(sectionId: string): boolean;
    /**
     * Get unique entities from recent records for the filter strip.
     * Returns up to 5 entities, sorted by frequency in the recent records.
     */
    get uniqueRecentRecordEntities(): {
        entityId: string;
        entityName: string;
        icon: string;
        count: number;
    }[];
    /**
     * Check if we should show the entity filter strip for recent records.
     * Only show when there are 2+ unique entities.
     */
    get showRecentRecordsEntityFilter(): boolean;
    /**
     * Get filtered recent records based on entity filter.
     */
    get filteredRecentRecords(): RecentRecordAccess[];
    /**
     * Set the entity filter for recent records
     */
    setRecentRecordsEntityFilter(entityId: string | null): void;
    /**
     * Get the display title for the header.
     * Priority: contextName > entityFilter.applicationName > "Data Explorer"
     */
    get displayTitle(): string;
    /**
     * Get the display icon for the header (when at home level).
     * Returns contextIcon if provided, otherwise null.
     */
    get displayIcon(): string | null;
    /**
     * Configuration for mj-entity-viewer composite component
     * Hides the built-in header since we have a custom header in the dashboard
     * Uses server-side pagination with 100 records per page (default)
     */
    viewerConfig: Partial<EntityViewerConfig>;
    constructor(stateService: ExplorerStateService, cdr: ChangeDetectorRef, recentAccessService: RecentAccessService, ngZone: NgZone);
    ngOnInit(): Promise<void>;
    /**
     * Handle keyboard shortcuts
     * "/" or Cmd+K focuses the filter input
     */
    handleKeyboardShortcut(event: KeyboardEvent): void;
    /**
     * Focus the filter input
     */
    private focusFilterInput;
    ngOnDestroy(): void;
    ngOnChanges(changes: SimpleChanges): Promise<void>;
    protected initDashboard(): void;
    protected loadData(): void;
    /**
     * Load all available entities the user can access, applying any configured filter
     * @param urlState Optional URL state - if provided, skip restoring persisted entity to avoid race conditions
     */
    private loadEntities;
    /**
     * Load entity IDs associated with a specific application
     */
    private loadApplicationEntityIds;
    /**
     * Apply the configured filter to the entity list
     */
    private applyEntityFilter;
    /**
     * Handle entity selection from navigation panel or home screen
     */
    onEntitySelected(entity: EntityInfo): void;
    /**
     * Handle state changes from external sources
     */
    private onStateChanged;
    /**
     * Reset viewMode to 'grid' if the current mode isn't supported by the given entity
     * (e.g., switching to an entity without geocoding while viewMode is 'map').
     */
    private reconcileViewModeForEntity;
    /**
     * Reset record counts when entity changes.
     * The actual counts will be updated when mj-entity-viewer emits dataLoaded event.
     */
    private resetRecordCounts;
    /**
     * Handle a view selection emitted by the workspace. Tracks the selected view for routing/export
     * and syncs the selected-view-id + smart-filter into the Explorer state service for URL sync.
     * Grid-state application is owned by the workspace.
     */
    onWorkspaceViewSelected(view: MJUserViewEntityExtended | null): void;
    /**
     * Handle the workspace's "open view in tab" request — route via NavigationService.
     */
    onOpenInTabRequested(viewId: string): void;
    /**
     * Handle the workspace's "create new record" request — route via NavigationService.
     */
    onCreateNewRecordRequested(entity: EntityInfo): void;
    /**
     * Clear the Explorer "view modified" flag after the workspace persists/reverts a view.
     */
    onWorkspaceViewSaved(): void;
    /**
     * Handle smart filter change from dashboard header
     */
    onSmartFilterChanged(prompt: string): void;
    /**
     * Handle direct keyboard input in the filter text box.
     * Only updates the live display text and pushes to the debounce subject.
     * Does NOT trigger state changes or URL updates — those happen after the debounce.
     */
    onFilterInputChanged(filterText: string): void;
    /**
     * Clear the record filter (called by the X button).
     */
    clearRecordFilter(): void;
    /**
     * Handle filter text change from mj-entity-viewer (two-way binding)
     */
    onFilterTextChanged(filterText: string): void;
    /**
     * Handle record selection from mj-entity-viewer
     */
    onViewerRecordSelected(event: RecordSelectedEvent): void;
    /**
     * Handle record opened from mj-entity-viewer (double-click or open button)
     */
    onViewerRecordOpened(event: RecordOpenedEvent): void;
    /**
     * Handle the workspace's OpenRecordRequested (record open from the inner viewer). Builds the
     * composite key from the record and routes to the full record view via the OpenEntityRecord output.
     */
    onWorkspaceOpenRecord(event: {
        entity: EntityInfo;
        record: Record<string, unknown>;
    }): void;
    /**
     * Handle data loaded from mj-entity-viewer
     */
    onDataLoaded(event: DataLoadedEvent): void;
    /**
     * Handle filtered count change from mj-entity-viewer
     */
    onFilteredCountChanged(event: FilteredCountChangedEvent): void;
    /**
     * Handle detail panel close
     */
    onDetailPanelClosed(): void;
    /**
     * Handle opening a record in full view (from detail panel)
     * Uses detailPanelEntity since the panel may be showing a different entity than the grid
     */
    onOpenRecord(record: Record<string, unknown>): void;
    /**
     * Handle creating a new record for the current entity
     */
    onCreateNewRecord(): void;
    /**
     * Show a notification to the user
     */
    private showNotification;
    /**
     * Handle navigation to a related entity from detail panel.
     * Navigates within the explorer and applies filter to show related records.
     */
    onNavigateToRelated(event: NavigateToRelatedEvent): void;
    /**
     * Handle opening a related record - display in detail panel (not new tab)
     * The record is already loaded, so just update the detail panel
     */
    onOpenRelatedRecord(event: {
        entityName: string;
        record: Record<string, unknown>;
    }): void;
    /**
     * Handle opening a foreign key record (from FK field link in detail panel)
     * Loads the record and displays it in the detail panel
     */
    onOpenForeignKeyRecord(event: {
        entityName: string;
        recordId: string;
    }): Promise<void>;
    /**
     * Show an already-loaded record in the detail panel
     * Note: This does NOT change selectedEntity (the main grid's entity)
     * It only updates detailPanelEntity which is used by the detail panel
     */
    private showRecordInDetailPanel;
    /**
     * Load a record by ID and show it in the detail panel
     */
    private loadAndShowRecordInDetailPanel;
    /**
     * Handle opening a record from navigation panel (recent/favorites)
     */
    onOpenRecordFromNav(event: OpenRecordEvent): void;
    /**
     * Handle selecting a record from navigation panel (recent/favorites).
     * Navigates to the entity within Data Explorer and selects the record
     * in the detail panel (instead of opening full record view).
     */
    onSelectRecordFromNav(event: SelectRecordEvent): void;
    /**
     * Toggle navigation panel
     */
    toggleNavigationPanel(): void;
    /**
     * Handle expand and focus from collapsed nav icon click
     */
    onExpandAndFocus(section: 'favorites' | 'recent' | 'entities'): void;
    /**
     * Apply a deep link to navigate to a specific entity/record
     */
    private applyDeepLink;
    /** Record ID to select once data loads (from deep link) */
    private pendingRecordSelection;
    /**
     * Handle breadcrumb click - navigate to that level
     */
    onBreadcrumbClick(breadcrumb: BreadcrumbItem, index: number): void;
    /**
     * Get the set of allowed entity names for filtering favorites/recents.
     * Returns null if no filter is active (all entities allowed).
     */
    get allowedEntityNames(): Set<string> | null;
    /**
     * Get display name for a record
     */
    private getRecordDisplayName;
    /**
     * Get the icon class for an entity
     */
    getEntityIcon(entity: EntityInfo): string;
    /**
     * Format entity icon to ensure proper Font Awesome class format
     */
    private formatEntityIcon;
    /**
     * Build a DataExplorerDeepLink from framework query params.
     * Returns null if no relevant params found.
     */
    private buildDeepLinkFromParams;
    /**
     * React to back/forward navigation or deep-link entry.
     * The base class calls this when query params change via popstate or deeplink.
     */
    protected OnQueryParamsChanged(params: Record<string, string>, _source: 'popstate' | 'deeplink'): void;
    /**
     * Public entry point for the resource wrapper to forward query param changes.
     * The wrapper receives OnQueryParamsChanged from the framework and delegates here.
     */
    HandleQueryParamsChanged(params: Record<string, string>, _source: 'popstate' | 'deeplink'): void;
    /**
     * Apply a params map (from framework query params) to the component state.
     */
    private applyParams;
    /**
     * Push current navigation state to the URL via the framework.
     * Called whenever state changes so users can bookmark/share URLs.
     */
    private pushCurrentStateToUrl;
    /**
     * Apply URL state to the component.
     * Used both during init and for popstate handling.
     */
    private applyUrlState;
    /**
     * Restore a saved view from the URL's viewId parameter.
     * Looks up the view by ID and sets it as selected; the workspace applies its grid state once
     * selectedViewEntity flows into its [SelectedView] input. Must be async because UserViewEngine's
     * cache may not be populated yet on cold page loads.
     */
    private restoreViewFromUrl;
    /**
     * Emit the current display name based on selected entity/record.
     */
    private emitDisplayName;
    /**
     * Toggle entity favorite status
     */
    toggleEntityFavorite(entity: EntityInfo, event: Event): Promise<void>;
    /**
     * Check if entity is favorited (for template)
     */
    isEntityFavorited(entity: EntityInfo): boolean;
    /**
     * Toggle show all entities vs common entities
     */
    toggleShowAllEntities(): void;
    /**
     * Toggle an application group's expanded/collapsed state
     */
    toggleAppGroup(groupId: string): void;
    /**
     * Set the home view mode (all vs favorites)
     */
    setHomeViewMode(mode: 'all' | 'favorites'): void;
    /**
     * Toggle the quick access (right) panel
     */
    toggleQuickAccessPanel(): void;
    /**
     * Toggle a section in the quick access panel
     */
    toggleQuickAccessSection(sectionId: string): void;
    /**
     * Build application entity groups from metadata.
     * Groups entities by their first application membership.
     * Entities not in any application go into "System & Other".
     */
    private buildAppEntityGroups;
    /**
     * Add an entity to its application group in the map, creating the group if needed
     */
    private addEntityToGroup;
    /**
     * Handle clicking on a recent record from home screen.
     * Navigates to the entity and sets up pending selection to select the record
     * and open the detail panel once data loads.
     */
    onRecentRecordClick(record: RecentRecordAccess): void;
    /**
     * Handle clicking on a favorite record from home screen.
     * Navigates to the entity and sets up pending selection to select the record
     * and open the detail panel once data loads.
     */
    onFavoriteRecordClick(record: FavoriteRecord): void;
    /**
     * Get the icon for an entity by ID (for recent records)
     */
    getEntityIconById(entityId: string): string;
    private relativeTimeCache;
    /**
     * Format relative time for display (e.g., "2 hours ago")
     * Cached to prevent ExpressionChangedAfterItHasBeenCheckedError
     */
    formatRelativeTime(date: Date): string;
    /**
     * Check if we're at the home level (no entity selected)
     */
    get isAtHomeLevel(): boolean;
    /**
     * NAVIGATION handler: open a *related* record on a (possibly different) entity, bubbled up from a
     * plug-in renderer through the workspace (e.g. a grid foreign-key drill-through). Resolves the
     * target entity and shows the record in the detail panel, mirroring the FK navigation path used
     * by {@link onOpenForeignKeyRecord}.
     *
     * @param nav the related-record navigation payload: the target entity name and the record's key.
     */
    onOpenRelatedRecordRequested(nav: ViewRelatedRecordNavigation): void;
    static ɵfac: i0.ɵɵFactoryDeclaration<DataExplorerDashboardComponent, never>;
    static ɵcmp: i0.ɵɵComponentDeclaration<DataExplorerDashboardComponent, "mj-data-explorer-dashboard", never, { "entityFilter": { "alias": "entityFilter"; "required": false; }; "deepLink": { "alias": "deepLink"; "required": false; }; "contextName": { "alias": "contextName"; "required": false; }; "contextIcon": { "alias": "contextIcon"; "required": false; }; "initialQueryParams": { "alias": "initialQueryParams"; "required": false; }; }, { "DisplayNameChanged": "DisplayNameChanged"; }, never, never, false, never>;
}
//# sourceMappingURL=data-explorer-dashboard.component.d.ts.map