<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/layout/ConfiguracoesPage.vue
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
-->
<script setup>
import { computed, ref, watch, onMounted, onBeforeUnmount } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useLayout } from '@/layout/composables/layout';

const route = useRoute();
const router = useRouter();

const showMenu = ref(false);
const asideOpen = ref(false);

// ── Layout-aware left position (igual ao TherapistDashboard) ──────────────
const { effectiveVariant, layoutState, layoutConfig, isMobile, railPanelPushesLayout } = useLayout();
const isMobileLayout = computed(() => isMobile.value);
const asideLeft = computed(() => {
    if (isMobileLayout.value) return undefined;
    if (effectiveVariant.value !== 'rail') {
        const isStaticActive = layoutConfig.menuMode === 'static' && !layoutState.staticMenuInactive;
        return isStaticActive ? '20rem' : '0';
    }
    return railPanelPushesLayout.value ? 'calc(60px + 260px)' : '60px';
});

// ── Hero sticky ────────────────────────────────────────────
const headerEl = ref(null);
const headerSentinelRef = ref(null);
const headerStuck = ref(false);
let _observer = null;

const grupos = [
    {
        key: 'agenda',
        label: 'Agenda',
        desc: 'Horários, bloqueios e agendador público para pacientes.',
        icon: 'pi pi-calendar',
        items: [
            {
                key: 'agenda',
                label: 'Agenda',
                desc: 'Horários semanais, exceções, duração e intervalo padrão.',
                icon: 'pi pi-calendar',
                to: '/configuracoes/agenda'
            },
            {
                key: 'bloqueios',
                label: 'Bloqueios',
                desc: 'Feriados nacionais, municipais e períodos bloqueados.',
                icon: 'pi pi-ban',
                to: '/configuracoes/bloqueios'
            },
            {
                key: 'agendador',
                label: 'Agendador Online',
                desc: 'Link público para pacientes solicitarem horários.',
                icon: 'pi pi-calendar-clock',
                to: '/configuracoes/agendador'
            }
        ]
    },
    {
        key: 'financeiro',
        label: 'Financeiro',
        desc: 'Formas de pagamento, valores, descontos e convênios.',
        icon: 'pi pi-wallet',
        items: [
            {
                key: 'pagamento',
                label: 'Pagamento',
                desc: 'Formas de pagamento: Pix, depósito, dinheiro, cartão, convênio.',
                icon: 'pi pi-wallet',
                to: '/configuracoes/pagamento'
            },
            {
                key: 'precificacao',
                label: 'Precificação',
                desc: 'Valor padrão da sessão e preços por tipo de compromisso.',
                icon: 'pi pi-tag',
                to: '/configuracoes/precificacao'
            },
            {
                key: 'descontos',
                label: 'Descontos por Paciente',
                desc: 'Descontos recorrentes aplicados automaticamente.',
                icon: 'pi pi-percentage',
                to: '/configuracoes/descontos'
            },
            {
                key: 'excecoes-financeiras',
                label: 'Exceções Financeiras',
                desc: 'O que cobrar em faltas, cancelamentos e situações excepcionais.',
                icon: 'pi pi-exclamation-triangle',
                to: '/configuracoes/excecoes-financeiras'
            },
            {
                key: 'convenios',
                label: 'Convênios',
                desc: 'Cadastre os convênios que você atende e seus valores.',
                icon: 'pi pi-id-card',
                to: '/configuracoes/convenios'
            }
        ]
    },
    {
        key: 'whatsapp',
        label: 'WhatsApp & Conversas',
        desc: 'Canal, tags, auto-reply, lembretes e créditos de mensagens.',
        icon: 'pi pi-whatsapp',
        items: [
            {
                key: 'whatsapp',
                label: 'Canal WhatsApp',
                desc: 'Escolha o canal (oficial AgenciaPSI ou pessoal) e configure a integração.',
                icon: 'pi pi-whatsapp',
                to: '/configuracoes/whatsapp',
                aliases: ['/configuracoes/whatsapp-pessoal', '/configuracoes/whatsapp-oficial']
            },
            {
                key: 'whatsapp-templates',
                label: 'Templates WhatsApp',
                desc: 'Personalize os textos enviados por WhatsApp ou volte ao padrão da plataforma.',
                icon: 'pi pi-file-edit',
                to: '/configuracoes/whatsapp-templates'
            },
            {
                key: 'conversas-tags',
                label: 'Tags de Conversa',
                desc: 'Etiquetas custom pra classificar threads no CRM (urgente, remarcação, etc).',
                icon: 'pi pi-tag',
                to: '/configuracoes/conversas-tags'
            },
            {
                key: 'conversas-autoreply',
                label: 'Auto-reply WhatsApp',
                desc: 'Resposta automática quando paciente escreve fora do horário de atendimento.',
                icon: 'pi pi-reply',
                to: '/configuracoes/conversas-autoreply'
            },
            {
                key: 'conversas-optouts',
                label: 'Opt-outs (LGPD)',
                desc: 'Números que pediram pra não receber mensagens automáticas. Direito de oposição LGPD.',
                icon: 'pi pi-ban',
                to: '/configuracoes/conversas-optouts'
            },
            {
                key: 'conversas-sla',
                label: 'SLA de resposta',
                desc: 'Tempo máximo pra responder mensagens de pacientes. Alerta quando estourar.',
                icon: 'pi pi-stopwatch',
                to: '/configuracoes/conversas-sla'
            },
            {
                key: 'conversas-bots',
                label: 'Bot de triagem',
                desc: 'Coleta nome e motivo do paciente via WhatsApp antes de entrar no fluxo humano.',
                icon: 'pi pi-android',
                to: '/configuracoes/conversas-bots'
            },
            {
                key: 'lembretes-sessao',
                label: 'Lembretes de Sessão',
                desc: 'WhatsApp automático 24h e 2h antes das sessões agendadas.',
                icon: 'pi pi-bell',
                to: '/configuracoes/lembretes-sessao'
            },
            {
                key: 'creditos-whatsapp',
                label: 'Créditos WhatsApp',
                desc: 'Compre pacotes de mensagens, veja saldo e extrato.',
                icon: 'pi pi-credit-card',
                to: '/configuracoes/creditos-whatsapp'
            }
        ]
    },
    {
        key: 'comunicacao',
        label: 'Comunicação',
        desc: 'SMS e templates de e-mail enviados aos pacientes.',
        icon: 'pi pi-send',
        items: [
            {
                key: 'sms',
                label: 'SMS',
                desc: 'Gerencie créditos SMS e personalize as mensagens enviadas.',
                icon: 'pi pi-comment',
                to: '/configuracoes/sms'
            },
            {
                key: 'email-templates',
                label: 'Templates de E-mail',
                desc: 'Personalize os e-mails enviados aos pacientes.',
                icon: 'pi pi-envelope',
                to: '/configuracoes/email-templates'
            }
        ]
    },
    {
        key: 'documentos',
        label: 'Documentos',
        desc: 'Modelos e geração de recibos, atestados, laudos, TCLE e LGPD.',
        icon: 'pi pi-file',
        items: [
            {
                key: 'documentos-templates',
                label: 'Modelos de documentos',
                desc: 'Cadastre e edite templates de recibos, atestados, laudos, TCLE, LGPD e mais.',
                icon: 'pi pi-file-edit',
                to: '/configuracoes/documentos/templates'
            }
        ]
    },
    {
        key: 'plataforma',
        label: 'Empresa & Plataforma',
        desc: 'Dados da empresa, recursos extras e registro de auditoria.',
        icon: 'pi pi-building',
        items: [
            {
                key: 'empresa',
                label: 'Minha Empresa',
                desc: 'CNPJ, endereço, logomarca e redes sociais.',
                icon: 'pi pi-building',
                to: '/configuracoes/empresa'
            },
            {
                key: 'recursos-extras',
                label: 'Recursos Extras',
                desc: 'Amplíe as funcionalidades com recursos adicionais e créditos.',
                icon: 'pi pi-box',
                to: '/configuracoes/recursos-extras'
            },
            {
                key: 'auditoria',
                label: 'Auditoria',
                desc: 'Registro imutável de operações (LGPD Art. 37).',
                icon: 'pi pi-shield',
                to: '/configuracoes/auditoria'
            }
        ]
    }
];

