<script setup>
import { ref, computed, onMounted, onBeforeUnmount } from 'vue';
import { useRouter } from 'vue-router';
import { useToast } from 'primevue/usetoast';
import { useConfirm } from 'primevue/useconfirm';
import { formatDistanceToNow, format } from 'date-fns';
import { ptBR } from 'date-fns/locale';
import { supabase } from '@/lib/supabase/client';
import { tenantDb } from '@/lib/supabase/tenantClient';
import { useNotificationStore } from '@/stores/notificationStore';
import { useConversationDrawerStore } from '@/stores/conversationDrawerStore';
import { useTenantStore } from '@/stores/tenantStore';

const router = useRouter();
const toast = useToast();
const confirm = useConfirm();
const notifStore = useNotificationStore();
const conversationDrawer = useConversationDrawerStore();
const tenantStore = useTenantStore();

// ─── State ───────────────────────────────────────────
const ownerId = ref(null);
const items = ref([]);
const loading = ref(true);
const search = ref('');
const filter = ref('all'); // all | unread | read | archived
const typeFilter = ref(null);

const headerEl = ref(null);
const headerSentinelRef = ref(null);
const headerStuck = ref(false);
let _headerObserver = null;

// ─── Type map ────────────────────────────────────────
const typeMap = {
    new_scheduling: { icon: 'pi-inbox', color: 'text-red-500', border: 'border-red-500', label: 'Agendamento' },
    new_patient: { icon: 'pi-user-plus', color: 'text-sky-500', border: 'border-sky-500', label: 'Novo paciente' },
    recurrence_alert: { icon: 'pi-refresh', color: 'text-amber-500', border: 'border-amber-500', label: 'Recorrência' },
    session_status: { icon: 'pi-calendar-times', color: 'text-orange-500', border: 'border-orange-500', label: 'Sessão' },
    inbound_message: { icon: 'pi-whatsapp', color: 'text-emerald-500', border: 'border-emerald-500', label: 'Mensagem' }
};

function metaFor(item) {
    return typeMap[item.type] || { icon: 'pi-bell', color: 'text-gray-400', border: 'border-gray-300', label: item.type };
}

// ─── Filters + search ────────────────────────────────
const quickStats = computed(() => {
    const total = items.value.length;
    const unread = items.value.filter((n) => !n.read_at && !n.archived).length;
    const read = items.value.filter((n) => n.read_at && !n.archived).length;
    const archived = items.value.filter((n) => n.archived).length;
    return [
        { label: 'Total', value: total, key: 'all', cls: '' },
        { label: 'Não lidas', value: unread, key: 'unread', cls: unread > 0 ? 'qs-warn' : '' },
        { label: 'Lidas', value: read, key: 'read', cls: '' },
        { label: 'Arquivadas', value: archived, key: 'archived', cls: '' }
    ];
});

const filteredItems = computed(() => {
    const q = search.value.trim().toLowerCase();
    return items.value.filter((n) => {
        if (filter.value === 'unread' && (n.read_at || n.archived)) return false;
        if (filter.value === 'read' && (!n.read_at || n.archived)) return false;
        if (filter.value === 'archived' && !n.archived) return false;
        if (filter.value === 'all' && n.archived) return false;
        if (typeFilter.value && n.type !== typeFilter.value) return false;
        if (q) {
            const title = (n.payload?.title || '').toLowerCase();
            const detail = (n.payload?.detail || '').toLowerCase();
            if (!title.includes(q) && !detail.includes(q)) return false;
        }
        return true;
    });
});

const hasActiveFilters = computed(() => filter.value !== 'all' || !!typeFilter.value || !!search.value.trim());

function clearFilters() {
    filter.value = 'all';
    typeFilter.value = null;
    search.value = '';
}

// ─── Data loading ────────────────────────────────────
async function load() {
    loading.value = true;
    try {
        const { data: authData } = await supabase.auth.getUser();
        ownerId.value = authData?.user?.id || null;
        if (!ownerId.value) {
            loading.value = false;
            return;
        }
        const { data, error } = await tenantDb().from('notifications').select('*').eq('owner_id', ownerId.value).order('created_at', { ascending: false }).limit(500);
        if (error) throw error;
        items.value = data || [];
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro', detail: e?.message || 'Falha ao carregar notificações.', life: 4500 });
    } finally {
        loading.value = false;
    }
}

