/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Arquivo: src/layout/melissa/composables/useMelissaDockPins.js
| Data: 2026-05-04
|
| Pins dinâmicos do dock Melissa — modelo híbrido:
|
|   - PINNED (manual, max 4): user fixa via menu de contexto, persiste
|     entre sessões em localStorage. Sempre visíveis, ordenados por ordem
|     de fixação.
|   - RECENT (MRU automático, max 3): toda vez que o user abre uma seção
|     que NÃO é built-in (agenda/conversas) e NÃO tá pinned, vira o pin
|     temporário mais recente, empurrando os mais antigos pra fora.
|
| Persistência: localStorage com chave `melissa.dock.pins.v1`. Salva só
| slugs de seção (string), nada de dado clínico — LGPD-safe. Singleton via
| módulo (estado fora da função) pra todas as instâncias compartilharem.
|
| Builtin (não-pinnável, não-recente): agenda, conversas — esses já têm
| pin permanente próprio no template (.dock-pin com hardcode).
|--------------------------------------------------------------------------
*/
import { ref, watch } from 'vue';

const STORAGE_KEY = 'melissa.dock.pins.v1';
const MAX_PINNED = 4;
const MAX_RECENT = 3;
const BUILTIN_SLUGS = new Set(['agenda', 'conversas']);

// Estado singleton compartilhado entre todas as instâncias.
const pinned = ref([]);
const recent = ref([]);
let _hydrated = false;

function _hydrate() {
    if (_hydrated) return;
    _hydrated = true;
    try {
        const raw = localStorage.getItem(STORAGE_KEY);
        if (!raw) return;
        const parsed = JSON.parse(raw);
        if (Array.isArray(parsed?.pinned)) {
            pinned.value = parsed.pinned.filter((s) => typeof s === 'string').slice(0, MAX_PINNED);
        }
        if (Array.isArray(parsed?.recent)) {
            recent.value = parsed.recent.filter((s) => typeof s === 'string').slice(0, MAX_RECENT);
        }
    } catch { /* localStorage corrompido — ignora silenciosamente */ }
}

function _persist() {
    try {
        localStorage.setItem(STORAGE_KEY, JSON.stringify({
            pinned: pinned.value,
            recent: recent.value
        }));
    } catch { /* quota excedida ou storage desabilitado — ok, em memória */ }
}

let _persistWatcherActive = false;
function _ensurePersistWatcher() {
    if (_persistWatcherActive) return;
    _persistWatcherActive = true;
    watch([pinned, recent], _persist, { deep: true });
}

export function useMelissaDockPins() {
    _hydrate();
    _ensurePersistWatcher();

    function isBuiltin(slug) {
        return BUILTIN_SLUGS.has(slug);
    }
    function isPinned(slug) {
        return pinned.value.includes(slug);
    }
    function isRecent(slug) {
        return recent.value.includes(slug);
    }

    // Chamado quando o user abre uma seção. Builtins e já-pinned não viram
    // recent (não duplica). Mais recente entra no topo, expulsa o mais
    // antigo se passar do limite.
    function pushRecent(slug) {
        if (!slug || isBuiltin(slug) || isPinned(slug)) return;
        recent.value = [slug, ...recent.value.filter((s) => s !== slug)].slice(0, MAX_RECENT);
    }

    // Move um slug de "recent" pra "pinned" (ou cria pinned direto).
    // Retorna { ok, reason } — reason='full' quando já tem 4 pinned.
    function pin(slug) {
        if (!slug || isBuiltin(slug)) return { ok: false, reason: 'builtin' };
        if (isPinned(slug)) return { ok: true, reason: 'already' };
        if (pinned.value.length >= MAX_PINNED) return { ok: false, reason: 'full' };
        recent.value = recent.value.filter((s) => s !== slug);
        pinned.value = [...pinned.value, slug];
        return { ok: true };
    }

    // Tira de "pinned" — não volta automaticamente pra recent (o user
    // explicitamente desafixou). Próxima abertura da seção vai pra recent
    // pelo fluxo normal de pushRecent.
    function unpin(slug) {
        pinned.value = pinned.value.filter((s) => s !== slug);
    }

    // Remove completamente (de ambas as listas). Usado pelo "Remover" do menu.
    function remove(slug) {
        pinned.value = pinned.value.filter((s) => s !== slug);
        recent.value = recent.value.filter((s) => s !== slug);
    }

    function clearAll() {
        pinned.value = [];
        recent.value = [];
    }

    return {
        pinned,
        recent,
        isBuiltin,
        isPinned,
        isRecent,
        pushRecent,
        pin,
        unpin,
        remove,
        clearAll,
        MAX_PINNED,
        MAX_RECENT
    };
}
