-- ==========================================================================
-- Agencia PSI — Migracao: Bot de auto-triagem WhatsApp (Grupo 3.7)
-- ==========================================================================
-- Criado por: Leonardo Nohama
-- Data: 2026-04-23 · Sao Carlos/SP — Brasil
--
-- Bot que coleta nome + motivo + preferencias antes de encaminhar o
-- paciente pro fluxo humano. Evita que terapeuta tenha que fazer
-- perguntas basicas toda vez que chega um lead novo no WhatsApp.
--
-- Modelo:
--   conversation_bots             → config (1 por tenant)
--   conversation_bot_sessions     → estado ativo por thread
--
-- Fluxo:
--   1. Paciente novo manda inbound
--   2. Edge evolution-whatsapp-inbound cria session no step 0 e envia
--      greeting + primeira pergunta (steps[0].prompt)
--   3. Proxima inbound: salva resposta em collected_data[steps[0].variable],
--      avanca step, envia proxima pergunta
--   4. Quando passa do ultimo step: envia closing_message, marca session
--      como 'completed', cria conversation_note com resumo das respostas
--
-- Interrupcoes:
--   - Paciente pede opt-out (keywords) → bot sai, session 'opted_out'
--   - Humano assume a conversa (conversation_assignments) → bot sai, 'abandoned_manual'
--   - Session sem resposta > idle_timeout → 'abandoned_idle' (job futuro)
--
-- UNIQUE parcial garante 1 sessao ativa por thread.
-- ==========================================================================

