/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/composables/useAuditoria.js
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
*/

import { ref, computed } from 'vue';
import { supabase } from '@/lib/supabase/client';
import { tenantDb } from '@/lib/supabase/tenantClient';
import { useTenantStore } from '@/stores/tenantStore';

// ─── helpers ────────────────────────────────────────────────────────────────

function startOfDay(d) {
    const x = new Date(d);
    x.setHours(0, 0, 0, 0);
    return x;
}

function endOfDay(d) {
    const x = new Date(d);
    x.setHours(23, 59, 59, 999);
    return x;
}

function resolveDateRange(preset, customRange) {
    const now = new Date();
    if (preset === 'today') {
        return { from: startOfDay(now), to: endOfDay(now) };
    }
    if (preset === 'last7') {
        const start = new Date(now);
        start.setDate(start.getDate() - 6);
        return { from: startOfDay(start), to: endOfDay(now) };
    }
    if (preset === 'last30') {
        const start = new Date(now);
        start.setDate(start.getDate() - 29);
        return { from: startOfDay(start), to: endOfDay(now) };
    }
    if (preset === 'last90') {
        const start = new Date(now);
        start.setDate(start.getDate() - 89);
        return { from: startOfDay(start), to: endOfDay(now) };
    }
    if (preset === 'custom' && Array.isArray(customRange) && customRange[0] && customRange[1]) {
        return { from: startOfDay(customRange[0]), to: endOfDay(customRange[1]) };
    }
    const start = new Date(now);
    start.setDate(start.getDate() - 6);
    return { from: startOfDay(start), to: endOfDay(now) };
}

function sanitizeSearch(raw) {
    if (typeof raw !== 'string') return '';
    return raw.trim().slice(0, 120).toLowerCase();
}

// ─── composable ─────────────────────────────────────────────────────────────

export function useAuditoria() {
    const tenantStore = useTenantStore();

    const events = ref([]);
    const usersMap = ref({}); // { uid: { email, display_name } }
    const loading = ref(false);
    const error = ref(null);

    const filters = ref({
        periodPreset: 'last7',
        customRange: null,
        sources: [], // [] = todas
        entityTypes: [], // [] = todos
        actions: [], // [] = todas
        userId: null,
        search: ''
    });

    const dateRange = computed(() => resolveDateRange(filters.value.periodPreset, filters.value.customRange));

    async function load() {
        const tenantId = tenantStore.activeTenantId;
        if (!tenantId) {
            events.value = [];
            error.value = new Error('Tenant ativo inválido.');
            return;
        }

        loading.value = true;
        error.value = null;

        try {
            const { from, to } = dateRange.value;

            let query = tenantDb().from('audit_log_unified')
                .select('uid, user_id, entity_type, entity_id, action, description, occurred_at, source, details')
                .gte('occurred_at', from.toISOString())
                .lte('occurred_at', to.toISOString())
                .order('occurred_at', { ascending: false })
                .limit(5000);

            if (filters.value.sources.length > 0) {
                query = query.in('source', filters.value.sources);
            }
            if (filters.value.entityTypes.length > 0) {
                query = query.in('entity_type', filters.value.entityTypes);
            }
            if (filters.value.actions.length > 0) {
                query = query.in('action', filters.value.actions);
            }
            if (filters.value.userId) {
                query = query.eq('user_id', filters.value.userId);
            }

            const { data, error: qErr } = await query;
            if (qErr) throw qErr;
            events.value = data ?? [];

            await resolveUserNames();
        } catch (err) {
            error.value = err;
            events.value = [];
        } finally {
            loading.value = false;
        }
    }

    async function resolveUserNames() {
        const uids = [...new Set(events.value.map((e) => e.user_id).filter(Boolean))];
        const unknown = uids.filter((u) => !usersMap.value[u]);
        if (!unknown.length) return;

        const { data } = await supabase.from('profiles').select('id, full_name, nickname').in('id', unknown);

        const next = { ...usersMap.value };
        for (const u of unknown) next[u] = { email: '', display_name: '' };
        for (const p of data ?? []) {
            next[p.id] = { email: '', display_name: p.full_name || p.nickname || '' };
        }
        usersMap.value = next;
    }

    function userDisplay(userId) {
        if (!userId) return 'Sistema';
        const u = usersMap.value[userId];
        if (!u) return 'Usuário desconhecido';
        return u.display_name || u.email || userId.slice(0, 8);
    }

    // filtro client-side: busca textual
    const rows = computed(() => {
        const q = sanitizeSearch(filters.value.search);
        if (!q) return events.value;
        return events.value.filter((e) => {
            const desc = (e.description || '').toLowerCase();
            const entity = (e.entity_type || '').toLowerCase();
            const action = (e.action || '').toLowerCase();
            const src = (e.source || '').toLowerCase();
            const user = userDisplay(e.user_id).toLowerCase();
            return desc.includes(q) || entity.includes(q) || action.includes(q) || src.includes(q) || user.includes(q);
        });
    });

    const summary = computed(() => {
        const bySource = {};
        const byAction = {};
        const byUser = new Set();

        for (const e of rows.value) {
            bySource[e.source] = (bySource[e.source] || 0) + 1;
            byAction[e.action] = (byAction[e.action] || 0) + 1;
            if (e.user_id) byUser.add(e.user_id);
        }

        return {
            totalRows: rows.value.length,
            bySource,
            byAction,
            distinctUsers: byUser.size
        };
    });

    return {
        events,
        rows,
        filters,
        dateRange,
        loading,
        error,
        summary,
        userDisplay,
        load
    };
}
