<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/views/pages/saas/SaasFeriadosPage.vue
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
-->
<script setup>
import { ref, computed, onMounted } from 'vue';
import { supabase } from '@/lib/supabase/client';
import { useToast } from 'primevue/usetoast';
import DatePicker from 'primevue/datepicker';
import { getFeriadosNacionais } from '@/utils/feriadosBR';
import { createNotice, deleteNotice } from '@/features/notices/noticeService';

const toast = useToast();

// ── Estado ───────────────────────────────────────────────────
const loading = ref(false);
const feriados = ref([]);
const ano = ref(new Date().getFullYear());
const search = ref('');

// ── Filtros ──────────────────────────────────────────────────
const filtroEstado = ref(null);
const filtroCidade = ref(null);

// ── Dialog ───────────────────────────────────────────────────
const dlgOpen = ref(false);
const saving = ref(false);
const form = ref(emptyForm());

function emptyForm() {
    return {
        nome: '',
        data: null,
        cidade: '',
        estado: '',
        observacao: '',
        bloqueia_sessoes: false
    };
}

const formValid = computed(() => !!form.value.nome.trim() && !!form.value.data);

function abrirDialog() {
    form.value = emptyForm();
    dlgOpen.value = true;
}

function dateToISO(d) {
    if (!d) return null;
    const dt = d instanceof Date ? d : new Date(d);
    return `${dt.getFullYear()}-${String(dt.getMonth() + 1).padStart(2, '0')}-${String(dt.getDate()).padStart(2, '0')}`;
}

async function salvar() {
    if (!formValid.value) return;
    saving.value = true;
    try {
        const isoData = dateToISO(form.value.data);
        const nome = form.value.nome.trim();
        const { error } = await supabase.rpc('saas_add_default_feriado', { p_data: isoData, p_nome: nome, p_tipo: 'municipal' });
        if (error) throw error;
        // Re-lista os defaults do ano (RPC retorna {data, nome, tipo}; re-listar é mais simples e fica consistente)
        await load();

        // ── Auto-aviso global: defaults são sempre globais ──
        if (isoData) {
            try {
                await createNotice({
                    title: form.value.nome.trim(),
                    message: `📅 Lembrete: <b>${form.value.nome.trim()}</b> — ${fmtDate(isoData)} é feriado. Organize sua agenda com antecedência.`,
                    variant: 'info',
                    starts_at: dateMinus2(isoData),
                    ends_at: `${isoData}T23:59`,
                    is_active: true,
                    priority: 10,
                    dismissible: true,
                    persist_dismiss: true,
                    dismiss_scope: 'device',
                    content_align: 'center',
                    action_type: 'none',
                    roles: [],
                    contexts: []
                });
                toast.add({ severity: 'success', summary: 'Feriado cadastrado', detail: 'Aviso global criado automaticamente.', life: 3000 });
            } catch {
                toast.add({ severity: 'success', summary: 'Feriado cadastrado', detail: 'Aviso global não pôde ser criado — crie manualmente em Avisos Globais.', life: 4000 });
            }
        } else {
            toast.add({ severity: 'success', summary: 'Feriado cadastrado', life: 1800 });
        }

        dlgOpen.value = false;
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro', detail: e?.message, life: 3500 });
    } finally {
        saving.value = false;
    }
}

// ── Load feriados ─────────────────────────────────────────────
async function load() {
    loading.value = true;
    try {
        const { data, error } = await supabase.rpc('saas_list_default_feriados', { p_ano: ano.value });
        if (error) throw error;
        // RPC retorna jsonb array direto (sem join de tenants; defaults não têm tenant)
        feriados.value = (data || []).slice().sort((a, b) => a.data.localeCompare(b.data));
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro', detail: e?.message, life: 3500 });
    } finally {
        loading.value = false;
    }
}

onMounted(() => {
    load();
    carregarDeclinados();
});

// ── Navegação de ano ─────────────────────────────────────────
async function anoAnterior() {
    ano.value--;
    carregarDeclinados();
    await load();
}
async function anoProximo() {
    ano.value++;
    carregarDeclinados();
    await load();
}

