<script setup>
/*
 * MelissaBusca
 * --------------------------------------------------
 * Busca rápida glass-style. Adaptação do GlobalSearch da topbar
 * (`src/components/search/GlobalSearch.vue`) pro layout Melissa.
 *
 * Diferenças vs. GlobalSearch:
 *  - Não chama Supabase — recebe pacientes/eventos via prop (preview)
 *  - Visual glass (white-on-glass) ao invés de surface-card
 *  - Sem loading state (busca client-side, instantâneo)
 *  - Emite ações pro parent decidir o que fazer
 *
 * Quando promover pra produção: trocar a busca por chamada à RPC
 * `search_global` + manter a mesma estrutura de panel/items.
 */
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue';
import { supabase } from '@/lib/supabase/client';
import { useRecentPatients } from '@/composables/useRecentPatients';

const props = defineProps({
    pacientes: { type: Array, default: () => [] },
    eventos: { type: Array, default: () => [] },
    atalhos: {
        type: Array,
        default: () => [
            { id: 'agenda', label: 'Agenda', icon: 'pi pi-calendar', sublabel: 'Sessões e compromissos', keywords: ['agenda', 'calendario', 'sessoes', 'hoje'] },
            { id: 'pacientes', label: 'Pacientes', icon: 'pi pi-users', sublabel: 'Cadastro e prontuários', keywords: ['pacientes', 'lista', 'cadastro'] },
            { id: 'conversas', label: 'WhatsApp', icon: 'pi pi-whatsapp', sublabel: 'Conversas em andamento', keywords: ['whatsapp', 'conversas', 'mensagens', 'chat'] },
            { id: 'financeiro', label: 'Financeiro', icon: 'pi pi-wallet', sublabel: 'Recebíveis e lançamentos', keywords: ['financeiro', 'pagamentos', 'cobrancas', 'dinheiro'] },
            { id: 'configuracoes', label: 'Configurações', icon: 'pi pi-cog', sublabel: 'Preferências e equipe', keywords: ['configuracoes', 'ajustes', 'preferencias', 'settings'] }
        ]
    }
});

const emit = defineEmits(['acao', 'paciente', 'evento', 'documento', 'intake']);

const rootEl = ref(null);
const inputEl = ref(null);
const query = ref('');
const showPanel = ref(false);
const activeIndex = ref(-1);

// RPC search_global results — preenchidos por debounce conforme o usuário digita.
// Cliente-side (props.pacientes / props.eventos) continua sendo fallback rápido
// pra digitação curta (1 char) e como complemento aos primeiros resultados.
const rpcResults = ref({ patients: [], appointments: [], documents: [], services: [], intakes: [] });
const searching = ref(false);
let debounceT = null;
let searchSeq = 0;

// Recently viewed (localStorage) — só aparece quando o input está vazio
const { items: recentPatients, hasItems: hasRecentPatients } = useRecentPatients();
const showRecent = computed(() => !query.value.trim() && hasRecentPatients.value);
const recentItems = computed(() => showRecent.value ? (recentPatients.value || []).slice(0, 5) : []);

function normalize(s) {
    return String(s || '')
        .normalize('NFD')
        .replace(/[̀-ͯ]/g, '')
        .toLowerCase()
        .trim();
}

function fmtHora(h) {
    const horas = Math.floor(h);
    const mins = Math.round((h - horas) * 60);
    return `${String(horas).padStart(2, '0')}:${String(mins).padStart(2, '0')}`;
}

const filteredAtalhos = computed(() => {
    const q = normalize(query.value);
    if (!q) return props.atalhos.slice(0, 4); // 4 defaults quando vazio
    return props.atalhos.filter((a) => {
        const hay = normalize(a.label + ' ' + (a.keywords || []).join(' '));
        return hay.includes(q);
    }).slice(0, 5);
});

// Pacientes — combina RPC (autoritativo, todos os pacientes) com props (preview de hoje).
// RPC tem prioridade; props complementa quando RPC ainda não trouxe nada.
const filteredPacientes = computed(() => {
    const q = normalize(query.value);
    if (q.length < 2) return [];

    const rpc = rpcResults.value.patients || [];
    if (rpc.length) {
        return rpc.slice(0, 5).map(p => ({
            id: p.id,
            nome: p.nome_completo || p.nome_social || p.nome || '(sem nome)',
            email: p.email,
            telefone: p.telefone
        }));
    }
    // Fallback client-side
    return props.pacientes
        .filter((p) => normalize(p.nome).includes(q))
        .slice(0, 5);
});