// ─── Actions ─────────────────────────────────────────
async function markRead(id) {
    const now = new Date().toISOString();
    const { error } = await tenantDb().from('notifications').update({ read_at: now }).eq('id', id);
    if (error) {
        toast.add({ severity: 'error', summary: 'Erro', detail: error.message, life: 3500 });
        return;
    }
    const item = items.value.find((n) => n.id === id);
    if (item) item.read_at = now;
    // Sync no store (drawer)
    const storeItem = notifStore.items.find((n) => n.id === id);
    if (storeItem) storeItem.read_at = now;
}

async function markUnread(id) {
    const { error } = await tenantDb().from('notifications').update({ read_at: null }).eq('id', id);
    if (error) {
        toast.add({ severity: 'error', summary: 'Erro', detail: error.message, life: 3500 });
        return;
    }
    const item = items.value.find((n) => n.id === id);
    if (item) item.read_at = null;
    const storeItem = notifStore.items.find((n) => n.id === id);
    if (storeItem) storeItem.read_at = null;
}

async function archive(id) {
    const { error } = await tenantDb().from('notifications').update({ archived: true }).eq('id', id);
    if (error) {
        toast.add({ severity: 'error', summary: 'Erro', detail: error.message, life: 3500 });
        return;
    }
    const item = items.value.find((n) => n.id === id);
    if (item) item.archived = true;
    // Remove do store do drawer (que só lista não-arquivadas)
    notifStore.items = notifStore.items.filter((n) => n.id !== id);
}

async function unarchive(id) {
    const { error } = await tenantDb().from('notifications').update({ archived: false }).eq('id', id);
    if (error) {
        toast.add({ severity: 'error', summary: 'Erro', detail: error.message, life: 3500 });
        return;
    }
    const item = items.value.find((n) => n.id === id);
    if (item) item.archived = false;
    // Readiciona no store do drawer
    if (item && !notifStore.items.find((n) => n.id === id)) {
        notifStore.items.unshift({ ...item });
    }
}

function confirmRemove(id) {
    confirm.require({
        message: 'Remover esta notificação permanentemente? Essa ação não pode ser desfeita.',
        header: 'Remover notificação',
        icon: 'pi pi-exclamation-triangle',
        acceptLabel: 'Remover',
        rejectLabel: 'Cancelar',
        acceptClass: 'p-button-danger',
        accept: () => remove(id)
    });
}

async function remove(id) {
    const { error } = await tenantDb().from('notifications').delete().eq('id', id);
    if (error) {
        toast.add({ severity: 'error', summary: 'Erro', detail: error.message, life: 3500 });
        return;
    }
    items.value = items.value.filter((n) => n.id !== id);
    notifStore.items = notifStore.items.filter((n) => n.id !== id);
    toast.add({ severity: 'success', summary: 'Removida', life: 2500 });
}

async function markAllRead() {
    const unreadIds = items.value.filter((n) => !n.read_at && !n.archived).map((n) => n.id);
    if (!unreadIds.length) return;
    const now = new Date().toISOString();
    const { error } = await tenantDb().from('notifications').update({ read_at: now }).in('id', unreadIds);
    if (error) {
        toast.add({ severity: 'error', summary: 'Erro', detail: error.message, life: 3500 });
        return;
    }
    items.value.forEach((n) => {
        if (unreadIds.includes(n.id)) n.read_at = now;
    });
    notifStore.items.forEach((n) => {
        if (unreadIds.includes(n.id)) n.read_at = now;
    });
    toast.add({ severity: 'success', summary: `${unreadIds.length} marcada${unreadIds.length > 1 ? 's' : ''} como lida${unreadIds.length > 1 ? 's' : ''}`, life: 2500 });
}

