import { normalizeQuery } from "./query.js";
import { APP_CONFIG } from "../../../app/config.js";
import { createPanelStateBridge } from "../../../stores/panelStateBridge.js";

const _safeSetValue = (el: any, value: any) => {
    if (!el) return;
    try {
        el.value = value;
    } catch (e) {
        console.debug?.(e);
    }
};

const _safeSetChecked = (el: any, checked: any) => {
    if (!el) return;
    try {
        el.checked = !!checked;
    } catch (e) {
        console.debug?.(e);
    }
};

export function createContextController({
    state,
    gridContainer,
    filterBtn,
    sortBtn,
    collectionsBtn,
    searchInputEl,
    kindSelect,
    wfCheckbox,
    workflowTypeSelect,
    workflowIdInput,
    workflowModelInput,
    workflowRunsOnSelect,
    ratingSelect,
    minSizeInput,
    maxSizeInput,
    minWidthInput,
    minHeightInput,
    maxWidthInput,
    maxHeightInput,
    resolutionPresetSelect,
    dateRangeSelect,
    dateExactInput,
    scopeController,
    sortController,
    updateSummaryBar,
    reloadGrid,
    extraActions = null,
    getExtraContext = null,
}: Record<string, any> = {}): Record<string, any> {
    const legacyState = state && typeof state === "object" ? state : {};
    const { read, write, controllerState } = createPanelStateBridge(state, [
        "searchQuery",
        "scope",
        "collectionId",
        "collectionName",
        "customRootId",
        "customRootLabel",
        "currentFolderRelativePath",
        "kindFilter",
        "workflowOnly",
        "minRating",
        "minSizeMB",
        "maxSizeMB",
        "minWidth",
        "minHeight",
        "maxWidth",
        "maxHeight",
        "resolutionCompare",
        "workflowType",
        "workflowId",
        "workflowModelFilter",
        "workflowRunsOnFilter",
        "dateRangeFilter",
        "dateExactFilter",
        "sort",
        "viewScope",
        "similarResults",
        "similarTitle",
        "similarSourceAssetId",
    ]);

    const setStateValue = (key: any, value: any) => {
        write(key, value);
    };

    const getStateValue = (key: string, fallback: any = "") => {
        return read(key, fallback);
    };

    const getContextState = () => ({
        ...(legacyState || {}),
        ...(controllerState?.() || {}),
        customRootLabel: getStateValue("customRootLabel", ""),
    });

    const resetBrowserHistory = () => {
        try {
            extraActions?.resetBrowserHistory?.();
        } catch (e) {
            console.debug?.(e);
        }
    };

    const applyBadgeCssVars = () => {
        try {
            const root =
                gridContainer?.closest?.(".mjr-assets-manager") ||
                document.querySelector?.(".mjr-assets-manager") ||
                document.documentElement;
            if (!root?.style?.setProperty) return;
            root.style.setProperty(
                "--mjr-star-active",
                String(APP_CONFIG.BADGE_STAR_COLOR || "#FFD45A"),
            );
            root.style.setProperty(
                "--mjr-badge-image",
                String(APP_CONFIG.BADGE_IMAGE_COLOR || "#2196F3"),
            );
            root.style.setProperty(
                "--mjr-badge-video",
                String(APP_CONFIG.BADGE_VIDEO_COLOR || "#9C27B0"),
            );
            root.style.setProperty(
                "--mjr-badge-audio",
                String(APP_CONFIG.BADGE_AUDIO_COLOR || "#FF9800"),
            );
            root.style.setProperty(
                "--mjr-badge-model3d",
                String(APP_CONFIG.BADGE_MODEL3D_COLOR || "#4CAF50"),
            );
            root.style.setProperty(
                "--mjr-badge-duplicate-alert",
                String(APP_CONFIG.BADGE_DUPLICATE_ALERT_COLOR || "#FF1744"),
            );
        } catch (e) {
            console.debug?.(e);
        }
    };

    const actions: Record<string, any> = {
        clearQuery: async () => {
            try {
                _safeSetValue(searchInputEl, "");
                setStateValue("searchQuery", "");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearCollection: async () => {
            try {
                setStateValue("collectionId", "");
                setStateValue("collectionName", "");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearScope: async () => {
            try {
                if (
                    String(state?.viewScope || "")
                        .trim()
                        .toLowerCase() === "similar" &&
                    typeof extraActions?.clearSimilarScope === "function"
                ) {
                    await extraActions.clearSimilarScope();
                    return;
                }
            } catch (e) {
                console.debug?.(e);
            }
            let didSetScope = false;
            try {
                setStateValue("customRootId", "");
                setStateValue("customRootLabel", "");
                setStateValue("currentFolderRelativePath", "");
                delete gridContainer?.dataset?.mjrSubfolder;
                resetBrowserHistory();
                if (typeof scopeController?.setScope === "function") {
                    await scopeController.setScope("output");
                    didSetScope = true;
                } else {
                    setStateValue("scope", "output");
                    scopeController?.setActiveTabStyles?.();
                }
            } catch (e) {
                console.debug?.(e);
            }
            try {
                if (!didSetScope) await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearCustomRoot: async () => {
            try {
                setStateValue("customRootId", "");
                setStateValue("customRootLabel", "");
                setStateValue("currentFolderRelativePath", "");
                delete gridContainer?.dataset?.mjrSubfolder;
                resetBrowserHistory();
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearFolder: async () => {
            try {
                // Ensure state is cleared so it doesn't get restored
                setStateValue("currentFolderRelativePath", "");
                delete gridContainer?.dataset?.mjrSubfolder;
                resetBrowserHistory();
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearKind: async () => {
            try {
                setStateValue("kindFilter", "");
                _safeSetValue(kindSelect, "");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearMinRating: async () => {
            try {
                setStateValue("minRating", 0);
                _safeSetValue(ratingSelect, "0");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearWorkflowOnly: async () => {
            try {
                setStateValue("workflowOnly", false);
                _safeSetChecked(wfCheckbox, false);
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearWorkflowType: async () => {
            try {
                setStateValue("workflowType", "");
                _safeSetValue(workflowTypeSelect, "");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearWorkflowId: async () => {
            try {
                setStateValue("workflowId", "");
                _safeSetValue(workflowIdInput, "");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearWorkflowModel: async () => {
            try {
                setStateValue("workflowModelFilter", "");
                _safeSetValue(workflowModelInput, "");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearWorkflowRunsOn: async () => {
            try {
                setStateValue("workflowRunsOnFilter", "");
                _safeSetValue(workflowRunsOnSelect, "");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearSize: async () => {
            try {
                setStateValue("minSizeMB", 0);
                setStateValue("maxSizeMB", 0);
                _safeSetValue(minSizeInput, "");
                _safeSetValue(maxSizeInput, "");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearResolution: async () => {
            try {
                setStateValue("minWidth", 0);
                setStateValue("minHeight", 0);
                setStateValue("maxWidth", 0);
                setStateValue("maxHeight", 0);
                _safeSetValue(minWidthInput, "");
                _safeSetValue(minHeightInput, "");
                _safeSetValue(maxWidthInput, "");
                _safeSetValue(maxHeightInput, "");
                _safeSetValue(resolutionPresetSelect, "");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearDateRange: async () => {
            try {
                setStateValue("dateRangeFilter", "");
                _safeSetValue(dateRangeSelect, "");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearDateExact: async () => {
            try {
                setStateValue("dateExactFilter", "");
                _safeSetValue(dateExactInput, "");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearSort: async () => {
            try {
                setStateValue("sort", "mtime_desc");
                sortController?.setSortIcon?.(getStateValue("sort", "mtime_desc"));
                sortController?.renderSortMenu?.();
            } catch (e) {
                console.debug?.(e);
            }
            try {
                await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
        clearAll: async () => {
            let didSetScope = false;
            try {
                _safeSetValue(searchInputEl, "");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                setStateValue("collectionId", "");
                setStateValue("collectionName", "");
                setStateValue("kindFilter", "");
                setStateValue("workflowOnly", false);
                setStateValue("minRating", 0);
                setStateValue("minSizeMB", 0);
                setStateValue("maxSizeMB", 0);
                setStateValue("minWidth", 0);
                setStateValue("minHeight", 0);
                setStateValue("maxWidth", 0);
                setStateValue("maxHeight", 0);
                setStateValue("resolutionCompare", "gte");
                setStateValue("workflowType", "");
                setStateValue("workflowId", "");
                setStateValue("workflowModelFilter", "");
                setStateValue("workflowRunsOnFilter", "");
                setStateValue("dateRangeFilter", "");
                setStateValue("dateExactFilter", "");
                setStateValue("sort", "mtime_desc");
                setStateValue("customRootId", "");
                setStateValue("customRootLabel", "");
                setStateValue("currentFolderRelativePath", "");
                delete gridContainer?.dataset?.mjrSubfolder;
                resetBrowserHistory();
                try {
                    await extraActions?.clearTransientContext?.();
                } catch (e) {
                    console.debug?.(e);
                }
                if (typeof scopeController?.setScope === "function") {
                    await scopeController.setScope("output");
                    didSetScope = true;
                } else {
                    setStateValue("scope", "output");
                    scopeController?.setActiveTabStyles?.();
                }
            } catch (e) {
                console.debug?.(e);
            }
            try {
                _safeSetValue(kindSelect, "");
                _safeSetChecked(wfCheckbox, false);
                _safeSetValue(workflowTypeSelect, "");
                _safeSetValue(workflowIdInput, "");
                _safeSetValue(workflowModelInput, "");
                _safeSetValue(workflowRunsOnSelect, "");
                _safeSetValue(ratingSelect, "0");
                _safeSetValue(minSizeInput, "");
                _safeSetValue(maxSizeInput, "");
                _safeSetValue(minWidthInput, "");
                _safeSetValue(minHeightInput, "");
                _safeSetValue(maxWidthInput, "");
                _safeSetValue(maxHeightInput, "");
                _safeSetValue(resolutionPresetSelect, "");
                _safeSetValue(dateRangeSelect, "");
                _safeSetValue(dateExactInput, "");
            } catch (e) {
                console.debug?.(e);
            }
            try {
                sortController?.setSortIcon?.(getStateValue("sort", "mtime_desc"));
                sortController?.renderSortMenu?.();
            } catch (e) {
                console.debug?.(e);
            }
            try {
                if (!didSetScope) await reloadGrid?.();
            } catch (e) {
                console.debug?.(e);
            }
        },
    };
    if (extraActions && typeof extraActions === "object") {
        const blocked = new Set(["__proto__", "constructor", "prototype"]);
        for (const [key, value] of Object.entries(extraActions)) {
            if (blocked.has(String(key))) continue;
            actions[key] = value;
        }
    }

    const update = () => {
        const rawQuery = String(searchInputEl?.value || "").trim();
        const normalizedQuery = normalizeQuery(searchInputEl);
        const currentState = getContextState();

        const filterActive = !!(
            getStateValue("kindFilter", "") ||
            "" ||
            getStateValue("workflowOnly", false) ||
            (Number(getStateValue("minRating", 0) || 0) || 0) > 0 ||
            (Number(getStateValue("minSizeMB", 0) || 0) || 0) > 0 ||
            (Number(getStateValue("maxSizeMB", 0) || 0) || 0) > 0 ||
            (Number(getStateValue("minWidth", 0) || 0) || 0) > 0 ||
            (Number(getStateValue("minHeight", 0) || 0) || 0) > 0 ||
            (Number(getStateValue("maxWidth", 0) || 0) || 0) > 0 ||
            (Number(getStateValue("maxHeight", 0) || 0) || 0) > 0 ||
            String(getStateValue("workflowType", "") || "").trim().length > 0 ||
            String(getStateValue("workflowId", "") || "").trim().length > 0 ||
            String(getStateValue("workflowModelFilter", "") || "").trim().length > 0 ||
            String(getStateValue("workflowRunsOnFilter", "") || "").trim().length > 0 ||
            getStateValue("dateRangeFilter", "") ||
            "" ||
            getStateValue("dateExactFilter", "") ||
            ""
        );
        const sortActive =
            String(getStateValue("sort", "mtime_desc") || "mtime_desc") !== "mtime_desc";
        const collectionsActive = !!(getStateValue("collectionId", "") || "");

        try {
            filterBtn?.classList?.toggle?.("mjr-context-active", filterActive);
            sortBtn?.classList?.toggle?.("mjr-context-active", sortActive);
            collectionsBtn?.classList?.toggle?.("mjr-context-active", collectionsActive);
        } catch (e) {
            console.debug?.(e);
        }

        try {
            const extraContext =
                (typeof getExtraContext === "function" ? getExtraContext() || {} : {}) || {};
            updateSummaryBar?.({
                state: currentState,
                gridContainer,
                context: { rawQuery: rawQuery || normalizedQuery, ...extraContext },
                actions,
            });
        } catch (e) {
            console.debug?.(e);
        }

        // Keep badge CSS vars aligned with live settings/theme changes.
        applyBadgeCssVars();
    };

    return { update, actions };
}