const filteredEventos = computed(() => {
    const q = normalize(query.value);
    if (q.length < 2) return [];
    return props.eventos
        .filter((e) => {
            const hay = normalize(
                (e.label || '') + ' ' + (e.pacienteNome || '') + ' ' + (e.descricao || '')
            );
            return hay.includes(q);
        })
        .slice(0, 5);
});

// Resultados exclusivos da RPC (não há fallback client-side)
const rpcAppointments = computed(() => rpcResults.value.appointments || []);
const rpcDocuments   = computed(() => rpcResults.value.documents || []);
const rpcIntakes     = computed(() => rpcResults.value.intakes || []);

const flatList = computed(() => {
    const out = [];
    recentItems.value.forEach((p, i) => out.push({ group: 'recent', item: p, idx: i }));
    filteredAtalhos.value.forEach((a, i) => out.push({ group: 'atalhos', item: a, idx: i }));
    filteredPacientes.value.forEach((p, i) => out.push({ group: 'pacientes', item: p, idx: i }));
    filteredEventos.value.forEach((e, i) => out.push({ group: 'eventos', item: e, idx: i }));
    rpcAppointments.value.forEach((a, i) => out.push({ group: 'rpc-appointments', item: a, idx: i }));
    rpcDocuments.value.forEach((d, i) => out.push({ group: 'rpc-documents', item: d, idx: i }));
    rpcIntakes.value.forEach((r, i) => out.push({ group: 'rpc-intakes', item: r, idx: i }));
    return out;
});

const hasAnyResult = computed(() => flatList.value.length > 0);

function findFlatIndex(group, idx) {
    return flatList.value.findIndex((x) => x.group === group && x.idx === idx);
}

function selectEntry(entry) {
    if (entry.group === 'atalhos') emit('acao', entry.item.id);
    else if (entry.group === 'pacientes') emit('paciente', entry.item);
    else if (entry.group === 'recent') emit('paciente', { id: entry.item.id, nome: entry.item.nome, ...entry.item.extras });
    else if (entry.group === 'eventos') emit('evento', entry.item);
    else if (entry.group === 'rpc-appointments') emit('evento', entry.item);
    else if (entry.group === 'rpc-documents') emit('documento', entry.item);
    else if (entry.group === 'rpc-intakes') emit('intake', entry.item);
    closePanel();
}

function closePanel() {
    showPanel.value = false;
    query.value = '';
    activeIndex.value = -1;
    inputEl.value?.blur();
}

function onFocus() {
    showPanel.value = true;
}

function onClickOutside(e) {
    if (rootEl.value && !rootEl.value.contains(e.target)) {
        showPanel.value = false;
        activeIndex.value = -1;
    }
}

function onKeydown(e) {
    if (!showPanel.value) return;
    if (e.key === 'ArrowDown') {
        e.preventDefault();
        activeIndex.value = Math.min(activeIndex.value + 1, flatList.value.length - 1);
    } else if (e.key === 'ArrowUp') {
        e.preventDefault();
        activeIndex.value = Math.max(activeIndex.value - 1, 0);
    } else if (e.key === 'Enter' && activeIndex.value >= 0) {
        e.preventDefault();
        selectEntry(flatList.value[activeIndex.value]);
    } else if (e.key === 'Escape') {
        // Stop bubbling pra ESC do parent não fechar overlay aleatório
        e.stopPropagation();
        closePanel();
    }
}

function onGlobalKeydown(e) {
    // Ctrl+K / ⌘+K → foca input
    if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault();
        showPanel.value = true;
        inputEl.value?.focus();
    }
}

// ── RPC search_global debounced ───────────────────────────────────────────
// Mesmo padrão do GlobalSearch.vue: query >= 2 chars dispara em 200ms,
// controla ordem via searchSeq pra ignorar respostas obsoletas.
function resetRpcResults() {
    rpcResults.value = { patients: [], appointments: [], documents: [], services: [], intakes: [] };
}

