import { ref, type Ref } from 'vue';

export interface DevIndicesApi {
    currentTarget: Ref<HTMLElement | null>;
    currentId: Ref<number | null>;
    overlayMode: Ref<boolean>;
    hoverEnabled: Ref<boolean>;
    setTarget(el: HTMLElement | null): void;
    toggleOverlay(): void;
    walkToParent(): void;
    walkToChild(): void;
    pauseHover(ms: number): void;
    reset(): void;
}

// Module-level singleton state — shared across all consumers
const currentTarget = ref<HTMLElement | null>(null);
const currentId = ref<number | null>(null);
const overlayMode = ref(false);
const hoverEnabled = ref(true);
let pauseTimer: ReturnType<typeof setTimeout> | null = null;

function parseId(el: HTMLElement | null): number | null {
    if (!el) return null;
    const raw = el.getAttribute('data-dx');
    if (raw == null) return null;
    const n = Number(raw);
    return Number.isFinite(n) ? n : null;
}

function setTarget(el: HTMLElement | null): void {
    if (el == null) {
        currentTarget.value = null;
        currentId.value = null;
        return;
    }
    const id = parseId(el);
    if (id == null) return;
    currentTarget.value = el;
    currentId.value = id;
}

function toggleOverlay(): void {
    overlayMode.value = !overlayMode.value;
}

function findAncestorWithDx(el: HTMLElement | null): HTMLElement | null {
    let cur: HTMLElement | null = el?.parentElement ?? null;
    while (cur) {
        if (cur.hasAttribute('data-dx')) return cur;
        cur = cur.parentElement;
    }
    return null;
}

function findFirstDescendantWithDx(el: HTMLElement | null): HTMLElement | null {
    if (!el) return null;
    // BFS: find first descendant with data-dx
    const queue: HTMLElement[] = Array.from(el.children) as HTMLElement[];
    while (queue.length) {
        const cur = queue.shift()!;
        if (cur.hasAttribute('data-dx')) return cur;
        queue.push(...(Array.from(cur.children) as HTMLElement[]));
    }
    return null;
}

function walkToParent(): void {
    const parent = findAncestorWithDx(currentTarget.value);
    if (parent) setTarget(parent);
}

function walkToChild(): void {
    const child = findFirstDescendantWithDx(currentTarget.value);
    if (child) setTarget(child);
}

function pauseHover(ms: number): void {
    hoverEnabled.value = false;
    if (pauseTimer) clearTimeout(pauseTimer);
    pauseTimer = setTimeout(() => {
        hoverEnabled.value = true;
        pauseTimer = null;
    }, ms);
}

function reset(): void {
    currentTarget.value = null;
    currentId.value = null;
    overlayMode.value = false;
    hoverEnabled.value = true;
    if (pauseTimer) {
        clearTimeout(pauseTimer);
        pauseTimer = null;
    }
}

export function useDevIndices(): DevIndicesApi {
    return {
        currentTarget,
        currentId,
        overlayMode,
        hoverEnabled,
        setTarget,
        toggleOverlay,
        walkToParent,
        walkToChild,
        pauseHover,
        reset,
    };
}
