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

// ─── Browser Notification helpers ────────────────────────────
const BROWSER_NOTIF_PREF_KEY = 'agenciapsi.browser_notifications_enabled';

function browserNotifSupported() {
    return typeof window !== 'undefined' && 'Notification' in window;
}

function browserNotifAllowed() {
    return browserNotifSupported() && Notification.permission === 'granted';
}

function browserNotifEnabled() {
    if (!browserNotifAllowed()) return false;
    try {
        const v = localStorage.getItem(BROWSER_NOTIF_PREF_KEY);
        return v !== 'false'; // default: on quando permitido
    } catch {
        return true;
    }
}

export function fireBrowserNotification(item, onClick) {
    if (!browserNotifEnabled()) return;
    if (document.hasFocus() && document.visibilityState === 'visible') return; // não notifica se tab ativa
    try {
        const title = item?.payload?.title || 'Nova notificação';
        const body = item?.payload?.detail || '';
        const n = new Notification(title, {
            body,
            icon: '/favicon.ico',
            tag: `agenciapsi:${item.id}`,
            requireInteraction: false
        });
        n.onclick = () => {
            window.focus();
            if (typeof onClick === 'function') {
                try { onClick(item); } catch { /* ignore */ }
            } else if (item?.payload?.deeplink) {
                // fallback: navegação direta se ninguém registrou handler
                window.location.href = item.payload.deeplink;
            }
            n.close();
        };
    } catch {
        // browser sem suporte ou permissão revogada
    }
}

export async function requestBrowserNotificationPermission() {
    if (!browserNotifSupported()) return false;
    if (Notification.permission === 'granted') return true;
    if (Notification.permission === 'denied') return false;
    try {
        const res = await Notification.requestPermission();
        return res === 'granted';
    } catch {
        return false;
    }
}

export function setBrowserNotificationEnabled(enabled) {
    try {
        localStorage.setItem(BROWSER_NOTIF_PREF_KEY, enabled ? 'true' : 'false');
    } catch {
        // ignore
    }
}

export function getBrowserNotificationEnabled() {
    return browserNotifEnabled();
}

export const useNotificationStore = defineStore('notifications', {
    state: () => ({
        items: [],
        drawerOpen: false,
        _channel: null
    }),

    getters: {
        unreadCount: (state) => state.items.filter((n) => !n.read_at && !n.archived).length,

        unreadItems: (state) => state.items.filter((n) => !n.read_at && !n.archived),

        allItems: (state) => state.items.filter((n) => !n.archived)
    },

    actions: {
        async load(ownerId) {
            const { data, error } = await supabase.from('notifications').select('*').eq('owner_id', ownerId).eq('archived', false).order('created_at', { ascending: false }).limit(50);

            if (error) {
                console.error('[notificationStore] load error:', error.message);
                return;
            }

            this.items = data || [];
        },

        subscribeRealtime(ownerId, onInsert = null) {
            if (this._channel) return;

            const channel = supabase
                .channel(`notifications:${ownerId}`)
                .on(
                    'postgres_changes',
                    {
                        event: 'INSERT',
                        schema: 'public',
                        table: 'notifications',
                        filter: `owner_id=eq.${ownerId}`
                    },
                    (payload) => {
                        this.items.unshift(payload.new);
                        if (typeof onInsert === 'function') {
                            try { onInsert(payload.new); } catch { /* ignore */ }
                        }
                    }
                )
                .subscribe();

            this._channel = channel;
        },

        async markRead(id) {
            const now = new Date().toISOString();
            const { error } = await supabase.from('notifications').update({ read_at: now }).eq('id', id);

            if (error) {
                console.error('[notificationStore] markRead error:', error.message);
                return;
            }

            const item = this.items.find((n) => n.id === id);
            if (item) item.read_at = now;
        },

        async markAllRead() {
            const unreadIds = this.items.filter((n) => !n.read_at && !n.archived).map((n) => n.id);

            if (!unreadIds.length) return;

            const now = new Date().toISOString();
            const { error } = await supabase.from('notifications').update({ read_at: now }).in('id', unreadIds);

            if (error) {
                console.error('[notificationStore] markAllRead error:', error.message);
                return;
            }

            this.items.forEach((n) => {
                if (unreadIds.includes(n.id)) n.read_at = now;
            });
        },

        async archive(id) {
            const { error } = await supabase.from('notifications').update({ archived: true }).eq('id', id);

            if (error) {
                console.error('[notificationStore] archive error:', error.message);
                return;
            }

            this.items = this.items.filter((n) => n.id !== id);
        },

        unsubscribe() {
            if (this._channel) {
                supabase.removeChannel(this._channel);
                this._channel = null;
            }
        }
    }
});