watch(query, (v) => {
    if (debounceT) clearTimeout(debounceT);
    const q = String(v || '').trim();
    if (q.length < 2) {
        resetRpcResults();
        searching.value = false;
        return;
    }
    searching.value = true;
    const mySeq = ++searchSeq;
    debounceT = setTimeout(async () => {
        try {
            const { data, error } = await supabase.rpc('search_global', { p_q: q, p_limit: 6 });
            if (mySeq !== searchSeq) return;
            if (error) {
                console.error('[MelissaBusca search_global]', error);
                resetRpcResults();
            } else {
                rpcResults.value = {
                    patients:     Array.isArray(data?.patients)     ? data.patients     : [],
                    appointments: Array.isArray(data?.appointments) ? data.appointments : [],
                    documents:    Array.isArray(data?.documents)    ? data.documents    : [],
                    services:     Array.isArray(data?.services)     ? data.services     : [],
                    intakes:      Array.isArray(data?.intakes)      ? data.intakes      : []
                };
            }
        } catch (e) {
            if (mySeq !== searchSeq) return;
            console.error('[MelissaBusca search_global exception]', e);
            resetRpcResults();
        } finally {
            if (mySeq === searchSeq) searching.value = false;
        }
    }, 200);
});

onMounted(() => {
    document.addEventListener('mousedown', onClickOutside);
    window.addEventListener('keydown', onGlobalKeydown);
});
onBeforeUnmount(() => {
    document.removeEventListener('mousedown', onClickOutside);
    window.removeEventListener('keydown', onGlobalKeydown);
    if (debounceT) clearTimeout(debounceT);
});
</script>