// ── Helpers ──────────────────────────────────────────────────
function fmtDate(iso) {
    if (!iso) return '—';
    const [y, m, d] = String(iso).split('-');
    return `${d}/${m}/${y}`;
}

// ── Opções de filtro ─────────────────────────────────────────
const estadoOptions = computed(() => {
    const set = new Set(feriados.value.map((f) => f.estado).filter(Boolean));
    return [{ label: 'Todos os estados', value: null }, ...[...set].sort().map((e) => ({ label: e, value: e }))];
});

const cidadeOptions = computed(() => {
    const set = new Set(
        feriados.value
            .filter((f) => !filtroEstado.value || f.estado === filtroEstado.value)
            .map((f) => f.cidade)
            .filter(Boolean)
    );
    return [{ label: 'Todas as cidades', value: null }, ...[...set].sort().map((c) => ({ label: c, value: c }))];
});

// ── Lista filtrada ────────────────────────────────────────────
const listaFiltrada = computed(() => {
    let list = feriados.value;
    if (filtroEstado.value) list = list.filter((f) => f.estado === filtroEstado.value);
    if (filtroCidade.value) list = list.filter((f) => f.cidade === filtroCidade.value);
    const q = search.value.trim().toLowerCase();
    if (q) list = list.filter((f) => f.nome.toLowerCase().includes(q) || (f.cidade || '').toLowerCase().includes(q));
    return list;
});

// ── Agrupamento por data ──────────────────────────────────────
const agrupados = computed(() => {
    const map = new Map();
    for (const f of listaFiltrada.value) {
        if (!map.has(f.data)) map.set(f.data, []);
        map.get(f.data).push(f);
    }
    return [...map.entries()].sort(([a], [b]) => a.localeCompare(b));
});

// ── Stats ─────────────────────────────────────────────────────
const totalFeriados = computed(() => feriados.value.length);
// TODO(schema-per-tenant): defaults não têm tenant_id/cidade/estado — estes stats e os filtros
// estado/cidade ficam sempre vazios/0. Remover os cards/filtros ou repensar a UI numa próxima passada.
const totalTenants = computed(() => new Set(feriados.value.map((f) => f.tenant_id).filter(Boolean)).size);
const totalMunicipios = computed(() => new Set(feriados.value.map((f) => f.cidade).filter(Boolean)).size);

// ── Feriados Nacionais (algoritmo) ────────────────────────────
const nacionais = computed(() => getFeriadosNacionais(ano.value));

function isPassado(iso) {
    return iso < new Date().toISOString().slice(0, 10);
}

function dateMinus2(iso) {
    const d = new Date(iso + 'T12:00:00');
    d.setDate(d.getDate() - 2);
    return `${d.toISOString().slice(0, 10)}T08:00`;
}

// Datas de nacionais já publicados no DB como feriado default (todos os defaults são globais)
const publicadosDatas = computed(() => new Set(feriados.value.map((f) => f.data)));

// Datas marcadas como "não publicar" — persiste em localStorage por ano
function lsKey() {
    return `saas_feriados_declinados_${ano.value}`;
}

function carregarDeclinados() {
    try {
        const raw = localStorage.getItem(lsKey());
        declinadosDatas.value = new Set(raw ? JSON.parse(raw) : []);
    } catch {
        declinadosDatas.value = new Set();
    }
}

function salvarDeclinados() {
    localStorage.setItem(lsKey(), JSON.stringify([...declinadosDatas.value]));
}

const declinadosDatas = ref(new Set());

// Estado de cada feriado: 'published' | 'declined' | 'idle'
function estadoNacional(iso) {
    if (publicadosDatas.value.has(iso)) return 'published';
    if (declinadosDatas.value.has(iso)) return 'declined';
    return 'idle';
}

// ── Fluxo de publicação ───────────────────────────────────────
const confirmandoNacional = ref(null); // ISO exibindo confirmação inline
const salvandoNacional = ref(null); // ISO sendo gravado
const dlgPublicar = ref(false); // Dialog de confirmação final
const feriadoParaPublicar = ref(null); // Objeto feriado aguardando confirmação final

