/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/stores/tenantStore.js
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
*/
import { defineStore } from 'pinia';
import { supabase } from '@/lib/supabase/client';
import { normalizeRole } from '@/utils/roleNormalizer';
import { logTenant, logError } from '@/support/supportLogger';

// wrapper que mantém o contrato original do tenantStore (retornar null quando role vazio)
function normalizeTenantRole(role, kind) {
    return normalizeRole(role, kind) || null;
}

function readSavedTenant() {
    const id = localStorage.getItem('tenant_id');
    if (!id) return null;
    try {
        const raw = localStorage.getItem('tenant');
        const obj = raw ? JSON.parse(raw) : null;
        return { id, role: obj?.role ?? null };
    } catch {
        return { id, role: null };
    }
}

function persistTenant(tenantId, role) {
    if (!tenantId) return clearPersistedTenant();
    localStorage.setItem('tenant_id', tenantId);
    localStorage.setItem('tenant', JSON.stringify({ id: tenantId, role }));
}

function clearPersistedTenant() {
    localStorage.removeItem('tenant_id');
    localStorage.removeItem('tenant');
}

// Promise compartilhada: enquanto um loadSessionAndTenant está em voo, todos os
// callers concorrentes aguardam a mesma promise (singleflight).
let loadPromise = null;

export const useTenantStore = defineStore('tenant', {
    state: () => ({
        loading: false,
        loaded: false,
        user: null,
        memberships: [],
        activeTenantId: null,
        activeRole: null,
        needsTenantLink: false,
        error: null
    }),

    getters: {
        tenantId: (s) => s.activeTenantId,
        currentTenantId: (s) => s.activeTenantId,
        role: (s) => s.activeRole,
        tenant: (s) => (s.activeTenantId ? { id: s.activeTenantId, role: s.activeRole } : null),
        hasActiveTenant: (s) => !!s.activeTenantId,
        // schema-per-tenant: slug vem de my_tenants(); schema físico é tenant_<slug>
        activeTenantSlug: (s) => s.memberships.find((x) => x.tenant_id === s.activeTenantId)?.slug ?? null,
        activeTenantSchema() {
            return this.activeTenantSlug ? `tenant_${this.activeTenantSlug}` : null;
        }
    },

    actions: {
        async ensureLoaded() {
            if (this.loaded) return;
            if (loadPromise) {
                await loadPromise;
                return;
            }
            await this.loadSessionAndTenant();
        },

        async loadSessionAndTenant() {
            if (loadPromise) return loadPromise;

            loadPromise = this._doLoadSessionAndTenant();
            try {
                await loadPromise;
            } finally {
                loadPromise = null;
            }
        },

        async _doLoadSessionAndTenant() {
            this.loading = true;
            this.error = null;

            try {
                const { data, error } = await supabase.auth.getSession();
                if (error) throw error;

                this.user = data?.session?.user ?? null;

                if (!this.user) {
                    this.memberships = [];
                    this.activeTenantId = null;
                    this.activeRole = null;
                    this.needsTenantLink = false;
                    this.loaded = true;
                    clearPersistedTenant();
                    return;
                }

                const { data: mem, error: mErr } = await supabase.rpc('my_tenants');
                if (mErr) throw mErr;

                this.memberships = Array.isArray(mem) ? mem : [];

                // ✅ FIX: só restaura o tenant salvo se pertence ao usuário atual.
                // Sem isso, usuário B herdava o tenant_id do usuário A (mesma máquina),
                // carregava com role errado e o menu ficava incorreto.
                const saved = readSavedTenant();
                const savedTenantId = saved?.id || null;

                let activeMembership = null;

                if (savedTenantId) {
                    activeMembership = this.memberships.find((x) => x.tenant_id === savedTenantId && x.status === 'active');
                    if (!activeMembership) {
                        logTenant('tenantStore', 'tenant salvo não pertence a este usuário, limpando', { savedTenantId });
                        clearPersistedTenant();
                    }
                }

                // fallback: primeiro active
                if (!activeMembership) {
                    activeMembership = this.memberships.find((x) => x.status === 'active');
                }

                this.activeTenantId = activeMembership?.tenant_id ?? null;
                this.activeRole = normalizeTenantRole(activeMembership?.role, activeMembership?.kind);

                if (this.activeTenantId) {
                    persistTenant(this.activeTenantId, this.activeRole);
                } else {
                    clearPersistedTenant();
                }

                this.needsTenantLink = !this.activeTenantId;
                this.loaded = true;
            } catch (e) {
                logError('tenantStore', 'loadSessionAndTenant falhou', e);
                this.error = e;

                if (!this.user) {
                    this.memberships = [];
                    this.activeTenantId = null;
                    this.activeRole = null;
                    this.needsTenantLink = false;
                    clearPersistedTenant();
                }

                this.loaded = true;
            } finally {
                this.loading = false;
            }
        },

        setActiveTenant(tenantId) {
            const found = this.memberships.find((x) => x.tenant_id === tenantId && x.status === 'active');

            this.activeTenantId = found?.tenant_id ?? null;
            this.activeRole = normalizeTenantRole(found?.role, found?.kind);
            this.needsTenantLink = !this.activeTenantId;

            if (this.activeTenantId) {
                persistTenant(this.activeTenantId, this.activeRole);
            } else {
                clearPersistedTenant();
            }
        },

        reset() {
            this.user = null;
            this.memberships = [];
            this.activeTenantId = null;
            this.activeRole = null;
            this.needsTenantLink = false;
            this.error = null;
            this.loaded = false;
            clearPersistedTenant();
        }
    }
});