// Flatten pra cálculos de item ativo (mesma lógica de antes)
const secoesFlat = computed(() => grupos.flatMap((g) => g.items));

const activeTo = computed(() => {
    const p = route.path || '';
    const hit = [...secoesFlat.value]
        .sort((a, b) => b.to.length - a.to.length)
        .find((s) => p === s.to || p.startsWith(s.to + '/') || (s.aliases || []).includes(p));
    return hit?.to || '/configuracoes/agenda';
});

const activeSecao = computed(() => secoesFlat.value.find((s) => s.to === activeTo.value));

// Grupo que contém a seção ativa (pra auto-expandir no accordion)
const activeGrupoKey = computed(() => grupos.find((g) => g.items.some((i) => i.to === activeTo.value))?.key || grupos[0].key);

// Accordion multi-open: começa com o grupo ativo aberto
const openGroups = ref([activeGrupoKey.value]);

// Quando a rota mudar e o grupo ativo não estiver aberto, abre ele (sem fechar os outros)
watch(activeGrupoKey, (k) => {
    if (k && !openGroups.value.includes(k)) {
        openGroups.value = [...openGroups.value, k];
    }
});

function ir(to) {
    if (!to) return;
    if (route.path !== to) router.push(to);
    asideOpen.value = false;
}

onMounted(() => {
    requestAnimationFrame(() => {
        showMenu.value = true;
    });

    const rootMargin = `${document.querySelector('.l2-main') ? '0px' : '-56px'} 0px 0px 0px`;
    _observer = new IntersectionObserver(
        ([entry]) => {
            headerStuck.value = !entry.isIntersecting;
        },
        { threshold: 0, rootMargin }
    );
    if (headerSentinelRef.value) _observer.observe(headerSentinelRef.value);
});

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