function pedirConfirmacaoNacional(iso) {
    confirmandoNacional.value = confirmandoNacional.value === iso ? null : iso;
}

async function declinarNacional(feriado) {
    const iso = feriado.data;
    const nome = feriado.nome;

    const s = new Set(declinadosDatas.value);
    s.add(iso);
    declinadosDatas.value = s;
    confirmandoNacional.value = null;
    salvarDeclinados();

    // Remove avisos globais associados (mesmo título + ends_at no dia)
    try {
        const { data: avisos } = await supabase.from('global_notices').select('id').eq('title', nome).gte('ends_at', `${iso}T00:00`).lte('ends_at', `${iso}T23:59`);

        if (avisos?.length) {
            await Promise.allSettled(avisos.map((a) => deleteNotice(a.id)));
            toast.add({ severity: 'info', summary: 'Aviso removido', detail: `Aviso global de "${nome}" excluído.`, life: 3000 });
        }
    } catch {
        /* silencioso — declinar já foi salvo */
    }
}

function reverterDeclinado(iso) {
    const s = new Set(declinadosDatas.value);
    s.delete(iso);
    declinadosDatas.value = s;
    salvarDeclinados();
}

function abrirDlgPublicar(feriado) {
    feriadoParaPublicar.value = feriado;
    confirmandoNacional.value = null;
    dlgPublicar.value = true;
}

// ── Despublicação ─────────────────────────────────────────────
const dlgUnpublish = ref(false);
const feriadoParaDespublicar = ref(null);
const despublicando = ref(false);

function abrirDlgUnpublish(feriado) {
    // Despublicação agora é por (data, nome) via RPC — não precisa mais do id do registro
    feriadoParaDespublicar.value = { ...feriado };
    dlgUnpublish.value = true;
}

async function confirmarDespublicacao() {
    const feriado = feriadoParaDespublicar.value;
    if (!feriado) return;
    despublicando.value = true;
    dlgUnpublish.value = false;
    try {
        // 1. Remove o feriado default do banco (por data + nome; propaga aos schemas)
        const { error } = await supabase.rpc('saas_remove_default_feriado', { p_data: feriado.data, p_nome: feriado.nome });
        if (error) throw error;
        feriados.value = feriados.value.filter((f) => !(f.data === feriado.data && f.nome === feriado.nome));

        // 2. Remove avisos globais associados (mesmo título + ends_at no dia do feriado)
        const { data: avisos } = await supabase.from('global_notices').select('id').eq('title', feriado.nome).gte('ends_at', `${feriado.data}T00:00`).lte('ends_at', `${feriado.data}T23:59`);

        await Promise.allSettled((avisos || []).map((a) => deleteNotice(a.id)));

        toast.add({
            severity: 'success',
            summary: 'Feriado despublicado',
            detail: `${feriado.nome} removido. Aviso(s) global(is) excluído(s).`,
            life: 3500
        });
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao despublicar', detail: e?.message, life: 4000 });
    } finally {
        despublicando.value = false;
        feriadoParaDespublicar.value = null;
    }
}

async function confirmarPublicacao() {
    const feriado = feriadoParaPublicar.value;
    if (!feriado) return;
    salvandoNacional.value = feriado.data;
    dlgPublicar.value = false;
    try {
        const { error } = await supabase.rpc('saas_add_default_feriado', { p_data: feriado.data, p_nome: feriado.nome, p_tipo: 'municipal' });
        if (error) throw error;
        // Re-lista para refletir o novo default publicado
        await load();

        // Auto-aviso global
        try {
            await createNotice({
                title: feriado.nome,
                message: `📅 Lembrete: <b>${feriado.nome}</b> — ${fmtDate(feriado.data)} é feriado nacional. Organize sua agenda com antecedência.`,
                variant: 'info',
                starts_at: dateMinus2(feriado.data),
                ends_at: `${feriado.data}T23:59`,
                is_active: true,
                priority: 10,
                dismissible: true,
                persist_dismiss: true,
                dismiss_scope: 'device',
                content_align: 'center',
                action_type: 'none',
                roles: [],
                contexts: []
            });
        } catch {
            /* silencioso — feriado já foi publicado */
        }

        toast.add({ severity: 'success', summary: 'Feriado publicado', detail: `${feriado.nome} — aviso global criado automaticamente.`, life: 3500 });
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao publicar', detail: e?.message, life: 4000 });
    } finally {
        salvandoNacional.value = null;
        feriadoParaPublicar.value = null;
    }
}

