import { useCallback, useEffect, useState } from "react";

import { CONTROL_VISIBILITY_CHANGED_EVENT } from "../events/visibilityChanged.js";
import { getSidebarCustomize } from "../sidebar/getSidebarCustomize.js";

import type { ControlVisibilityChangedEvent } from "../events/visibilityChanged.js";

type UseCustomizeValue = { value: any; visible: boolean };

function useCustomizeValues<T = Record<string, UseCustomizeValue>>(settings: string[]) {
    const customize = getSidebarCustomize();
    const getValue = useCallback(
        (setting): UseCustomizeValue => {
            const s = customize(setting);
            return {
                value: s.get(),
                visible: s.findControls()[0].active(),
            };
        },
        [customize],
    );

    const [values, setValues] = useState<T>(() =>
        settings.reduce((p, c) => {
            p[c] = getValue(c);
            return p;
        }, {} as T),
    );

    // Listen to changes
    useEffect(() => {
        for (const setting of settings) {
            customize(setting, (value: any) =>
                value.bind("change", () => {
                    setValues((state) => ({ ...state, [setting]: getValue(setting) }));
                }),
            );
        }

        // Listen to visibility changes
        const listener = async ({ detail: { setting } }: CustomEvent<ControlVisibilityChangedEvent>) => {
            if (Object.values(settings).indexOf(setting) > -1) {
                setValues((state) => ({ ...state, [setting]: getValue(setting) }));
            }
        };

        document.addEventListener(CONTROL_VISIBILITY_CHANGED_EVENT, listener as any);
        return () => {
            document.removeEventListener(CONTROL_VISIBILITY_CHANGED_EVENT, listener as any);
        };
    }, []);

    return values;
}

export { useCustomizeValues, type UseCustomizeValue };
