import { onBeforeUnmount, onMounted } from 'vue';
import { POLLING_INTERVAL_MS } from '../constants/polling';

/**
 * Polling-composable для авто-обновления view-данных.
 *
 * Используется в DealsView/KanbanView/AdminTenants/Billing/Incidents как
 * замена manual reload-btn — каждые `intervalMs` миллисекунд вызывает
 * переданный `loader()`. На MVP это покрывает «real-time» pattern до
 * приезда SSE/WebSocket в production.
 *
 * Pause при скрытой вкладке (`document.hidden=true`) через Page Visibility
 * API — не делаем лишних запросов когда пользователь смотрит другую
 * вкладку. Resume на visibilitychange-event.
 *
 * Cleanup на onBeforeUnmount: clearInterval + removeEventListener.
 */
export interface PollingOptions {
    /** Период polling в миллисекундах. По умолчанию POLLING_INTERVAL_MS (30 с). */
    intervalMs?: number;
    /** Если false — composable не стартует interval (для disable-флага). */
    enabled?: boolean;
}

export function usePolling(loader: () => void | Promise<void>, options: PollingOptions = {}): void {
    const intervalMs = options.intervalMs ?? POLLING_INTERVAL_MS;
    const enabled = options.enabled ?? true;

    if (!enabled) return;

    let timerId: ReturnType<typeof setInterval> | null = null;
    let visibilityListener: (() => void) | null = null;

    function start() {
        if (timerId !== null) return;
        timerId = setInterval(() => {
            // Skip если вкладка скрыта — экономим запросы.
            if (typeof document !== 'undefined' && document.hidden) return;
            void loader();
        }, intervalMs);
    }

    function stop() {
        if (timerId !== null) {
            clearInterval(timerId);
            timerId = null;
        }
    }

    onMounted(() => {
        start();
        if (typeof document !== 'undefined') {
            visibilityListener = () => {
                if (document.hidden) {
                    stop();
                } else {
                    start();
                    // Сразу подгрузить свежее на возврат во вкладку (не ждать interval).
                    void loader();
                }
            };
            document.addEventListener('visibilitychange', visibilityListener);
        }
    });

    onBeforeUnmount(() => {
        stop();
        if (visibilityListener !== null && typeof document !== 'undefined') {
            document.removeEventListener('visibilitychange', visibilityListener);
            visibilityListener = null;
        }
    });
}