// ── Excluir ───────────────────────────────────────────────────
async function excluir(feriado) {
    try {
        // Agora deleta por (data, nome) — defaults não têm id de tenant associado
        const { error } = await supabase.rpc('saas_remove_default_feriado', { p_data: feriado.data, p_nome: feriado.nome });
        if (error) throw error;
        feriados.value = feriados.value.filter((f) => !(f.data === feriado.data && f.nome === feriado.nome));
        toast.add({ severity: 'success', summary: 'Removido', life: 1500 });
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro', detail: e?.message, life: 3000 });
    }
}
</script>

<template>
    <div class="flex flex-col gap-4 p-4">
        <!-- Header -->
        <div class="cfg-subheader">
            <div class="cfg-subheader__icon"><i class="pi pi-calendar" /></div>
            <div class="min-w-0 flex-1">
                <div class="cfg-subheader__title">Feriados Municipais</div>
                <div class="cfg-subheader__sub">Feriados cadastrados pelos tenants — alimentam o banco central de feriados do SaaS.</div>
            </div>
            <div class="flex items-center gap-2 shrink-0">
                <Button icon="pi pi-chevron-left" text rounded severity="secondary" @click="anoAnterior" />
                <span class="font-bold text-[1rem] w-14 text-center">{{ ano }}</span>
                <Button icon="pi pi-chevron-right" text rounded severity="secondary" @click="anoProximo" />
                <Button icon="pi pi-refresh" severity="secondary" outlined rounded :loading="loading" @click="load" />
                <Button icon="pi pi-plus" label="Cadastrar" size="small" @click="abrirDialog" />
            </div>
        </div>

        <div class="flex flex-col gap-6">
        <!-- ══ Feriados Nacionais ══════════════════════════════════ -->
        <div class="rounded-md border border-[var(--surface-border)] bg-[var(--surface-card)] overflow-hidden">
            <div class="flex items-center gap-2 px-5 py-3 border-b border-[var(--surface-border)] bg-[var(--surface-ground)]">
                <i class="pi pi-flag text-blue-500" />
                <span class="font-bold text-sm">Feriados Nacionais — {{ ano }}</span>
                <span class="text-[0.72rem] text-[var(--text-color-secondary)] ml-1">(gerados automaticamente)</span>
            </div>

            <div class="flex flex-col">
                <div v-for="f in nacionais" :key="f.data" class="flex flex-col border-b border-[var(--surface-border)] last:border-b-0" :class="isPassado(f.data) ? 'opacity-40' : ''">
                    <!-- Linha principal -->
                    <div class="flex items-center gap-3 px-5 py-2.5 flex-wrap" :class="!isPassado(f.data) ? 'hover:bg-[var(--surface-hover)]' : ''">
                        <!-- Data -->
                        <span class="font-mono text-xs font-semibold bg-[var(--surface-ground)] border border-[var(--surface-border)] rounded px-2 py-0.5 shrink-0">
                            {{ fmtDate(f.data) }}
                        </span>

                        <!-- Nome -->
                        <span class="flex-1 min-w-[160px] text-sm font-medium" :class="{ 'line-through opacity-50': publicadosDatas.has(f.data) }">
                            {{ f.nome }}
                        </span>

                        <!-- Tags -->
                        <Tag v-if="f.movel" value="Móvel" severity="secondary" class="text-[0.68rem]" />
                        <Tag v-if="isPassado(f.data)" value="Passado" severity="secondary" class="text-[0.68rem] opacity-60" />
                        <Tag v-if="publicadosDatas.has(f.data)" value="Publicado" severity="success" class="text-[0.68rem]" />

                        <!-- Ícone de estado -->
                        <template v-if="!isPassado(f.data)">
                            <!-- Publicado → clicável para despublicar -->
                            <button v-if="estadoNacional(f.data) === 'published'" v-tooltip.top="'Publicado — clique para despublicar'" class="snf-lock snf-lock--published" @click="abrirDlgUnpublish(f)">
                                <i class="pi pi-lock text-xs" />
                            </button>

                            <!-- Salvando / despublicando -->
                            <span v-else-if="salvandoNacional === f.data || despublicando" class="snf-lock">
                                <i class="pi pi-spinner pi-spin text-xs" />
                            </span>

                            <!-- Confirmação inline aberta → botão fechar -->
                            <button v-else-if="confirmandoNacional === f.data" v-tooltip.top="'Fechar'" class="snf-lock snf-lock--active" @click="confirmandoNacional = null">
                                <i class="pi pi-times text-xs" />
                            </button>

                            <!-- Declinado → círculo X, clicável para reverter -->
                            <button v-else-if="estadoNacional(f.data) === 'declined'" v-tooltip.top="'Marcado como não publicar — clique para reverter'" class="snf-lock snf-lock--declined" @click="reverterDeclinado(f.data)">
                                <i class="pi pi-times-circle text-xs" />
                            </button>

                            <!-- Idle → cadeado aberto -->
                            <button v-else v-tooltip.top="'Definir publicação deste feriado'" class="snf-lock snf-lock--idle" @click="pedirConfirmacaoNacional(f.data)">
                                <i class="pi pi-lock-open text-xs" />
                            </button>
                        </template>
                    </div>

                    <!-- Confirmação inline — Publicar ou Não publicar -->
                    <Transition name="snf-expand">
                        <div v-if="confirmandoNacional === f.data" class="snf-confirm mx-5 mb-2">
                            <i class="pi pi-question-circle snf-confirm__icon" />
                            <div class="flex-1 min-w-0">
                                <p class="text-xs font-semibold mb-0.5">
                                    O que fazer com <b>{{ f.nome }}</b
                                    >?
                                </p>
                                <p class="text-xs opacity-70 leading-snug">Publicar torna o feriado visível na agenda de todos os tenants e cria um aviso global automaticamente. Não publicar mantém oculto — você pode mudar depois.</p>
                            </div>
                            <div class="flex gap-1.5 shrink-0 flex-wrap justify-end">
                                <Button label="Não publicar" size="small" severity="secondary" outlined icon="pi pi-times-circle" class="rounded-full h-7 text-xs px-3" @click="declinarNacional(f)" />
                                <Button label="Sim, publicar" size="small" severity="warn" icon="pi pi-megaphone" class="rounded-full h-7 text-xs px-3" @click="abrirDlgPublicar(f)" />
                            </div>
                        </div>
                    </Transition>
                </div>
            </div>
        </div>

        <!-- ── Stats municipais ────────────────────────────────── -->
        <div>
            <div class="flex items-center gap-2 mb-3">
                <i class="pi pi-star text-amber-500" />
                <span class="font-bold text-sm">Feriados Municipais</span>
            </div>

            <!-- ── Stats ──────────────────────────────────────────── -->
            <div class="grid grid-cols-3 gap-3">
                <div class="rounded-md border border-[var(--surface-border)] bg-[var(--surface-card)] p-4 text-center">
                    <div class="text-2xl font-bold text-amber-500">{{ totalFeriados }}</div>
                    <div class="text-[1rem] text-[var(--text-color-secondary)] mt-1">Total de feriados</div>
                </div>
                <div class="rounded-md border border-[var(--surface-border)] bg-[var(--surface-card)] p-4 text-center">
                    <div class="text-2xl font-bold text-blue-500">{{ totalTenants }}</div>
                    <div class="text-[1rem] text-[var(--text-color-secondary)] mt-1">Tenants contribuintes</div>
                </div>
                <div class="rounded-md border border-[var(--surface-border)] bg-[var(--surface-card)] p-4 text-center">
                    <div class="text-2xl font-bold text-green-500">{{ totalMunicipios }}</div>
                    <div class="text-[1rem] text-[var(--text-color-secondary)] mt-1">Municípios</div>
                </div>
            </div>

            <!-- ── Filtros ─────────────────────────────────────────── -->
            <div class="flex flex-wrap gap-3 rounded-md border border-[var(--surface-border)] bg-[var(--surface-card)] px-4 py-3">
                <div class="flex-1 min-w-[160px]">
                    <IconField>
                        <InputIcon class="pi pi-search" />
                        <InputText v-model="search" class="w-full" placeholder="Buscar feriado ou cidade…" />
                    </IconField>
                </div>
                <Select v-model="filtroEstado" :options="estadoOptions" optionLabel="label" optionValue="value" class="min-w-[160px]" @change="filtroCidade = null" />
                <Select v-model="filtroCidade" :options="cidadeOptions" optionLabel="label" optionValue="value" class="min-w-[180px]" />
            </div>

            <!-- ── Loading ─────────────────────────────────────────── -->
            <div v-if="loading" class="flex items-center justify-center py-16">
                <i class="pi pi-spinner pi-spin text-2xl opacity-40" />
            </div>

            <template v-else>
                <div v-if="!agrupados.length" class="rounded-md border border-[var(--surface-border)] bg-[var(--surface-card)] p-8 text-center text-[var(--text-color-secondary)]">Nenhum feriado municipal cadastrado para {{ ano }}.</div>

                <!-- ── Lista agrupada por data ───────────────────────── -->
                <div v-for="[data, lista] in agrupados" :key="data" class="rounded-md border border-[var(--surface-border)] bg-[var(--surface-card)] overflow-hidden">
                    <div class="flex items-center gap-2 px-5 py-3 border-b border-[var(--surface-border)] font-semibold bg-[var(--surface-ground)]">
                        <span class="font-mono text-[1rem]">{{ fmtDate(data) }}</span>
                        <span class="text-[1rem] bg-[var(--surface-card)] border border-[var(--surface-border)] rounded-full px-2 py-px text-[var(--text-color-secondary)]">{{ lista.length }}</span>
                    </div>

                    <div class="flex flex-col">
                        <div v-for="f in lista" :key="f.id" class="flex items-center gap-3 px-5 py-2.5 border-b border-[var(--surface-border)] last:border-b-0 flex-wrap hover:bg-[var(--surface-hover)]">
                            <div class="font-medium text-[1rem] flex-1 min-w-[180px]">{{ f.nome }}</div>

                            <div class="flex items-center gap-2 flex-wrap">
                                <Tag v-if="f.cidade" :value="f.cidade" severity="secondary" />
                                <Tag v-if="f.estado" :value="f.estado" severity="info" />
                                <Tag v-if="f.bloqueia_sessoes" value="Bloqueia" severity="danger" />
                            </div>

                            <div class="ml-auto">
                                <Button icon="pi pi-trash" text rounded size="small" severity="danger" @click="excluir(f)" />
                            </div>
                        </div>
                    </div>
                </div>
            </template>
        </div>
        <!-- /municipais -->
        </div>
    </div>
    <!-- /content -->

    <!-- ══ Dialog despublicação ══════════════════════════════ -->
    <Dialog v-model:visible="dlgUnpublish" modal :draggable="false" :style="{ width: '420px' }" header="Despublicar feriado">
        <div v-if="feriadoParaDespublicar" class="flex flex-col gap-4 pt-1">
            <div class="flex items-center gap-3 rounded-lg bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-800 px-4 py-3">
                <i class="pi pi-exclamation-triangle text-red-500 text-lg shrink-0" />
                <div>
                    <p class="font-semibold text-sm m-0">{{ feriadoParaDespublicar.nome }}</p>
                    <p class="text-xs text-[var(--text-color-secondary)] m-0">{{ fmtDate(feriadoParaDespublicar.data) }}</p>
                </div>
            </div>
            <ul class="text-sm flex flex-col gap-1.5 m-0 pl-0 list-none">
                <li class="flex items-start gap-2">
                    <i class="pi pi-times text-red-500 mt-0.5 shrink-0" />
                    O feriado será removido da agenda de <b>todos os tenants</b>.
                </li>
                <li class="flex items-start gap-2">
                    <i class="pi pi-times text-red-500 mt-0.5 shrink-0" />
                    O aviso global associado a este feriado será <b>excluído automaticamente</b>.
                </li>
            </ul>
        </div>
        <template #footer>
            <Button label="Cancelar" severity="secondary" outlined @click="dlgUnpublish = false" />
            <Button label="Despublicar" icon="pi pi-trash" severity="danger" :loading="despublicando" @click="confirmarDespublicacao" />
        </template>
    </Dialog>

    <!-- ══ Dialog confirmação final — publicar nacional ══════ -->
    <Dialog v-model:visible="dlgPublicar" modal :draggable="false" :style="{ width: '440px' }" header="Confirmar publicação">
        <div v-if="feriadoParaPublicar" class="flex flex-col gap-4 pt-1">
            <div class="flex items-center gap-3 rounded-lg bg-amber-50 dark:bg-amber-950/30 border border-amber-200 dark:border-amber-800 px-4 py-3">
                <i class="pi pi-flag text-amber-500 text-lg shrink-0" />
                <div>
                    <p class="font-semibold text-sm m-0">{{ feriadoParaPublicar.nome }}</p>
                    <p class="text-xs text-[var(--text-color-secondary)] m-0">{{ fmtDate(feriadoParaPublicar.data) }}</p>
                </div>
            </div>
            <ul class="text-sm flex flex-col gap-1.5 m-0 pl-0 list-none">
                <li class="flex items-start gap-2">
                    <i class="pi pi-users text-blue-500 mt-0.5 shrink-0" />
                    O feriado ficará visível na agenda de <b>todos os tenants</b>.
                </li>
                <li class="flex items-start gap-2">
                    <i class="pi pi-megaphone text-blue-500 mt-0.5 shrink-0" />
                    Um <b>aviso global</b> será criado automaticamente (você pode editar depois em Avisos Globais).
                </li>
                <li class="flex items-start gap-2">
                    <i class="pi pi-info-circle text-[var(--text-color-secondary)] mt-0.5 shrink-0" />
                    <span class="text-[var(--text-color-secondary)]">Sessões <b>não</b> serão bloqueadas automaticamente — cada usuário decide bloquear individualmente.</span>
                </li>
            </ul>
        </div>
        <template #footer>
            <Button label="Cancelar" severity="secondary" outlined @click="dlgPublicar = false" />
            <Button label="Confirmar publicação" icon="pi pi-check" severity="warn" :loading="!!salvandoNacional" @click="confirmarPublicacao" />
        </template>
    </Dialog>

    <!-- ══ Dialog cadastro ════════════════════════════════════ -->
    <Dialog v-model:visible="dlgOpen" modal :draggable="false" header="Cadastrar feriado" :style="{ width: '460px' }">
        <div class="flex flex-col gap-4 pt-1">
            <div>
                <label class="text-[1rem] text-[var(--text-color-secondary)] font-medium">Nome do feriado *</label>
                <InputText v-model="form.nome" class="w-full mt-1" placeholder="Ex.: Padroeiro Municipal, Aniversário da cidade…" />
            </div>

            <div>
                <label class="text-[1rem] text-[var(--text-color-secondary)] font-medium">Data *</label>
                <DatePicker v-model="form.data" showIcon fluid iconDisplay="input" dateFormat="dd/mm/yy" :manualInput="false" class="mt-1">
                    <template #inputicon="sp"><i class="pi pi-calendar" @click="sp.clickCallback" /></template>
                </DatePicker>
            </div>

            <div class="flex gap-3">
                <div class="flex-1">
                    <label class="text-[1rem] text-[var(--text-color-secondary)] font-medium">Cidade</label>
                    <InputText v-model="form.cidade" class="w-full mt-1" placeholder="Ex.: São Paulo" />
                </div>
                <div class="w-24">
                    <label class="text-[1rem] text-[var(--text-color-secondary)] font-medium">Estado (UF)</label>
                    <InputText v-model="form.estado" class="w-full mt-1" placeholder="SP" maxlength="2" />
                </div>
            </div>

            <div>
                <label class="text-[1rem] text-[var(--text-color-secondary)] font-medium">Observação <span class="opacity-60">(opcional)</span></label>
                <Textarea v-model="form.observacao" class="w-full mt-1" rows="2" autoResize placeholder="Nota interna…" />
            </div>

            <div class="flex items-center gap-2">
                <Checkbox v-model="form.bloqueia_sessoes" :binary="true" inputId="bloqueia" />
                <label for="bloqueia" class="text-[1rem] cursor-pointer">Bloqueia sessões neste dia</label>
            </div>
        </div>

        <template #footer>
            <Button label="Cancelar" severity="secondary" outlined @click="dlgOpen = false" />
            <Button label="Cadastrar" icon="pi pi-check" :disabled="!formValid" :loading="saving" @click="salvar" />
        </template>
    </Dialog>