// ─── Row actions ─────────────────────────────────────
function handleRowClick(n) {
    if (n.type === 'inbound_message') {
        const payload = n.payload || {};
        if (payload.patient_id) {
            conversationDrawer.openForPatient(payload.patient_id);
        } else if (payload.from_number) {
            conversationDrawer.openForThread({
                thread_key: `anon:${payload.from_number}`,
                tenant_id: tenantStore.activeTenantId,
                patient_id: null,
                patient_name: null,
                contact_number: payload.from_number,
                channel: payload.channel || 'whatsapp',
                message_count: 1,
                unread_count: 1,
                kanban_status: 'awaiting_us',
                last_message_at: new Date().toISOString()
            });
        }
        if (!n.read_at) markRead(n.id);
        return;
    }
    const deeplink = n.payload?.deeplink;
    if (deeplink) {
        if (!n.read_at) markRead(n.id);
        router.push(deeplink);
    } else if (!n.read_at) {
        markRead(n.id);
    }
}

// ─── Helpers ─────────────────────────────────────────
function timeAgo(iso) {
    try {
        return formatDistanceToNow(new Date(iso), { addSuffix: true, locale: ptBR });
    } catch {
        return '—';
    }
}

function fullDate(iso) {
    try {
        return format(new Date(iso), "dd 'de' MMMM 'às' HH:mm", { locale: ptBR });
    } catch {
        return '';
    }
}

function initials(item) {
    return item.payload?.avatar_initials || '?';
}

// ─── Lifecycle ───────────────────────────────────────
onMounted(() => {
    load();
    if (headerSentinelRef.value) {
        _headerObserver = new IntersectionObserver(
            ([entry]) => {
                headerStuck.value = !entry.isIntersecting;
            },
            { threshold: 0 }
        );
        _headerObserver.observe(headerSentinelRef.value);
    }
});

onBeforeUnmount(() => {
    _headerObserver?.disconnect();
});
</script>

