/* |-------------------------------------------------------------------------- | Agência PSI |-------------------------------------------------------------------------- | Arquivo: src/composables/useAutoReplySettings.js | Data: 2026-04-21 | | Settings de auto-reply fora do horário (CRM Grupo 2.3). |-------------------------------------------------------------------------- */ import { ref } from 'vue'; import { supabase } from '@/lib/supabase/client'; import { useTenantStore } from '@/stores/tenantStore'; const DEFAULT_SETTINGS = { enabled: false, message: 'Olá! Nosso horário de atendimento acabou. Retornaremos sua mensagem assim que possível. Obrigado!', cooldown_minutes: 180, schedule_mode: 'agenda', business_hours: [], custom_window: [] }; export function useAutoReplySettings() { const tenantStore = useTenantStore(); const settings = ref({ ...DEFAULT_SETTINGS }); const loading = ref(false); const saving = ref(false); const error = ref(null); const lastLoadedAt = ref(null); async function load() { const tenantId = tenantStore.activeTenantId; if (!tenantId) return; loading.value = true; error.value = null; try { const { data, error: err } = await supabase .from('conversation_autoreply_settings') .select('enabled, message, cooldown_minutes, schedule_mode, business_hours, custom_window') .eq('tenant_id', tenantId) .maybeSingle(); if (err) throw err; if (data) { settings.value = { enabled: !!data.enabled, message: data.message ?? DEFAULT_SETTINGS.message, cooldown_minutes: Number(data.cooldown_minutes ?? DEFAULT_SETTINGS.cooldown_minutes), schedule_mode: data.schedule_mode ?? 'agenda', business_hours: Array.isArray(data.business_hours) ? data.business_hours : [], custom_window: Array.isArray(data.custom_window) ? data.custom_window : [] }; } else { settings.value = { ...DEFAULT_SETTINGS, business_hours: [], custom_window: [] }; } lastLoadedAt.value = new Date().toISOString(); } catch (e) { error.value = e?.message || 'Falha ao carregar settings'; } finally { loading.value = false; } } async function save(partial = null) { const tenantId = tenantStore.activeTenantId; if (!tenantId) return { ok: false, error: 'no_tenant' }; const payload = partial ? { ...settings.value, ...partial } : { ...settings.value }; // Sanitização básica payload.message = String(payload.message || '').trim().slice(0, 2000); if (!payload.message) return { ok: false, error: 'mensagem vazia' }; payload.cooldown_minutes = Math.max(0, Math.min(43200, Number(payload.cooldown_minutes) || 0)); if (!['agenda', 'business_hours', 'custom'].includes(payload.schedule_mode)) { payload.schedule_mode = 'agenda'; } payload.business_hours = Array.isArray(payload.business_hours) ? payload.business_hours : []; payload.custom_window = Array.isArray(payload.custom_window) ? payload.custom_window : []; saving.value = true; try { const { error: err } = await supabase .from('conversation_autoreply_settings') .upsert({ tenant_id: tenantId, ...payload }, { onConflict: 'tenant_id' }); if (err) throw err; settings.value = payload; return { ok: true }; } catch (e) { return { ok: false, error: e?.message || 'Falha ao salvar' }; } finally { saving.value = false; } } // Busca a agenda_regras_semanais do tenant — pra mostrar preview "seguindo agenda" async function loadAgendaWindows() { const tenantId = tenantStore.activeTenantId; if (!tenantId) return []; try { const { data } = await supabase .from('agenda_regras_semanais') .select('dia_semana, hora_inicio, hora_fim, ativo') .eq('tenant_id', tenantId) .eq('ativo', true) .order('dia_semana'); return (data || []).map((r) => ({ dow: r.dia_semana, start: String(r.hora_inicio).slice(0, 5), end: String(r.hora_fim).slice(0, 5) })); } catch { return []; } } return { settings, loading, saving, error, lastLoadedAt, load, save, loadAgendaWindows }; }