/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/composables/useAjuda.js
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
*/
// - Home: docs da sessão atual + outros docs paginados + FAQ
// - Navegação interna com stack (voltar)
// - Votação por usuário (útil / não útil)

import { ref, computed } from 'vue';
import { supabase } from '@/lib/supabase/client';
import { sessionRole, sessionIsSaasAdmin } from '@/app/session';

const ADMIN_ROLES = ['clinic_admin', 'tenant_admin'];

function isCurrentUserAdmin() {
    return sessionIsSaasAdmin.value || ADMIN_ROLES.includes(sessionRole.value);
}

// ── Singleton state ────────────────────────────────────────────
const cache = new Map(); // path → { docs, relatedDocs, faqItens }
const docCache = new Map(); // id   → { docs, relatedDocs, faqItens }

// Estado da sessão atual
const sessionDocs = ref([]);
const sessionFaq = ref([]);
const sessionPath = ref('');

// Estado da home (todos os docs paginados + FAQ global)
const allDocs = ref([]);
const allDocsTotal = ref(0);
const allDocsPage = ref(0);
const allDocsLoading = ref(false);
const ALL_DOCS_PAGE_SIZE = 8;

const globalFaq = ref([]);
const globalFaqLoading = ref(false);

// Drawer
const drawerOpen = ref(false);
const loading = ref(false);

// Stack de navegação — cada entrada: { currentDoc, label }
const navStack = ref([]);
// null = home, objeto = doc aberto
const currentDoc = ref(null);

const isHome = computed(() => currentDoc.value === null);
const isNavigating = computed(() => navStack.value.length > 0);

// Votos do usuário { [docId]: true | false | null }
const meusVotos = ref({});

// ── Helpers ───────────────────────────────────────────────────
function normalizePath(path) {
    return (
        String(path || '')
            .split('?')[0]
            .split('#')[0]
            .replace(/\/$/, '') || '/'
    );
}

async function fetchFaqItensForDocs(docIds) {
    if (!docIds.length) return [];
    const { data } = await supabase.from('saas_faq_itens').select('id, doc_id, pergunta, resposta, ordem').in('doc_id', docIds).eq('ativo', true).order('doc_id').order('ordem');
    return data || [];
}

// ── Fetch por rota (chamado pelo AppLayout ao mudar de rota) ──
export async function fetchDocsForPath(rawPath) {
    const path = normalizePath(rawPath);
    sessionPath.value = path;
    currentDoc.value = null;
    navStack.value = [];
    // Reseta paginação de outros docs ao mudar de rota
    allDocs.value = [];
    allDocsPage.value = 0;

    if (cache.has(path)) {
        const cached = cache.get(path);
        sessionDocs.value = cached.docs;
        sessionFaq.value = cached.faqItens;
        return;
    }

    loading.value = true;
    try {
        const { data, error } = await supabase
            .from('saas_docs')
            .select('id, titulo, conteudo, medias, tipo_acesso, docs_relacionados, ordem, categoria, exibir_no_faq, votos_util, votos_nao_util')
            .eq('pagina_path', path)
            .eq('ativo', true)
            .order('ordem');

        if (error) throw error;

        const userIsAdmin = isCurrentUserAdmin();
        const mainDocs = (data || []).filter((d) => d.tipo_acesso === 'usuario' || userIsAdmin);

        const allIds = [...new Set(mainDocs.flatMap((d) => d.docs_relacionados || []))];
        let related = [];
        if (allIds.length) {
            const { data: relData } = await supabase.from('saas_docs').select('id, titulo, pagina_path').in('id', allIds).eq('ativo', true);
            related = relData || [];
        }

        const itens = await fetchFaqItensForDocs(mainDocs.map((d) => d.id));

        cache.set(path, { docs: mainDocs, relatedDocs: related, faqItens: itens });
        sessionDocs.value = mainDocs;
        sessionFaq.value = itens;
    } catch (e) {
        console.warn('[useAjuda] erro ao buscar docs:', e?.message || e);
        sessionDocs.value = [];
        sessionFaq.value = [];
    } finally {
        loading.value = false;
    }
}