<template>
    <ConfirmDialog />

    <!-- Sentinel -->
    <div ref="headerSentinelRef" class="h-px" />

    <!-- Hero sticky -->
    <section
        ref="headerEl"
        class="sticky mx-3 md:mx-4 my-3 z-20 overflow-hidden rounded-md border border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)] px-3 py-2.5 transition-[border-radius] duration-200"
        :class="{ 'rounded-tl-none rounded-tr-none': headerStuck }"
        :style="{ top: 'var(--layout-sticky-top, 56px)' }"
    >
        <!-- Blobs decorativos -->
        <div class="absolute inset-0 pointer-events-none overflow-hidden" aria-hidden="true">
            <div class="absolute w-64 h-64 -top-16 -right-8 rounded-full blur-[60px] bg-indigo-500/10" />
            <div class="absolute w-72 h-72 top-0 -left-16 rounded-full blur-[60px] bg-emerald-400/[0.07]" />
        </div>

        <div class="relative z-1 flex items-center gap-3">
            <div class="flex items-center gap-2 shrink-0">
                <div class="grid place-items-center w-9 h-9 rounded-md shrink-0 bg-indigo-500/10 text-indigo-500">
                    <i class="pi pi-bell text-base" />
                </div>
                <div class="min-w-0 hidden lg:block">
                    <div class="text-[1rem] font-bold tracking-tight text-[var(--text-color)]">Notificações</div>
                    <div class="text-[1rem] text-[var(--text-color-secondary)]">Histórico completo — leia, arquive ou remova</div>
                </div>
            </div>

            <div class="flex items-center gap-1 shrink-0 ml-auto">
                <Button
                    v-if="quickStats[1].value > 0"
                    label="Marcar todas lidas"
                    icon="pi pi-check-circle"
                    severity="secondary"
                    outlined
                    size="small"
                    class="rounded-full"
                    :disabled="loading"
                    @click="markAllRead"
                />
                <Button icon="pi pi-refresh" severity="secondary" outlined class="h-9 w-9 rounded-full" :loading="loading" v-tooltip.bottom="'Recarregar'" @click="load" />
            </div>
        </div>
    </section>

    <!-- Quick-stats -->
    <div class="grid grid-cols-2 md:grid-cols-4 gap-2 px-3 md:px-4 mb-3">
        <template v-if="loading">
            <Skeleton v-for="n in 4" :key="n" height="3.5rem" class="rounded-md" />
        </template>
        <template v-else>
            <div
                v-for="s in quickStats"
                :key="s.key"
                class="flex flex-col gap-0.5 px-4 py-2.5 rounded-md border cursor-pointer select-none transition-[border-color,box-shadow,background] duration-150 hover:shadow-[0_2px_8px_rgba(0,0,0,0.06)]"
                :class="[
                    filter === s.key
                        ? 'border-[var(--primary-color,#6366f1)] shadow-[0_0_0_3px_rgba(99,102,241,0.15)] bg-[var(--surface-card,#fff)]'
                        : s.cls === 'qs-warn'
                          ? 'border-amber-500/25 bg-amber-500/5 hover:border-amber-500/40'
                          : 'border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)] hover:border-indigo-300/50'
                ]"
                @click="filter = s.key"
            >
                <div class="text-[1.35rem] font-bold leading-none" :class="s.cls === 'qs-warn' ? 'text-amber-500' : 'text-[var(--text-color)]'">{{ s.value }}</div>
                <div class="text-[1rem] text-[var(--text-color-secondary)] opacity-75 truncate">{{ s.label }}</div>
            </div>
        </template>
    </div>

    <!-- Toolbar: busca + type filter + clear -->
    <div class="px-3 md:px-4 mb-3 flex flex-col md:flex-row items-stretch md:items-center gap-2">
        <IconField class="flex-1">
            <InputIcon class="pi pi-search" />
            <InputText v-model="search" placeholder="Buscar por título ou descrição…" class="w-full" />
        </IconField>

        <Select
            v-model="typeFilter"
            :options="[
                { label: 'Todos os tipos', value: null },
                { label: 'Agendamento', value: 'new_scheduling' },
                { label: 'Novo paciente', value: 'new_patient' },
                { label: 'Recorrência', value: 'recurrence_alert' },
                { label: 'Sessão', value: 'session_status' },
                { label: 'Mensagem', value: 'inbound_message' }
            ]"
            optionLabel="label"
            optionValue="value"
            placeholder="Tipo"
            class="md:w-[200px]"
        />

        <Button v-if="hasActiveFilters" label="Limpar filtros" icon="pi pi-filter-slash" severity="secondary" outlined size="small" class="rounded-full" @click="clearFilters" />
    </div>

    <!-- Lista -->
    <div class="px-3 md:px-4 pb-5">
        <!-- Skeleton list -->
        <div v-if="loading" class="flex flex-col gap-2">
            <Skeleton v-for="n in 8" :key="n" height="5rem" class="rounded-md" />
        </div>

        <!-- Empty -->
        <div v-else-if="!filteredItems.length" class="flex flex-col items-center justify-center gap-2 py-12 text-center">
            <i class="pi pi-bell-slash text-4xl text-[var(--text-color-secondary)] opacity-40" />
            <div class="text-[1rem] font-semibold text-[var(--text-color)]">{{ hasActiveFilters ? 'Nada encontrado' : 'Nenhuma notificação ainda' }}</div>
            <div class="text-sm text-[var(--text-color-secondary)]">{{ hasActiveFilters ? 'Ajuste os filtros ou limpe-os para ver tudo.' : 'Quando algo acontecer, você será avisado aqui.' }}</div>
        </div>

        <!-- Items -->
        <div v-else class="flex flex-col gap-2">
            <div
                v-for="n in filteredItems"
                :key="n.id"
                class="notif-row"
                :class="[metaFor(n).border, !n.read_at && !n.archived ? 'notif-row--unread' : '', n.archived ? 'notif-row--archived' : '']"
                role="button"
                tabindex="0"
                @click="handleRowClick(n)"
                @keydown.enter="handleRowClick(n)"
            >
                <div class="notif-row__icon" :class="metaFor(n).color">
                    <i :class="['pi', metaFor(n).icon]" />
                </div>

                <div class="notif-row__avatar">{{ initials(n) }}</div>

                <div class="notif-row__body">
                    <div class="flex items-center gap-2 flex-wrap">
                        <span class="notif-row__title">{{ n.payload?.title || '(sem título)' }}</span>
                        <span class="notif-row__type-pill">{{ metaFor(n).label }}</span>
                        <span v-if="n.archived" class="notif-row__type-pill notif-row__type-pill--muted">Arquivada</span>
                    </div>
                    <div class="notif-row__detail">{{ n.payload?.detail || '—' }}</div>
                    <div class="notif-row__time" :title="fullDate(n.created_at)">{{ timeAgo(n.created_at) }}</div>
                </div>

                <div class="notif-row__actions" @click.stop>
                    <button v-if="!n.read_at && !n.archived" class="notif-row__btn" v-tooltip.top="'Marcar como lida'" @click="markRead(n.id)">
                        <i class="pi pi-check" />
                    </button>
                    <button v-else-if="n.read_at && !n.archived" class="notif-row__btn" v-tooltip.top="'Marcar como não lida'" @click="markUnread(n.id)">
                        <i class="pi pi-envelope" />
                    </button>
                    <button v-if="!n.archived" class="notif-row__btn" v-tooltip.top="'Arquivar'" @click="archive(n.id)">
                        <i class="pi pi-inbox" />
                    </button>
                    <button v-else class="notif-row__btn" v-tooltip.top="'Desarquivar'" @click="unarchive(n.id)">
                        <i class="pi pi-undo" />
                    </button>
                    <button class="notif-row__btn notif-row__btn--danger" v-tooltip.top="'Remover'" @click="confirmRemove(n.id)">
                        <i class="pi pi-trash" />
                    </button>
                </div>
            </div>
        </div>
    </div>
