import { onBeforeUnmount, onMounted, ref } from 'vue';

/**
 * Shared horizontal-scroll synchronization for wide kView data tables.
 * The real table viewport remains authoritative; an optional persistent
 * native scrollbar mirrors its progress without duplicating table content.
 */
export const useKviewTableScroll = () => {
    const mainScroll = ref<HTMLElement | null>(null);
    const tableElement = ref<HTMLTableElement | null>(null);
    const persistentHorizontalScroll = ref<HTMLElement | null>(null);
    const containerWidth = ref(0);
    const horizontalScrollWidth = ref(0);
    const isHorizontallyScrollable = ref(false);
    const isHorizontallyScrolled = ref(false);
    let resizeObserver: ResizeObserver | null = null;

    const syncScrollProgress = (source: HTMLElement, target: HTMLElement): void => {
        const sourceMaximum = Math.max(0, source.scrollWidth - source.clientWidth);
        const targetMaximum = Math.max(0, target.scrollWidth - target.clientWidth);
        const next = sourceMaximum > 0
            ? Math.min(targetMaximum, Math.max(0, (source.scrollLeft / sourceMaximum) * targetMaximum))
            : 0;

        if (Math.abs(target.scrollLeft - next) > 0.5) {
            target.scrollLeft = next;
        }
    };

    const alignPersistentHorizontalScroll = (): void => {
        if (mainScroll.value && persistentHorizontalScroll.value) {
            syncScrollProgress(mainScroll.value, persistentHorizontalScroll.value);
        }
    };

    const syncHorizontalScrollState = (): void => {
        const scroller = mainScroll.value;

        if (!scroller) {
            horizontalScrollWidth.value = 0;
            isHorizontallyScrollable.value = false;
            isHorizontallyScrolled.value = false;

            return;
        }

        horizontalScrollWidth.value = scroller.scrollWidth;
        isHorizontallyScrollable.value = scroller.scrollWidth > scroller.clientWidth + 1;
        isHorizontallyScrolled.value = isHorizontallyScrollable.value && scroller.scrollLeft > 1;
        alignPersistentHorizontalScroll();
    };

    const syncMainHorizontalScroll = (): void => {
        const scroller = mainScroll.value;
        const persistentScroller = persistentHorizontalScroll.value;

        if (!scroller || !persistentScroller) {
            return;
        }

        syncScrollProgress(persistentScroller, scroller);
        syncHorizontalScrollState();
    };

    onMounted(() => {
        containerWidth.value = mainScroll.value?.clientWidth ?? 0;
        syncHorizontalScrollState();

        if (typeof ResizeObserver !== 'undefined' && mainScroll.value) {
            resizeObserver = new ResizeObserver(() => {
                containerWidth.value = mainScroll.value?.clientWidth ?? 0;
                syncHorizontalScrollState();
            });
            resizeObserver.observe(mainScroll.value);

            if (tableElement.value) {
                resizeObserver.observe(tableElement.value);
            }
        }
    });

    onBeforeUnmount(() => {
        resizeObserver?.disconnect();
        resizeObserver = null;
    });

    return {
        mainScroll,
        tableElement,
        persistentHorizontalScroll,
        containerWidth,
        horizontalScrollWidth,
        isHorizontallyScrollable,
        isHorizontallyScrolled,
        alignPersistentHorizontalScroll,
        syncHorizontalScrollState,
        syncMainHorizontalScroll,
    };
};