<template>
    <div class="flex min-h-screen bg-[var(--surface-ground)]">
        <!-- Overlay mobile -->
        <div v-if="asideOpen" class="fixed inset-0 bg-black/40 backdrop-blur-sm z-[39] xl:hidden" @click="asideOpen = false" />

        <!-- Aside drawer -->
        <aside
            class="cfg-aside-drawer flex flex-col overflow-y-auto shrink-0 bg-[var(--surface-card)] border-r border-[var(--surface-border)]"
            :class="asideOpen ? 'translate-x-0 visible' : 'max-xl:-translate-x-full max-xl:invisible'"
            :style="{ left: asideLeft }"
        >
            <!-- Cabeçalho da aside (sticky — igual à sidebar principal) -->
            <div class="cfg-aside-header sticky top-0 z-10 flex items-center gap-2 px-4 h-[50px] border-b border-[var(--surface-border)] shrink-0 bg-[var(--surface-card)]">
                <div class="grid place-items-center w-8 h-8 rounded-md bg-indigo-500/[0.12] text-[var(--p-primary-500,#6366f1)] shrink-0">
                    <i class="pi pi-cog text-sm" />
                </div>
                <span class="text-sm font-bold text-[var(--text-color)] tracking-tight">Configurações</span>
            </div>

            <!-- Label seções -->
            <div class="flex items-center gap-1.5 px-4 pt-3 pb-1.5 text-[0.68rem] font-bold uppercase tracking-[0.06em] text-[var(--text-color-secondary)] opacity-60">
                <i class="pi pi-list text-[0.65rem]" />
                <span>Seções</span>
            </div>

            <!-- Accordion de grupos -->
            <div v-if="showMenu" class="cfg-menu-accordion px-2 pb-3">
                <Accordion v-model:value="openGroups" multiple>
                    <AccordionPanel v-for="g in grupos" :key="g.key" :value="g.key">
                        <AccordionHeader class="cfg-group-header">
                            <div class="flex items-center gap-2.5 w-full min-w-0">
                                <div class="cfg-group-icon grid place-items-center w-9 h-9 rounded-md shrink-0 bg-[color-mix(in_srgb,var(--primary-color)_12%,transparent)] text-[var(--primary-color,#6366f1)]">
                                    <i :class="g.icon" class="text-[0.95rem]" />
                                </div>
                                <div class="flex-1 min-w-0 flex flex-col gap-0.5">
                                    <span class="text-[0.9rem] font-bold leading-5 text-[var(--text-color)] truncate">{{ g.label }}</span>
                                    <span class="text-[0.8rem] leading-[1.15rem] text-[var(--text-color-secondary)] opacity-75 whitespace-normal break-words">{{ g.desc }}</span>
                                </div>
                                <Badge :value="g.items.length" severity="contrast" class="cfg-group-badge shrink-0" />
                            </div>
                        </AccordionHeader>
                        <AccordionContent>
                            <div class="cfg-nav-list flex flex-col gap-2 py-1">
                                <button
                                    v-for="s in g.items"
                                    :key="s.key"
                                    class="cfg-nav-item flex items-center gap-3 p-3 cursor-pointer w-full text-left rounded-[6px] border bg-[var(--surface-card)] transition-colors duration-[120ms]"
                                    :class="activeTo === s.to ? 'cfg-nav-item--active' : 'border-[var(--surface-border)]'"
                                    @click="ir(s.to)"
                                >
                                    <div
                                        class="w-10 h-10 rounded-[6px] flex items-center justify-center shrink-0 transition-colors duration-[120ms]"
                                        :class="activeTo === s.to
                                            ? 'bg-[color-mix(in_srgb,var(--primary-color)_15%,transparent)] text-[var(--primary-color,#6366f1)]'
                                            : 'bg-[var(--surface-ground)] text-[var(--text-color-secondary)]'"
                                    >
                                        <i :class="s.icon" class="text-lg" />
                                    </div>

                                    <div class="flex-1 min-w-0 flex flex-col gap-0.5">
                                        <span
                                            class="font-semibold leading-5 truncate"
                                            :class="activeTo === s.to ? 'text-[var(--primary-color,#6366f1)]' : 'text-[var(--text-color)]'"
                                        >{{ s.label }}</span>
                                        <span class="text-sm leading-[1.15rem] text-[var(--text-color-secondary)] whitespace-normal break-words">{{ s.desc }}</span>
                                    </div>
                                </button>
                            </div>
                        </AccordionContent>
                    </AccordionPanel>
                </Accordion>
            </div>
        </aside>

        <!-- Área principal -->
        <div class="flex-1 min-w-0 xl:pl-[320px]">
            <!-- Sentinel -->
            <div ref="headerSentinelRef" class="h-px" />

            <!-- Hero compacto -->
            <div
                ref="headerEl"
                class="sticky top-[var(--layout-sticky-top,56px)] z-20 overflow-hidden rounded-md border border-[var(--surface-border)] bg-[var(--surface-card)] px-3 py-2.5 mx-3 md:mx-4 my-3"
                :class="{ 'rounded-tl-none rounded-tr-none': headerStuck }"
            >
                <!-- 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-emerald-300/10" />
                    <div class="absolute w-72 h-72 top-0 -left-16 rounded-full blur-[60px] bg-indigo-500/[0.09]" />
                </div>

                <div class="relative z-1 flex items-center gap-3">
                    <!-- Brand -->
                    <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/[0.12] text-[var(--p-primary-500,#6366f1)]">
                            <i class="pi pi-cog text-base" />
                        </div>
                        <div class="min-w-0">
                            <!-- Título: Configurações · Seção -->
                            <div class="text-[1rem] font-bold tracking-tight text-[var(--text-color)] flex items-center gap-1.5 flex-wrap">
                                <span>Configurações</span>
                                <template v-if="activeSecao">
                                    <span class="text-[var(--text-color-secondary)] opacity-40 font-normal">·</span>
                                    <span>{{ activeSecao.label }}</span>
                                </template>
                            </div>
                            <!-- Subtítulo: ícone + descrição da seção -->
                            <div class="text-xs text-[var(--text-color-secondary)] flex items-center gap-1 mt-px">
                                <template v-if="activeSecao">
                                    <i :class="activeSecao.icon" class="opacity-50 shrink-0" />
                                    <span>{{ activeSecao.desc }}</span>
                                </template>
                                <span v-else class="opacity-60">Configurações gerais do sistema</span>
                            </div>
                        </div>
                    </div>

                    <!-- Ações -->
                    <div class="flex items-center gap-2 ml-auto shrink-0">
                        <!-- Slot de ações específicas da sub-página (via Teleport) -->
                        <div id="cfg-page-actions" class="flex items-center gap-1.5"></div>

                        <!-- Toggle aside — mobile/tablet apenas -->
                        <button
                            class="xl:hidden inline-flex items-center gap-1.5 h-9 px-3 rounded-full border border-[var(--surface-border)] bg-transparent text-xs font-semibold text-[var(--text-color)] cursor-pointer hover:bg-[var(--surface-hover)] transition-colors duration-150"
                            @click="asideOpen = !asideOpen"
                        >
                            <i class="pi pi-bars text-[0.75rem]" />
                            <span class="hidden sm:inline">Menu desta seção</span>
                        </button>
                        <Button icon="pi pi-arrow-left" severity="secondary" outlined class="h-9 w-9 rounded-full" v-tooltip.bottom="'Voltar'" @click="router.back()" />
                    </div>
                </div>
            </div>

            <!-- Conteúdo da seção -->
            <div class="px-3 md:px-4 pb-5">
                <router-view />
            </div>
        </div>
    </div>
</template>

<style scoped>
/* Aside drawer — comportamento responsivo */
.cfg-aside-drawer {
    position: fixed;
    top: calc(56px + var(--notice-banner-height, 0px));
    left: 0;
    height: calc(100dvh - 56px - var(--notice-banner-height, 0px));
    width: min(320px, 90vw);
    z-index: 40;
    overflow-y: auto;
    transition:
        transform 0.25s cubic-bezier(0.4, 0, 0.2, 1),
        visibility 0.25s;
    box-shadow: 4px 0 24px rgba(0, 0, 0, 0.15);
}
@media (min-width: 1280px) {
    .cfg-aside-drawer {
        position: fixed;
        top: calc(56px + var(--notice-banner-height, 0px));
        height: calc(100vh - 56px - var(--notice-banner-height, 0px));
        width: 320px;
        transform: none;
        visibility: visible;
        box-shadow: none;
        z-index: auto;
        overflow-y: auto;
    }
}

/* ── Lista de subitens (cards) ──────────────────────────────── */
.cfg-nav-list {
    margin: 0.15rem 0.25rem 0.35rem 1.5rem;
}

/* ── Hover e estado ativo dos cards ─────────────────────────── */
.cfg-nav-item {
    transition:
        background-color 150ms ease,
        border-color 150ms ease;
}
.cfg-nav-item:hover {
    background: var(--surface-hover) !important;
    border-color: color-mix(in srgb, var(--primary-color) 30%, var(--surface-border)) !important;
}
.cfg-nav-item--active {
    background: color-mix(in srgb, var(--primary-color) 6%, var(--surface-card));
    border-color: var(--primary-color, #6366f1) !important;
}

/* ── Accordion do menu — compacto, sem bordas grossas ───────────── */
.cfg-menu-accordion :deep(.p-accordion) {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.cfg-menu-accordion :deep(.p-accordionpanel) {
    border: none;
    background: transparent;
}
.cfg-menu-accordion :deep(.p-accordionheader) {
    padding: 0.5rem 0.5rem;
    border-radius: 8px;
    background: transparent;
    border: none;
    color: var(--text-color);
    transition: background-color 120ms ease;
    min-height: 52px;
}
.cfg-menu-accordion :deep(.p-accordionheader:hover) {
    background: color-mix(in srgb, var(--primary-color) 8%, var(--surface-card)) !important;
    color: var(--text-color) !important;
}
.cfg-menu-accordion :deep(.p-accordionheader:focus-visible) {
    box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--primary-color) 30%, transparent);
}
.cfg-menu-accordion :deep(.p-accordionheader-toggle-icon) {
    color: var(--text-color-secondary);
    opacity: 0.55;
    font-size: 0.7rem;
    margin-left: 0.25rem;
    transition: color 150ms ease, opacity 150ms ease, transform 150ms ease;
}
.cfg-menu-accordion :deep(.p-accordionheader:hover) .p-accordionheader-toggle-icon {
    color: var(--primary-color, #6366f1);
    opacity: 0.8;
}

/* Ícone do grupo ganha anel primary no hover (igual aos subitens) */
.cfg-group-icon {
    transition: box-shadow 150ms ease, background-color 150ms ease;
}
.cfg-menu-accordion :deep(.p-accordionheader:hover) .cfg-group-icon {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary-color) 25%, transparent);
    background: color-mix(in srgb, var(--primary-color) 18%, transparent);
}

/* Badge circular do contador de itens (igual ao p-badge-circle do pasteds.txt) */
.cfg-group-badge :deep(.p-badge),
.cfg-group-badge.p-badge {
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 0.35rem;
    font-size: 0.68rem;
    font-weight: 700;
    border-radius: 9999px;
    line-height: 1.25rem;
}
.cfg-menu-accordion :deep(.p-accordioncontent) {
    border: none;
    background: transparent;
}
.cfg-menu-accordion :deep(.p-accordioncontent-content) {
    padding: 0.15rem 0.2rem 0.35rem;
    background: transparent;
    border: none;
}
</style>
