/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/layout/composables/layout.js
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
*/
import { computed, reactive, ref, onMounted, onBeforeUnmount } from 'vue';

// Espelha --breakpoint-xl de src/assets/tailwind.css
const BREAKPOINT_XL = 1280;

// ── resolve variant salvo no localStorage ───────────────────
// 'classic' = Sidebar lateral
// 'rail'    = Mini rail + painel
// 'melissa' = Layout Melissa (Direção B). Hoje só persiste a preferência —
//             o switch real do app vem na Fase 5 (router wire-up).
function _loadVariant() {
    try {
        const v = localStorage.getItem('layout_variant');
        if (v === 'rail' || v === 'classic' || v === 'melissa') return v;
    } catch {}
    return 'rail';
}

function _loadRailOpenMode() {
    try {
        const v = localStorage.getItem('rail_open_mode');
        if (v === 'click' || v === 'hover') return v;
    } catch {}
    return 'hover';
}

// ── resolve tema (preset/primary/surface) salvo no localStorage ─
function _loadSavedTheme() {
    try {
        const raw = localStorage.getItem('ui_theme_config');
        if (raw) return JSON.parse(raw);
    } catch {}
    return {};
}

const _savedTheme = _loadSavedTheme();

const layoutConfig = reactive({
    preset: _savedTheme.preset || 'Aura',
    primary: _savedTheme.primary || 'emerald',
    surface: _savedTheme.surface || null,
    darkTheme: false,
    menuMode: _savedTheme.menuMode || 'static',
    variant: _loadVariant(), // 'classic' | 'rail'
    railOpenMode: _loadRailOpenMode() // 'click' | 'hover'
});

const layoutState = reactive({
    staticMenuInactive: false,
    overlayMenuActive: false,
    mobileMenuActive: false,
    profileSidebarVisible: false,
    configSidebarVisible: false,
    sidebarExpanded: false,
    menuHoverActive: false,
    anchored: false,
    activeMenuItem: null,
    activePath: null,
    // ── Layout 2 (rail) ─────────────────────────────────────
    railSectionKey: null, // qual seção está ativa no rail
    railPanelOpen: false, // painel lateral expandido
    // ── variant dirty: true quando o usuário mudou o variant
    // mas ainda não salvou — impede que loadUserSettings reverta
    _variantDirty: false
});

/**
 * ✅ Fonte da verdade do dark:
 * - DOM class: .app-dark (usado pelo PrimeUI/PrimeVue)
 * - layoutConfig.darkTheme: refletir o DOM (pra UI reagir)
 *
 * Motivo: você aplica tema cedo (main.js / user_settings) e depois
 * usa o composable em páginas/Topbar/Configurator. Se não sincronizar,
 * isDarkTheme pode ficar "mentindo".
 */
let _syncedDarkFromDomOnce = false;
function syncDarkFromDomOnce() {
    if (_syncedDarkFromDomOnce) return;
    _syncedDarkFromDomOnce = true;
    try {
        layoutConfig.darkTheme = document.documentElement.classList.contains('app-dark');
    } catch {}
}

// ── reactive mobile state (atualiza no resize) ───────────────
const _isMobileRef = ref(typeof window !== 'undefined' ? window.innerWidth <= BREAKPOINT_XL : false);

if (typeof window !== 'undefined') {
    const _onResize = () => {
        _isMobileRef.value = window.innerWidth <= BREAKPOINT_XL;
    };
    window.addEventListener('resize', _onResize, { passive: true });
}

// ── Timer compartilhado para hover do rail ───────────────────
let _railHoverCloseTimer = null;