<template>
    <div ref="rootEl" class="mb-search">
        <div class="mb-field">
            <i class="pi pi-search mb-field__icon" />
            <input
                ref="inputEl"
                v-model="query"
                type="text"
                placeholder="Buscar paciente, agenda, atalho…"
                class="mb-field__input"
                @focus="onFocus"
                @keydown="onKeydown"
            />
            <span class="mb-field__kbd" aria-hidden="true">Ctrl K</span>
        </div>

        <Transition name="mb-fade">
            <div v-if="showPanel" class="mb-panel" role="listbox">
                <div
                    v-if="query.trim().length >= 2 && !hasAnyResult"
                    class="mb-empty"
                >
                    Nada encontrado pra "<span class="text-white/80">{{ query.trim() }}</span>"
                </div>

                <!-- Acessados recentemente (só quando query vazia) -->
                <div v-if="showRecent" class="mb-group">
                    <div class="mb-group__title">Acessados recentemente</div>
                    <button
                        v-for="(p, i) in recentItems"
                        :key="'mr-' + p.id"
                        class="mb-item"
                        :class="{ 'is-active': findFlatIndex('recent', i) === activeIndex }"
                        @click="selectEntry({ group: 'recent', item: p })"
                        @mouseenter="activeIndex = findFlatIndex('recent', i)"
                    >
                        <span class="mb-item__icon"><i class="pi pi-history" /></span>
                        <span class="mb-item__main">
                            <span class="mb-item__label">{{ p.nome }}</span>
                            <span class="mb-item__sub">{{ p.extras?.telefone || p.extras?.email || 'Abrir prontuário' }}</span>
                        </span>
                        <i class="mb-item__go pi pi-arrow-right" />
                    </button>
                </div>

                <!-- Atalhos -->
                <div v-if="filteredAtalhos.length" class="mb-group">
                    <div class="mb-group__title">{{ query.trim() ? 'Ações' : 'Atalhos' }}</div>
                    <button
                        v-for="(a, i) in filteredAtalhos"
                        :key="'a-' + a.id"
                        class="mb-item"
                        :class="{ 'is-active': findFlatIndex('atalhos', i) === activeIndex }"
                        @click="selectEntry({ group: 'atalhos', item: a })"
                        @mouseenter="activeIndex = findFlatIndex('atalhos', i)"
                    >
                        <span class="mb-item__icon"><i :class="a.icon" /></span>
                        <span class="mb-item__main">
                            <span class="mb-item__label">{{ a.label }}</span>
                            <span v-if="a.sublabel" class="mb-item__sub">{{ a.sublabel }}</span>
                        </span>
                        <i class="mb-item__go pi pi-arrow-right" />
                    </button>
                </div>

                <!-- Pacientes -->
                <div v-if="filteredPacientes.length" class="mb-group">
                    <div class="mb-group__title">Pacientes</div>
                    <button
                        v-for="(p, i) in filteredPacientes"
                        :key="'p-' + p.id"
                        class="mb-item"
                        :class="{ 'is-active': findFlatIndex('pacientes', i) === activeIndex }"
                        @click="selectEntry({ group: 'pacientes', item: p })"
                        @mouseenter="activeIndex = findFlatIndex('pacientes', i)"
                    >
                        <span class="mb-item__icon"><i class="pi pi-user" /></span>
                        <span class="mb-item__main">
                            <span class="mb-item__label">{{ p.nome }}</span>
                            <span class="mb-item__sub">Abrir prontuário</span>
                        </span>
                        <i class="mb-item__go pi pi-arrow-right" />
                    </button>
                </div>

                <!-- Eventos -->
                <div v-if="filteredEventos.length" class="mb-group">
                    <div class="mb-group__title">Agenda de hoje</div>
                    <button
                        v-for="(e, i) in filteredEventos"
                        :key="'e-' + e.id"
                        class="mb-item"
                        :class="{ 'is-active': findFlatIndex('eventos', i) === activeIndex }"
                        @click="selectEntry({ group: 'eventos', item: e })"
                        @mouseenter="activeIndex = findFlatIndex('eventos', i)"
                    >
                        <span
                            class="mb-item__icon"
                            :style="{ backgroundColor: `${e.color}33`, color: e.color }"
                        >
                            <i class="pi pi-clock" />
                        </span>
                        <span class="mb-item__main">
                            <span class="mb-item__label">{{ e.label }}</span>
                            <span class="mb-item__sub">{{ fmtHora(e.startH) }} – {{ fmtHora(e.endH) }}</span>
                        </span>
                        <i class="mb-item__go pi pi-arrow-right" />
                    </button>
                </div>

                <!-- RPC: Sessões/agendamentos (qualquer data) -->
                <div v-if="rpcAppointments.length" class="mb-group">
                    <div class="mb-group__title">Sessões</div>
                    <button
                        v-for="(e, i) in rpcAppointments"
                        :key="'rpc-a-' + e.id"
                        class="mb-item"
                        :class="{ 'is-active': findFlatIndex('rpc-appointments', i) === activeIndex }"
                        @click="selectEntry({ group: 'rpc-appointments', item: e })"
                        @mouseenter="activeIndex = findFlatIndex('rpc-appointments', i)"
                    >
                        <span class="mb-item__icon"><i class="pi pi-calendar" /></span>
                        <span class="mb-item__main">
                            <span class="mb-item__label">{{ e.paciente_nome || e.title || 'Sessão' }}</span>
                            <span class="mb-item__sub">{{ e.inicio_em ? new Date(e.inicio_em).toLocaleDateString('pt-BR') + ' ' + new Date(e.inicio_em).toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' }) : 'Sem data' }}</span>
                        </span>
                        <i class="mb-item__go pi pi-arrow-right" />
                    </button>
                </div>

                <!-- RPC: Documentos -->
                <div v-if="rpcDocuments.length" class="mb-group">
                    <div class="mb-group__title">Documentos</div>
                    <button
                        v-for="(d, i) in rpcDocuments"
                        :key="'rpc-d-' + d.id"
                        class="mb-item"
                        :class="{ 'is-active': findFlatIndex('rpc-documents', i) === activeIndex }"
                        @click="selectEntry({ group: 'rpc-documents', item: d })"
                        @mouseenter="activeIndex = findFlatIndex('rpc-documents', i)"
                    >
                        <span class="mb-item__icon"><i class="pi pi-file" /></span>
                        <span class="mb-item__main">
                            <span class="mb-item__label">{{ d.nome_original || 'Documento' }}</span>
                            <span class="mb-item__sub">{{ d.paciente_nome ? `${d.paciente_nome} · ` : '' }}{{ d.tipo_documento || 'outro' }}</span>
                        </span>
                        <i class="mb-item__go pi pi-arrow-right" />
                    </button>
                </div>

                <!-- RPC: Cadastros recebidos (intakes) -->
                <div v-if="rpcIntakes.length" class="mb-group">
                    <div class="mb-group__title">Cadastros recebidos</div>
                    <button
                        v-for="(r, i) in rpcIntakes"
                        :key="'rpc-i-' + r.id"
                        class="mb-item"
                        :class="{ 'is-active': findFlatIndex('rpc-intakes', i) === activeIndex }"
                        @click="selectEntry({ group: 'rpc-intakes', item: r })"
                        @mouseenter="activeIndex = findFlatIndex('rpc-intakes', i)"
                    >
                        <span class="mb-item__icon"><i class="pi pi-inbox" /></span>
                        <span class="mb-item__main">
                            <span class="mb-item__label">{{ r.nome_completo || 'Cadastro' }}</span>
                            <span class="mb-item__sub">{{ r.created_at ? new Date(r.created_at).toLocaleDateString('pt-BR') : '' }}</span>
                        </span>
                        <i class="mb-item__go pi pi-arrow-right" />
                    </button>
                </div>
            </div>
        </Transition>
    </div>
</template>

<style scoped>
.mb-search {
    position: relative;
    width: 100%;
    max-width: 560px;
    /* Só horizontal — top/bottom ficam livres pro parent (mt-X do Tailwind) */
    margin-left: auto;
    margin-right: auto;
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
}

.mb-field {
    position: relative;
    display: flex;
    align-items: center;
    background: var(--m-bg-soft);
    backdrop-filter: blur(20px) saturate(140%);
    -webkit-backdrop-filter: blur(20px) saturate(140%);
    border: 1px solid var(--m-border-strong);
    border-radius: 12px;
    padding: 0 14px;
    height: 44px;
    transition: background-color 160ms ease, border-color 160ms ease;
}
.mb-field:focus-within {
    background: var(--m-bg-soft-hover);
    border-color: var(--m-border-strong);
}
.mb-field__icon {
    color: var(--m-text-muted);
    font-size: 0.95rem;
    margin-right: 10px;
    flex-shrink: 0;
}
.mb-field__input {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: white;
    font-size: 0.9rem;
    font-family: inherit;
    min-width: 0;
}
.mb-field__input::placeholder {
    color: var(--m-text-muted);
}
.mb-field__kbd {
    color: var(--m-text-muted);
    font-size: 0.62rem;
    font-weight: 500;
    padding: 2px 7px;
    border-radius: 4px;
    background: var(--m-bg-soft);
    border: 1px solid var(--m-border-strong);
    margin-left: 8px;
    flex-shrink: 0;
    letter-spacing: 0.05em;
}

.mb-panel {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 30;
    max-height: 60vh;
    overflow-y: auto;
    background: var(--m-bg-medium);
    backdrop-filter: blur(28px) saturate(160%);
    -webkit-backdrop-filter: blur(28px) saturate(160%);
    border: 1px solid var(--m-border-strong);
    border-radius: 12px;
    padding: 6px;
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45);
    scrollbar-width: thin;
    scrollbar-color: var(--m-border-strong) transparent;
}
.mb-panel::-webkit-scrollbar { width: 6px; }
.mb-panel::-webkit-scrollbar-thumb {
    background: var(--m-border-strong);
    border-radius: 3px;
}

.mb-empty {
    padding: 18px 14px;
    text-align: center;
    color: var(--m-text-muted);
    font-size: 0.85rem;
}

.mb-group + .mb-group {
    margin-top: 4px;
    padding-top: 4px;
    border-top: 1px solid var(--m-border);
}
.mb-group__title {
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--m-text-faint);
    font-size: 0.6rem;
    font-weight: 600;
    padding: 8px 10px 4px;
}

.mb-item {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    background: transparent;
    border: none;
    border-radius: 8px;
    color: white;
    text-align: left;
    cursor: pointer;
    font-family: inherit;
    transition: background-color 100ms ease;
}
.mb-item:hover,
.mb-item.is-active {
    background: var(--m-bg-soft);
}
.mb-item__icon {
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    background: var(--m-bg-soft);
    border-radius: 7px;
    color: var(--m-text-muted);
    flex-shrink: 0;
    font-size: 0.85rem;
}
.mb-item__main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.mb-item__label {
    font-size: 0.85rem;
    color: white;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mb-item__sub {
    font-size: 0.7rem;
    color: var(--m-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mb-item__go {
    color: var(--m-text-faint);
    font-size: 0.7rem;
    flex-shrink: 0;
}

.mb-fade-enter-active,
.mb-fade-leave-active {
    transition: opacity 140ms ease, transform 160ms ease;
}
.mb-fade-enter-from,
.mb-fade-leave-to {
    opacity: 0;
    transform: translateY(-6px);
}
</style>
