-- ==========================================================================
-- Agencia PSI — Migracao: Opt-out de conversas (CRM Grupo 5.2, LGPD)
-- ==========================================================================
-- Criado por: Leonardo Nohama
-- Data: 2026-04-21 · Sao Carlos/SP — Brasil
--
-- Quando paciente envia keyword de opt-out (PARAR, SAIR, CANCELAR, STOP...),
-- bloqueia envios automaticos (auto-reply + futuros lembretes).
--
-- LGPD: direito de oposicao (Art. 18, §2). Pedido de interrupcao deve ser
-- respeitado. Mensagens manuais do terapeuta nao sao bloqueadas — relacao
-- terapeutica existe.
--
-- Phone e normalizado (apenas digitos) pra matching consistente.
-- ==========================================================================

CREATE TABLE IF NOT EXISTS public.conversation_optouts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
    phone TEXT NOT NULL CHECK (phone ~ '^\d{6,15}$'),
    patient_id UUID REFERENCES public.patients(id) ON DELETE SET NULL,

    -- 'keyword' = detectado automaticamente por palavra-chave
    -- 'manual' = adicionado manualmente pelo terapeuta/admin
    source TEXT NOT NULL DEFAULT 'keyword'
        CHECK (source IN ('keyword', 'manual')),

    keyword_matched TEXT,       -- palavra/frase que disparou (quando source='keyword')
    original_message TEXT,      -- texto completo da msg original (truncado)
    notes TEXT,                 -- observacao do terapeuta (quando manual)

    blocked_by UUID REFERENCES auth.users(id) ON DELETE SET NULL,  -- quem adicionou manual

    opted_out_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    opted_back_in_at TIMESTAMPTZ,  -- quando usuario restaurou (opt-in)

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

-- Unique: um registro ativo por tenant+phone. Permite historico se fizer opt-in e depois opt-out de novo.
-- Active = opted_back_in_at IS NULL
CREATE UNIQUE INDEX IF NOT EXISTS uq_conv_optouts_active
    ON public.conversation_optouts (tenant_id, phone)
    WHERE opted_back_in_at IS NULL;

CREATE INDEX IF NOT EXISTS idx_conv_optouts_tenant_phone
    ON public.conversation_optouts (tenant_id, phone);

CREATE INDEX IF NOT EXISTS idx_conv_optouts_patient
    ON public.conversation_optouts (patient_id)
    WHERE patient_id IS NOT NULL;

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

COMMENT ON TABLE public.conversation_optouts IS
    'Numeros que pediram pra nao receber mensagens automaticas. LGPD Art. 18 Sec.2.';

-- ---------------------------------------------------------------------------
-- Keywords de opt-out — lista do tenant (reutilizavel)
-- Cada tenant pode customizar suas palavras-chave. Default aplicado via seed.
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS public.conversation_optout_keywords (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES public.tenants(id) ON DELETE CASCADE,  -- NULL = system (todos)
    keyword TEXT NOT NULL CHECK (length(keyword) > 0 AND length(keyword) <= 100),
    enabled BOOLEAN NOT NULL DEFAULT true,
    is_system BOOLEAN NOT NULL DEFAULT false,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_conv_optout_kw_tenant
    ON public.conversation_optout_keywords (tenant_id)
    WHERE enabled = true;

-- Seed keywords padrao (system, tenant_id NULL, todos veem)
INSERT INTO public.conversation_optout_keywords (tenant_id, keyword, is_system, enabled) VALUES
    (NULL, 'parar',              true, true),
    (NULL, 'sair',                true, true),
    (NULL, 'cancelar',            true, true),
    (NULL, 'stop',                true, true),
    (NULL, 'descadastrar',        true, true),
    (NULL, 'remover',             true, true),
    (NULL, 'nao quero mais',      true, true),
    (NULL, 'não quero mais',      true, true),
    (NULL, 'desinscrever',        true, true),
    (NULL, 'unsubscribe',         true, true)
ON CONFLICT DO NOTHING;

COMMENT ON TABLE public.conversation_optout_keywords IS
    'Palavras-chave que disparam opt-out quando paciente envia. Sistema (tenant_id NULL) + custom do tenant.';

-- ---------------------------------------------------------------------------
-- RLS: optouts
-- ---------------------------------------------------------------------------
ALTER TABLE public.conversation_optouts ENABLE ROW LEVEL SECURITY;

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

DROP POLICY IF EXISTS "optouts: insert" ON public.conversation_optouts;
CREATE POLICY "optouts: insert"
    ON public.conversation_optouts
    FOR INSERT
    TO authenticated
    WITH CHECK (
        public.is_saas_admin()
        OR EXISTS (
            SELECT 1 FROM public.tenant_members tm
            WHERE tm.user_id = auth.uid()
              AND tm.tenant_id = conversation_optouts.tenant_id
              AND tm.status = 'active'
        )
    );

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

-- ---------------------------------------------------------------------------
-- RLS: keywords
-- ---------------------------------------------------------------------------
ALTER TABLE public.conversation_optout_keywords ENABLE ROW LEVEL SECURITY;

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

DROP POLICY IF EXISTS "optout_kw: insert custom" ON public.conversation_optout_keywords;
CREATE POLICY "optout_kw: insert custom"
    ON public.conversation_optout_keywords
    FOR INSERT
    TO authenticated
    WITH CHECK (
        tenant_id IS NOT NULL
        AND is_system = false
        AND (
            public.is_saas_admin()
            OR EXISTS (
                SELECT 1 FROM public.tenant_members tm
                WHERE tm.user_id = auth.uid()
                  AND tm.tenant_id = conversation_optout_keywords.tenant_id
                  AND tm.status = 'active'
            )
        )
    );

DROP POLICY IF EXISTS "optout_kw: update/delete custom" ON public.conversation_optout_keywords;
CREATE POLICY "optout_kw: update/delete custom"
    ON public.conversation_optout_keywords
    FOR UPDATE
    TO authenticated
    USING (
        is_system = false
        AND tenant_id IS NOT NULL
        AND (
            public.is_saas_admin()
            OR EXISTS (
                SELECT 1 FROM public.tenant_members tm
                WHERE tm.user_id = auth.uid()
                  AND tm.tenant_id = conversation_optout_keywords.tenant_id
                  AND tm.status = 'active'
            )
        )
    );

DROP POLICY IF EXISTS "optout_kw: delete custom" ON public.conversation_optout_keywords;
CREATE POLICY "optout_kw: delete custom"
    ON public.conversation_optout_keywords
    FOR DELETE
    TO authenticated
    USING (
        is_system = false
        AND tenant_id IS NOT NULL
        AND (
            public.is_saas_admin()
            OR EXISTS (
                SELECT 1 FROM public.tenant_members tm
                WHERE tm.user_id = auth.uid()
                  AND tm.tenant_id = conversation_optout_keywords.tenant_id
                  AND tm.status = 'active'
            )
        )
    );

-- ==========================================================================
-- FIM DA MIGRACAO
-- ==========================================================================