</template>

<style scoped>
.notif-row {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.875rem 1rem;
    border-left-width: 3px;
    border-left-style: solid;
    border-top: 1px solid var(--surface-border);
    border-right: 1px solid var(--surface-border);
    border-bottom: 1px solid var(--surface-border);
    border-radius: 6px;
    background: var(--surface-card);
    cursor: pointer;
    transition:
        background 0.15s,
        box-shadow 0.15s,
        border-color 0.15s;
}
.notif-row:hover {
    background: var(--surface-hover);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.notif-row--unread {
    background: color-mix(in srgb, var(--primary-color) 5%, var(--surface-card));
}
.notif-row--unread:hover {
    background: color-mix(in srgb, var(--primary-color) 8%, var(--surface-card));
}
.notif-row--archived {
    opacity: 0.7;
}

.notif-row__icon {
    flex-shrink: 0;
    padding-top: 0.2rem;
    font-size: 1rem;
}

.notif-row__avatar {
    flex-shrink: 0;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    background: linear-gradient(135deg, #6366f1, #38bdf8);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    display: flex;
    align-items: center;
    justify-content: center;
}

.notif-row__body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}
.notif-row__title {
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--text-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}
.notif-row__type-pill {
    display: inline-flex;
    align-items: center;
    padding: 1px 8px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--text-color) 6%, transparent);
    color: var(--text-color-secondary);
    font-size: 0.65rem;
    font-weight: 600;
    white-space: nowrap;
}
.notif-row__type-pill--muted {
    background: color-mix(in srgb, var(--text-color-secondary) 12%, transparent);
}
.notif-row__detail {
    font-size: 0.82rem;
    color: var(--text-color-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    max-width: 100%;
}
.notif-row__time {
    font-size: 0.72rem;
    color: var(--text-color-secondary);
    opacity: 0.7;
}

.notif-row__actions {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex-shrink: 0;
    opacity: 0.4;
    transition: opacity 0.15s;
}
.notif-row:hover .notif-row__actions,
.notif-row:focus-within .notif-row__actions {
    opacity: 1;
}

.notif-row__btn {
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    border: none;
    background: transparent;
    color: var(--text-color-secondary);
    display: grid;
    place-items: center;
    cursor: pointer;
    font-size: 0.82rem;
    transition:
        background 0.15s,
        color 0.15s;
}
.notif-row__btn:hover {
    background: var(--surface-border);
    color: var(--text-color);
}
.notif-row__btn--danger:hover {
    background: color-mix(in srgb, #ef4444 12%, transparent);
    color: #ef4444;
}
</style>
