import { useEffect } from "react";

import { SETTING_ACCESSIBILITY_CHANGED_EVENT } from "../events/accessibilityChanged.js";
import { CONTROL_VISIBILITY_CHANGED_EVENT } from "../events/visibilityChanged.js";
import { calculateControlBreadcrumb } from "../sidebar/calculateControlBreadcrumb.js";
import { CONDITIONAL_HIDDEN_CLASS_NAME } from "../sidebar/conditionalControls.js";
import { getSidebarCustomize } from "../sidebar/getSidebarCustomize.js";

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

/**
 * Dispatch a `SettingAccessibilityChangedEvent` when an accessibility value changes with
 * all relevant information. This is useful to calculate an accessibility-score.
 */
function useA11yDispatcher({ setting, valid }: Pick<SettingAccessibilityChangedEvent, "setting" | "valid">) {
    useEffect(() => {
        const customize = getSidebarCustomize();
        const dispatch = () =>
            customize.control(setting, async (instance: { container: JQuery<HTMLLIElement> }) => {
                const { container } = instance;
                const visible = !container.hasClass(CONDITIONAL_HIDDEN_CLASS_NAME);
                const breadcrumb = await calculateControlBreadcrumb(setting);
                document.dispatchEvent(
                    new CustomEvent<SettingAccessibilityChangedEvent>(SETTING_ACCESSIBILITY_CHANGED_EVENT, {
                        detail: {
                            setting,
                            valid,
                            visible,
                            breadcrumb,
                            instance,
                        },
                    }),
                );
            });

        dispatch();

        // Listen to visibility changes
        const listener = async ({ detail: { setting: eSetting } }: CustomEvent<ControlVisibilityChangedEvent>) => {
            if (setting === eSetting) {
                dispatch();
            }
        };

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

export { useA11yDispatcher };
