import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { UserInfoEngine } from '@memberjunction/core-entities';
import * as i0 from "@angular/core";
// Setting key prefix to avoid collisions
const SETTING_PREFIX = '__ACTION_DASHBOARD__';
const DEFAULT_STATE = {
    treeWidth: 280,
    treeCollapsed: false,
    viewMode: 'card',
    sortConfig: { field: 'name', direction: 'asc' },
    expandedCategories: [],
    selectedCategoryId: 'all',
    filters: {
        searchTerm: '',
        statuses: [],
        types: [],
        approvalStatuses: [],
        hasExecutions: null
    }
};
const TREE_WIDTH_MIN = 180;
const TREE_WIDTH_MAX = 450;
const TREE_COLLAPSED_WIDTH = 0;
export class ActionExplorerStateService {
    // UI State subjects
    _treeWidth$ = new BehaviorSubject(DEFAULT_STATE.treeWidth);
    _treeCollapsed$ = new BehaviorSubject(DEFAULT_STATE.treeCollapsed);
    _viewMode$ = new BehaviorSubject(DEFAULT_STATE.viewMode);
    _sortConfig$ = new BehaviorSubject(DEFAULT_STATE.sortConfig);
    _expandedCategories$ = new BehaviorSubject(new Set(DEFAULT_STATE.expandedCategories));
    _selectedCategoryId$ = new BehaviorSubject(DEFAULT_STATE.selectedCategoryId);
    _filters$ = new BehaviorSubject(DEFAULT_STATE.filters);
    // Slide panel states
    _newCategoryPanelOpen$ = new BehaviorSubject(false);
    _newActionPanelOpen$ = new BehaviorSubject(false);
    // Persistence subjects (debounced)
    _persistState$ = new Subject();
    _destroy$ = new Subject();
    // Public observables
    TreeWidth$ = this._treeWidth$.asObservable();
    TreeCollapsed$ = this._treeCollapsed$.asObservable();
    ViewMode$ = this._viewMode$.asObservable();
    SortConfig$ = this._sortConfig$.asObservable();
    ExpandedCategories$ = this._expandedCategories$.asObservable();
    SelectedCategoryId$ = this._selectedCategoryId$.asObservable();
    Filters$ = this._filters$.asObservable();
    NewCategoryPanelOpen$ = this._newCategoryPanelOpen$.asObservable();
    NewActionPanelOpen$ = this._newActionPanelOpen$.asObservable();
    // Current values (synchronous access)
    get TreeWidth() { return this._treeWidth$.value; }
    get TreeCollapsed() { return this._treeCollapsed$.value; }
    get ViewMode() { return this._viewMode$.value; }
    get SortConfig() { return this._sortConfig$.value; }
    get ExpandedCategories() { return this._expandedCategories$.value; }
    get SelectedCategoryId() { return this._selectedCategoryId$.value; }
    get Filters() { return this._filters$.value; }
    // Constants
    TreeWidthMin = TREE_WIDTH_MIN;
    TreeWidthMax = TREE_WIDTH_MAX;
    TreeCollapsedWidth = TREE_COLLAPSED_WIDTH;
    constructor() {
        this.setupPersistence();
    }
    ngOnDestroy() {
        this._destroy$.next();
        this._destroy$.complete();
    }
    setupPersistence() {
        // Debounced persistence - save state 500ms after last change
        this._persistState$.pipe(debounceTime(500), takeUntil(this._destroy$)).subscribe(() => {
            this.saveState();
        });
    }
    /**
     * Load saved state from UserInfoEngine
     */
    async loadSavedState() {
        try {
            const savedState = UserInfoEngine.Instance.GetSetting(`${SETTING_PREFIX}action-explorer/state`);
            if (savedState) {
                const state = JSON.parse(savedState);
                if (state.treeWidth != null && state.treeWidth >= TREE_WIDTH_MIN && state.treeWidth <= TREE_WIDTH_MAX) {
                    this._treeWidth$.next(state.treeWidth);
                }
                if (state.treeCollapsed != null) {
                    this._treeCollapsed$.next(state.treeCollapsed);
                }
                if (state.viewMode != null) {
                    this._viewMode$.next(state.viewMode);
                }
                if (state.sortConfig != null) {
                    this._sortConfig$.next(state.sortConfig);
                }
                if (state.expandedCategories != null) {
                    this._expandedCategories$.next(new Set(state.expandedCategories));
                }
                // Note: selectedCategoryId is loaded from URL params, not saved state
                // Note: filters are loaded from URL params, not saved state
            }
        }
        catch (error) {
            console.warn('[ActionExplorerState] Failed to load saved state:', error);
        }
    }
    /**
     * Save current state to UserInfoEngine
     */
    async saveState() {
        try {
            const state = {
                treeWidth: this._treeWidth$.value,
                treeCollapsed: this._treeCollapsed$.value,
                viewMode: this._viewMode$.value,
                sortConfig: this._sortConfig$.value,
                expandedCategories: Array.from(this._expandedCategories$.value),
                selectedCategoryId: this._selectedCategoryId$.value,
                filters: this._filters$.value
            };
            await UserInfoEngine.Instance.SetSetting(`${SETTING_PREFIX}action-explorer/state`, JSON.stringify(state));
        }
        catch (error) {
            console.warn('[ActionExplorerState] Failed to save state:', error);
        }
    }
    queuePersist() {
        this._persistState$.next();
    }
    // Tree panel methods
    setTreeWidth(width) {
        const clampedWidth = Math.min(Math.max(width, TREE_WIDTH_MIN), TREE_WIDTH_MAX);
        if (clampedWidth !== this._treeWidth$.value) {
            this._treeWidth$.next(clampedWidth);
            this.queuePersist();
        }
    }
    setTreeCollapsed(collapsed) {
        if (collapsed !== this._treeCollapsed$.value) {
            this._treeCollapsed$.next(collapsed);
            this.queuePersist();
        }
    }
    toggleTreeCollapsed() {
        this.setTreeCollapsed(!this._treeCollapsed$.value);
    }
    // View mode methods
    setViewMode(mode) {
        if (mode !== this._viewMode$.value) {
            this._viewMode$.next(mode);
            this.queuePersist();
        }
    }
    // Sort methods
    setSortConfig(config) {
        if (config.field !== this._sortConfig$.value.field ||
            config.direction !== this._sortConfig$.value.direction) {
            this._sortConfig$.next(config);
            this.queuePersist();
        }
    }
    toggleSortDirection() {
        const current = this._sortConfig$.value;
        this.setSortConfig({
            field: current.field,
            direction: current.direction === 'asc' ? 'desc' : 'asc'
        });
    }
    setSortField(field) {
        const current = this._sortConfig$.value;
        if (field === current.field) {
            this.toggleSortDirection();
        }
        else {
            this.setSortConfig({ field, direction: 'asc' });
        }
    }
    // Category expansion methods
    toggleCategoryExpanded(categoryId) {
        const expanded = new Set(this._expandedCategories$.value);
        if (expanded.has(categoryId)) {
            expanded.delete(categoryId);
        }
        else {
            expanded.add(categoryId);
        }
        this._expandedCategories$.next(expanded);
        this.queuePersist();
    }
    setCategoryExpanded(categoryId, isExpanded) {
        const expanded = new Set(this._expandedCategories$.value);
        if (isExpanded) {
            expanded.add(categoryId);
        }
        else {
            expanded.delete(categoryId);
        }
        this._expandedCategories$.next(expanded);
        this.queuePersist();
    }
    expandPathToCategory(categoryId, categoryParentMap) {
        const expanded = new Set(this._expandedCategories$.value);
        let currentId = categoryParentMap.get(categoryId) || null;
        while (currentId) {
            expanded.add(currentId);
            currentId = categoryParentMap.get(currentId) || null;
        }
        this._expandedCategories$.next(expanded);
        this.queuePersist();
    }
    collapseAllCategories() {
        this._expandedCategories$.next(new Set());
        this.queuePersist();
    }
    expandAllCategories(categoryIds) {
        this._expandedCategories$.next(new Set(categoryIds));
        this.queuePersist();
    }
    // Selected category methods
    setSelectedCategoryId(categoryId) {
        if (categoryId !== this._selectedCategoryId$.value) {
            this._selectedCategoryId$.next(categoryId);
            // Don't persist - this comes from URL
        }
    }
    // Filter methods
    setFilters(filters) {
        this._filters$.next({ ...this._filters$.value, ...filters });
        // Don't persist filters - they come from URL
    }
    setSearchTerm(searchTerm) {
        if (searchTerm !== this._filters$.value.searchTerm) {
            this._filters$.next({ ...this._filters$.value, searchTerm });
        }
    }
    setStatusFilter(statuses) {
        this._filters$.next({ ...this._filters$.value, statuses });
    }
    setTypeFilter(types) {
        this._filters$.next({ ...this._filters$.value, types });
    }
    clearFilters() {
        this._filters$.next({
            searchTerm: '',
            statuses: [],
            types: [],
            approvalStatuses: [],
            hasExecutions: null
        });
    }
    hasActiveFilters() {
        const f = this._filters$.value;
        return f.searchTerm.length > 0 ||
            f.statuses.length > 0 ||
            f.types.length > 0 ||
            f.approvalStatuses.length > 0 ||
            f.hasExecutions != null;
    }
    // Panel methods
    openNewCategoryPanel() {
        this._newCategoryPanelOpen$.next(true);
    }
    closeNewCategoryPanel() {
        this._newCategoryPanelOpen$.next(false);
    }
    openNewActionPanel() {
        this._newActionPanelOpen$.next(true);
    }
    closeNewActionPanel() {
        this._newActionPanelOpen$.next(false);
    }
    /**
     * Build URL query params from current state for deep linking
     */
    buildQueryParams() {
        const params = {};
        if (this._selectedCategoryId$.value !== 'all') {
            params['category'] = this._selectedCategoryId$.value;
        }
        else {
            params['category'] = null;
        }
        if (this._viewMode$.value !== 'card') {
            params['view'] = this._viewMode$.value;
        }
        else {
            params['view'] = null;
        }
        const sort = this._sortConfig$.value;
        if (sort.field !== 'name' || sort.direction !== 'asc') {
            params['sort'] = `${sort.field}_${sort.direction}`;
        }
        else {
            params['sort'] = null;
        }
        const f = this._filters$.value;
        if (f.searchTerm) {
            params['q'] = f.searchTerm;
        }
        else {
            params['q'] = null;
        }
        if (f.statuses.length > 0) {
            params['status'] = f.statuses.join(',');
        }
        else {
            params['status'] = null;
        }
        if (f.types.length > 0) {
            params['type'] = f.types.join(',');
        }
        else {
            params['type'] = null;
        }
        return params;
    }
    /**
     * Parse URL query params and update state
     */
    parseQueryParams(params) {
        const category = params.get('category');
        if (category) {
            this._selectedCategoryId$.next(category);
        }
        const view = params.get('view');
        if (view && ['card', 'list', 'compact'].includes(view)) {
            this._viewMode$.next(view);
        }
        const sort = params.get('sort');
        if (sort) {
            const [field, direction] = sort.split('_');
            if (field && direction) {
                this._sortConfig$.next({ field, direction });
            }
        }
        const searchTerm = params.get('q') || '';
        const statuses = params.get('status')?.split(',').filter(s => s) || [];
        const types = params.get('type')?.split(',').filter(t => t) || [];
        this._filters$.next({
            ...this._filters$.value,
            searchTerm,
            statuses,
            types
        });
    }
    static ɵfac = function ActionExplorerStateService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ActionExplorerStateService)(); };
    static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: ActionExplorerStateService, factory: ActionExplorerStateService.ɵfac });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ActionExplorerStateService, [{
        type: Injectable
    }], () => [], null); })();
//# sourceMappingURL=action-explorer-state.service.js.map