// ── Todos os docs paginados (para a home do drawer) ───────────
export async function loadAllDocs(page = 0) {
    allDocsLoading.value = true;
    try {
        const from = page * ALL_DOCS_PAGE_SIZE;
        const to = from + ALL_DOCS_PAGE_SIZE - 1;

        const userIsAdmin = isCurrentUserAdmin();
        let query = supabase.from('saas_docs').select('id, titulo, pagina_path, categoria, votos_util, votos_nao_util', { count: 'exact' }).eq('ativo', true).order('titulo').range(from, to);

        if (!userIsAdmin) query = query.eq('tipo_acesso', 'usuario');

        const { data, count, error } = await query;
        if (error) throw error;

        // Exclui docs da sessão atual
        const sessionIds = new Set(sessionDocs.value.map((d) => d.id));
        const filtered = (data || []).filter((d) => !sessionIds.has(d.id));

        allDocs.value = page === 0 ? filtered : [...allDocs.value, ...filtered];
        allDocsTotal.value = count || 0;
        allDocsPage.value = page;
    } catch (e) {
        console.warn('[useAjuda] erro ao carregar todos os docs:', e?.message || e);
    } finally {
        allDocsLoading.value = false;
    }
}

// ── FAQ global (itens fora da sessão atual) ───────────────────
export async function loadGlobalFaq() {
    globalFaqLoading.value = true;
    try {
        const userIsAdmin = isCurrentUserAdmin();
        let q = supabase.from('saas_docs').select('id, titulo').eq('ativo', true).eq('exibir_no_faq', true);

        if (!userIsAdmin) q = q.eq('tipo_acesso', 'usuario');

        const { data: faqDocs } = await q;
        if (!faqDocs?.length) {
            globalFaq.value = [];
            return;
        }

        const sessionIds = new Set(sessionDocs.value.map((d) => d.id));
        const outrosIds = faqDocs.filter((d) => !sessionIds.has(d.id)).map((d) => d.id);

        if (!outrosIds.length) {
            globalFaq.value = [];
            return;
        }

        const itens = await fetchFaqItensForDocs(outrosIds);
        globalFaq.value = itens.map((item) => ({
            ...item,
            _docTitulo: faqDocs.find((d) => d.id === item.doc_id)?.titulo || ''
        }));
    } catch (e) {
        console.warn('[useAjuda] erro ao carregar FAQ global:', e?.message || e);
        globalFaq.value = [];
    } finally {
        globalFaqLoading.value = false;
    }
}

// ── Votos do usuário ──────────────────────────────────────────
export async function loadMeusVotos() {
    try {
        const {
            data: { user }
        } = await supabase.auth.getUser();
        if (!user) return;
        const { data } = await supabase.from('saas_doc_votos').select('doc_id, util').eq('user_id', user.id);
        meusVotos.value = {};
        for (const v of data || []) meusVotos.value[v.doc_id] = v.util;
    } catch (e) {
        console.warn('[useAjuda] erro ao carregar votos:', e?.message || e);
    }
}

export async function votar(docId, util) {
    try {
        const { data, error } = await supabase.rpc('saas_votar_doc', {
            p_doc_id: docId,
            p_util: util
        });
        if (error) throw error;

        const acao = data?.acao;
        meusVotos.value = {
            ...meusVotos.value,
            [docId]: acao === 'removido' ? null : util
        };
        _atualizarContadorLocal(docId, util, acao);
    } catch (e) {
        console.warn('[useAjuda] erro ao votar:', e?.message || e);
    }
}

function _atualizarContadorLocal(docId, util, acao) {
    const ajustar = (doc) => {
        if (!doc || doc.id !== docId) return doc;
        let { votos_util = 0, votos_nao_util = 0 } = doc;
        if (acao === 'registrado') {
            if (util) votos_util++;
            else votos_nao_util++;
        } else if (acao === 'removido') {
            if (util) votos_util = Math.max(0, votos_util - 1);
            else votos_nao_util = Math.max(0, votos_nao_util - 1);
        } else if (acao === 'atualizado') {
            if (util) {
                votos_util++;
                votos_nao_util = Math.max(0, votos_nao_util - 1);
            } else {
                votos_nao_util++;
                votos_util = Math.max(0, votos_util - 1);
            }
        }
        return { ...doc, votos_util, votos_nao_util };
    };
    sessionDocs.value = sessionDocs.value.map(ajustar);
    allDocs.value = allDocs.value.map(ajustar);
    if (currentDoc.value) {
        currentDoc.value = { ...currentDoc.value, docs: currentDoc.value.docs.map(ajustar) };
    }
    cache.forEach((val, key) => {
        if (val.docs.some((d) => d.id === docId)) cache.delete(key);
    });
    docCache.delete(docId);
}