-- ---------------------------------------------------------------------------
-- Tabela: conversation_bots (config)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS public.conversation_bots (
    tenant_id UUID PRIMARY KEY REFERENCES public.tenants(id) ON DELETE CASCADE,

    enabled BOOLEAN NOT NULL DEFAULT false,

    greeting_message TEXT NOT NULL DEFAULT 'Olá! 👋 Sou o assistente virtual. Vou te fazer algumas perguntas rápidas pra a equipe preparar seu atendimento.',
    closing_message TEXT NOT NULL DEFAULT 'Obrigado! Recebemos suas informações e a equipe entrará em contato em breve. 💙',

    -- Array de steps: [{ "prompt": "...", "variable": "...", "type": "text" }]
    steps JSONB NOT NULL DEFAULT jsonb_build_array(
        jsonb_build_object('prompt', 'Qual seu nome completo?', 'variable', 'nome_completo', 'type', 'text'),
        jsonb_build_object('prompt', 'O que te levou a buscar atendimento? Pode me contar brevemente.', 'variable', 'motivo', 'type', 'text'),
        jsonb_build_object('prompt', 'Prefere atendimento online ou presencial?', 'variable', 'modalidade', 'type', 'text'),
        jsonb_build_object('prompt', 'Qual o melhor dia e horário pra você? (Ex: terça à tarde)', 'variable', 'horario_preferido', 'type', 'text')
    ),

    -- Gatilho: quem dispara o bot?
    trigger_mode TEXT NOT NULL DEFAULT 'new_contact'
        CHECK (trigger_mode IN ('new_contact', 'all_unassigned', 'keyword')),
    -- Usado quando trigger_mode='keyword'
    trigger_keywords TEXT[] NOT NULL DEFAULT ARRAY[]::TEXT[],

    -- Abandono automatico: se session fica ativa sem avancar por N min
    idle_timeout_minutes INT NOT NULL DEFAULT 30 CHECK (idle_timeout_minutes >= 5 AND idle_timeout_minutes <= 1440),

    -- Se bot deve encerrar quando paciente usa keyword de opt-out
    respect_optout BOOLEAN NOT NULL DEFAULT true,

    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

DROP TRIGGER IF EXISTS trg_conv_bots_updated_at ON public.conversation_bots;
CREATE TRIGGER trg_conv_bots_updated_at
    BEFORE UPDATE ON public.conversation_bots
    FOR EACH ROW EXECUTE FUNCTION public.set_updated_at();

COMMENT ON TABLE public.conversation_bots IS
    'Config do bot de triagem WhatsApp por tenant. steps contem array de perguntas.';


-- ---------------------------------------------------------------------------
-- Tabela: conversation_bot_sessions (estado)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS public.conversation_bot_sessions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
    thread_key TEXT NOT NULL,
    contact_number TEXT,

    current_step INT NOT NULL DEFAULT 0,
    collected_data JSONB NOT NULL DEFAULT '{}'::jsonb,

    status TEXT NOT NULL DEFAULT 'active'
        CHECK (status IN ('active', 'completed', 'abandoned_idle', 'abandoned_manual', 'opted_out')),

    started_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    last_advance_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    completed_at TIMESTAMPTZ,
    abandoned_at TIMESTAMPTZ,

    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

DROP TRIGGER IF EXISTS trg_bot_sessions_updated_at ON public.conversation_bot_sessions;
CREATE TRIGGER trg_bot_sessions_updated_at
    BEFORE UPDATE ON public.conversation_bot_sessions
    FOR EACH ROW EXECUTE FUNCTION public.set_updated_at();

-- 1 sessao ativa por thread
CREATE UNIQUE INDEX IF NOT EXISTS uq_bot_sessions_active_per_thread
    ON public.conversation_bot_sessions (tenant_id, thread_key)
    WHERE status = 'active';

CREATE INDEX IF NOT EXISTS idx_bot_sessions_tenant_status
    ON public.conversation_bot_sessions (tenant_id, status, started_at DESC);

COMMENT ON TABLE public.conversation_bot_sessions IS
    'Estado do bot por thread. UNIQUE parcial garante 1 ativa por (tenant, thread).';


-- ---------------------------------------------------------------------------
-- RLS
-- ---------------------------------------------------------------------------
ALTER TABLE public.conversation_bots ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS "conv_bots: select membros" ON public.conversation_bots;
CREATE POLICY "conv_bots: select membros"
    ON public.conversation_bots
    FOR SELECT TO authenticated
    USING (
        public.is_saas_admin()
        OR EXISTS (
            SELECT 1 FROM public.tenant_members tm
            WHERE tm.tenant_id = conversation_bots.tenant_id
              AND tm.user_id = auth.uid()
              AND tm.status = 'active'
        )
    );

DROP POLICY IF EXISTS "conv_bots: write admins" ON public.conversation_bots;
CREATE POLICY "conv_bots: write admins"
    ON public.conversation_bots
    FOR ALL TO authenticated
    USING (
        public.is_saas_admin()
        OR EXISTS (
            SELECT 1 FROM public.tenant_members tm
            WHERE tm.tenant_id = conversation_bots.tenant_id
              AND tm.user_id = auth.uid()
              AND tm.role IN ('clinic_admin', 'tenant_admin')
              AND tm.status = 'active'
        )
    )
    WITH CHECK (
        public.is_saas_admin()
        OR EXISTS (
            SELECT 1 FROM public.tenant_members tm
            WHERE tm.tenant_id = conversation_bots.tenant_id
              AND tm.user_id = auth.uid()
              AND tm.role IN ('clinic_admin', 'tenant_admin')
              AND tm.status = 'active'
        )
    );


ALTER TABLE public.conversation_bot_sessions ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS "bot_sessions: select membros" ON public.conversation_bot_sessions;
CREATE POLICY "bot_sessions: select membros"
    ON public.conversation_bot_sessions
    FOR SELECT TO authenticated
    USING (
        public.is_saas_admin()
        OR EXISTS (
            SELECT 1 FROM public.tenant_members tm
            WHERE tm.tenant_id = conversation_bot_sessions.tenant_id
              AND tm.user_id = auth.uid()
              AND tm.status = 'active'
        )
    );

DROP POLICY IF EXISTS "bot_sessions: write service_role" ON public.conversation_bot_sessions;
CREATE POLICY "bot_sessions: write service_role"
    ON public.conversation_bot_sessions
    FOR ALL TO service_role
    USING (true) WITH CHECK (true);