</template>

<style scoped>
/* ── Cadeado por feriado nacional ────────────────────────── */
.snf-lock {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    flex-shrink: 0;
    transition: all 0.14s;
}
.snf-lock--idle {
    color: var(--text-color-secondary);
    background: transparent;
    border: 1.5px solid var(--surface-border);
    cursor: pointer;
}
.snf-lock--idle:hover {
    color: var(--amber-600, #d97706);
    border-color: var(--amber-400, #fbbf24);
    background: color-mix(in srgb, var(--amber-400, #fbbf24) 12%, transparent);
}
.snf-lock--active {
    color: var(--amber-600, #d97706);
    border: 1.5px solid var(--amber-400, #fbbf24);
    background: color-mix(in srgb, var(--amber-400, #fbbf24) 14%, transparent);
    cursor: pointer;
}
.snf-lock--done {
    color: var(--text-color-secondary);
    opacity: 0.45;
    cursor: default;
}
.snf-lock--published {
    color: var(--green-600, #16a34a);
    border: 1.5px solid color-mix(in srgb, var(--green-500, #22c55e) 50%, transparent);
    background: color-mix(in srgb, var(--green-500, #22c55e) 10%, transparent);
    cursor: pointer;
}
.snf-lock--published:hover {
    color: var(--red-500, #ef4444);
    border-color: color-mix(in srgb, var(--red-400, #f87171) 50%, transparent);
    background: color-mix(in srgb, var(--red-400, #f87171) 12%, transparent);
}
.snf-lock--declined {
    color: var(--red-500, #ef4444);
    border: 1.5px solid color-mix(in srgb, var(--red-400, #f87171) 50%, transparent);
    background: color-mix(in srgb, var(--red-400, #f87171) 10%, transparent);
    cursor: pointer;
}
.snf-lock--declined:hover {
    background: color-mix(in srgb, var(--red-400, #f87171) 20%, transparent);
}

/* ── Confirmação inline ──────────────────────────────────── */
.snf-confirm {
    display: flex;
    align-items: flex-start;
    gap: 0.625rem;
    padding: 0.625rem 0.75rem;
    border-radius: 0.875rem;
    background: color-mix(in srgb, var(--amber-400, #fbbf24) 10%, var(--surface-card));
    border: 1px solid color-mix(in srgb, var(--amber-400, #fbbf24) 30%, transparent);
}
.snf-confirm__icon {
    color: var(--amber-500, #f59e0b);
    flex-shrink: 0;
    margin-top: 2px;
    font-size: 0.8rem;
}

/* ── Transição expand ────────────────────────────────────── */
.snf-expand-enter-active,
.snf-expand-leave-active {
    transition:
        opacity 0.15s ease,
        transform 0.15s ease;
}
.snf-expand-enter-from,
.snf-expand-leave-to {
    opacity: 0;
    transform: translateY(-4px);
}
</style>