// ── Navegação interna ─────────────────────────────────────────
export async function navigateToDoc(docId, label = '') {
    if (!docId) return;

    navStack.value.push({ currentDoc: currentDoc.value, label: label || 'Voltar' });
    loading.value = true;
    try {
        if (docCache.has(docId)) {
            currentDoc.value = docCache.get(docId);
            return;
        }

        const { data, error } = await supabase.from('saas_docs').select('id, titulo, conteudo, medias, tipo_acesso, docs_relacionados, ordem, categoria, exibir_no_faq, votos_util, votos_nao_util').eq('id', docId).eq('ativo', true).maybeSingle();

        if (error) throw error;
        if (!data) {
            navStack.value.pop();
            return;
        }

        const userIsAdmin = isCurrentUserAdmin();
        if (data.tipo_acesso !== 'usuario' && !userIsAdmin) {
            navStack.value.pop();
            return;
        }

        const relIds = data.docs_relacionados || [];
        let related = [];
        if (relIds.length) {
            const { data: relData } = await supabase.from('saas_docs').select('id, titulo, pagina_path').in('id', relIds).eq('ativo', true);
            related = relData || [];
        }

        const itens = await fetchFaqItensForDocs([data.id]);
        const entry = { docs: [data], relatedDocs: related, faqItens: itens };
        docCache.set(docId, entry);
        currentDoc.value = entry;
    } catch (e) {
        console.warn('[useAjuda] erro ao navegar para doc:', e?.message || e);
        navStack.value.pop();
    } finally {
        loading.value = false;
    }
}

export function navBack() {
    const prev = navStack.value.pop();
    if (prev) currentDoc.value = prev.currentDoc;
}

export function invalidateAjudaCache(path) {
    if (path) cache.delete(normalizePath(path));
    else cache.clear();
    docCache.clear();
}

export function resetAjuda() {
    drawerOpen.value = false;
    navStack.value = [];
    currentDoc.value = null;
    sessionDocs.value = [];
    sessionFaq.value = [];
    sessionPath.value = '';
    allDocs.value = [];
    allDocsTotal.value = 0;
    allDocsPage.value = 0;
    globalFaq.value = [];
    meusVotos.value = {};
    cache.clear();
    docCache.clear();
}

// ── Composable público ────────────────────────────────────────
export function useAjuda() {
    const hasAjuda = computed(() => true); // sempre habilitado

    const allDocsHasMore = computed(() => allDocs.value.length < allDocsTotal.value - sessionDocs.value.length);

    function openDrawer() {
        drawerOpen.value = true;
        currentDoc.value = null;
        if (!allDocs.value.length) loadAllDocs(0);
        if (!globalFaq.value.length) loadGlobalFaq();
        if (!Object.keys(meusVotos.value).length) loadMeusVotos();
    }

    function closeDrawer() {
        drawerOpen.value = false;
        navStack.value = [];
        currentDoc.value = null;
    }

    function loadMoreDocs() {
        loadAllDocs(allDocsPage.value + 1);
    }

    return {
        sessionDocs,
        sessionFaq,
        sessionPath,
        allDocs,
        allDocsTotal,
        allDocsLoading,
        allDocsHasMore,
        globalFaq,
        globalFaqLoading,
        currentDoc,
        isHome,
        isNavigating,
        navStack,
        drawerOpen,
        loading,
        hasAjuda,
        meusVotos,
        openDrawer,
        closeDrawer,
        navigateToDoc,
        navBack,
        votar,
        loadMoreDocs
    };
}