export function useLayout() {
    // ✅ garante coerência sempre que alguém usar useLayout()
    syncDarkFromDomOnce();

    const executeDarkModeToggle = () => {
        layoutConfig.darkTheme = !layoutConfig.darkTheme;

        // ✅ garante consistência (não depende do estado anterior do DOM)
        document.documentElement.classList.toggle('app-dark', layoutConfig.darkTheme);
    };

    const toggleDarkMode = () => {
        if (!document.startViewTransition) {
            executeDarkModeToggle();
            return;
        }

        // ✅ não usa "event" (undefined) e mantém transição suave quando suportado
        document.startViewTransition(() => executeDarkModeToggle());
    };

    const isDesktop = () => window.innerWidth > BREAKPOINT_XL;

    // breakpoint do botão hamburguer no Rail (≤ xl)
    const isRailMobile = () => window.innerWidth <= BREAKPOINT_XL;

    const toggleMenu = () => {
        // No Rail, em desktop, o botão hamburguer controla a sidebar mobile do rail
        if (layoutConfig.variant === 'rail' && !_isMobileRef.value) {
            layoutState.mobileMenuActive = !layoutState.mobileMenuActive;
            return;
        }

        // Layout clássico — usa effectiveMenuMode para decidir o estado correto
        if (isDesktop()) {
            if (effectiveMenuMode.value === 'static') {
                layoutState.staticMenuInactive = !layoutState.staticMenuInactive;
            }
            if (effectiveMenuMode.value === 'overlay') {
                layoutState.overlayMenuActive = !layoutState.overlayMenuActive;
            }
        } else {
            // ≤ xl: effectiveMenuMode sempre 'overlay' — usa overlayMenuActive para
            // parear corretamente com a classe layout-overlay do containerClass
            layoutState.overlayMenuActive = !layoutState.overlayMenuActive;
        }
    };

    const toggleConfigSidebar = () => {
        layoutState.configSidebarVisible = !layoutState.configSidebarVisible;
    };

    const hideMobileMenu = () => {
        layoutState.mobileMenuActive = false;
        layoutState.overlayMenuActive = false;
        layoutState.menuHoverActive = false;
    };

    // ✅ use isso ao navegar: mantém menu aberto no desktop, fecha só no mobile
    const closeMenuOnNavigate = () => {
        if (!isDesktop()) {
            layoutState.mobileMenuActive = false;
            layoutState.overlayMenuActive = false;
            layoutState.menuHoverActive = false;
        }
    };

    /**
     * ✅ aceita:
     * - changeMenuMode({ value: 'static' })
     * - changeMenuMode('static')
     *
     * Motivo: você chama isso de lugares diferentes (Topbar, Configurator, Profile).
     */
    const changeMenuMode = (eventOrValue) => {
        const nextMode = typeof eventOrValue === 'string' ? eventOrValue : eventOrValue?.value;

        // ✅ não deixa setar undefined / vazio
        if (!nextMode) return;

        layoutConfig.menuMode = nextMode;

        // ✅ reset consistente (evita drift quando alterna overlay/static)
        layoutState.staticMenuInactive = false;
        layoutState.overlayMenuActive = false;
        layoutState.mobileMenuActive = false;
        layoutState.sidebarExpanded = false;
        layoutState.menuHoverActive = false;
        layoutState.anchored = false;
    };

    const setVariant = (v, { fromUser = true } = {}) => {
        if (v !== 'classic' && v !== 'rail' && v !== 'melissa') return;
        const prev = layoutConfig.variant;
        layoutConfig.variant = v;
        try {
            localStorage.setItem('layout_variant', v);
        } catch {}
        // Reset do estado do rail SÓ quando o novo variant não é 'rail'.
        // Antes, o reset acontecia em todo setVariant — incluindo na troca
        // de volta pra rail (ex.: rail → melissa → rail). Resultado: o rail
        // remontava sem seção ativa e o menu da esquerda aparecia sem itens
        // até o usuário clicar em algo. Preservar o estado quando volta pra
        // rail mantém a UX coerente.
        if (v !== 'rail') {
            layoutState.railSectionKey = null;
            layoutState.railPanelOpen = false;
        }
        // marca que o usuário fez uma escolha explícita (não restauração do DB)
        if (fromUser) layoutState._variantDirty = true;
        // dev-only: facilita auditar trocas de layout sem instrumentar o profile
        if (typeof window !== 'undefined' && window?.__DEV_LAYOUT_LOG) {
            // eslint-disable-next-line no-console
            console.debug('[layout.setVariant]', prev, '→', v);
        }
    };

    const setRailOpenMode = (mode) => {
        if (mode !== 'click' && mode !== 'hover') return;
        layoutConfig.railOpenMode = mode;
        try {
            localStorage.setItem('rail_open_mode', mode);
        } catch {}
    };

    const clearRailHoverClose = () => {
        if (_railHoverCloseTimer !== null) {
            clearTimeout(_railHoverCloseTimer);
            _railHoverCloseTimer = null;
        }
    };

    const scheduleRailHoverClose = (delay = 200) => {
        clearRailHoverClose();
        _railHoverCloseTimer = setTimeout(() => {
            layoutState.railPanelOpen = false;
            _railHoverCloseTimer = null;
        }, delay);
    };

    const isDarkTheme = computed(() => layoutConfig.darkTheme);
    const hasOpenOverlay = computed(() => layoutState.overlayMenuActive);

    // true apenas quando o painel está aberto E empurra o layout (não no modo hover)
    const railPanelPushesLayout = computed(() =>
        layoutState.railPanelOpen && layoutConfig.railOpenMode !== 'hover'
    );

    // ── Em mobile (≤ xl / 1280px) sempre usa o layout clássico, ───────
    // independente de layoutConfig.variant
    const isMobile = computed(() => _isMobileRef.value);
    const effectiveVariant = computed(() => (_isMobileRef.value ? 'classic' : layoutConfig.variant));

    // ── Em mobile (≤ xl) força overlay, sem alterar o valor salvo ───────
    const effectiveMenuMode = computed(() => (_isMobileRef.value ? 'overlay' : layoutConfig.menuMode));

    return {
        layoutConfig,
        layoutState,
        isDarkTheme,
        toggleDarkMode,
        toggleConfigSidebar,
        toggleMenu,
        hideMobileMenu,
        closeMenuOnNavigate,
        changeMenuMode,
        setVariant,
        setRailOpenMode,
        railPanelPushesLayout,
        clearRailHoverClose,
        scheduleRailHoverClose,
        isDesktop,
        isRailMobile,
        isMobile,
        effectiveVariant,
        effectiveMenuMode,
        hasOpenOverlay
    };
}
