-- =============================================================================
-- Migration: 20260419000018_servicos_prontuarios_hardening
-- Sessão 9 — Serviços/Prontuários scan.
--
-- Resolve:
--   • Serviços V#1+V#2 (CRÍTICOS): silos por owner em services/medicos/insurance_plans
--   • Serviços V#3+V#4 (ALTOS): cascade silos em commitment_services/insurance_plan_services
--   • Serviços V#5: WITH CHECK ausente em commitment_time_logs/determined_*
--
-- Padrão validado em 5 áreas anteriores (Documentos/Financeiro/Comunicação/etc):
-- SELECT tenant_member, INSERT/UPDATE/DELETE owner+saas, com WITH CHECK explícito.
-- =============================================================================

-- ─────────────────────────────────────────────────────────────────────────
-- V#1 services — split em 4 policies
-- -----------------------------------------------------------------------------
DROP POLICY IF EXISTS "services: owner full access" ON public.services;
DROP POLICY IF EXISTS "services: select" ON public.services;
DROP POLICY IF EXISTS "services: insert" ON public.services;
DROP POLICY IF EXISTS "services: update" ON public.services;
DROP POLICY IF EXISTS "services: delete" ON public.services;

CREATE POLICY "services: select" ON public.services
  FOR SELECT TO authenticated
  USING (
    owner_id = auth.uid()
    OR public.is_saas_admin()
    OR tenant_id IN (
      SELECT tm.tenant_id FROM public.tenant_members tm
      WHERE tm.user_id = auth.uid() AND tm.status = 'active'
    )
  );

CREATE POLICY "services: insert" ON public.services
  FOR INSERT TO authenticated
  WITH CHECK (
    owner_id = auth.uid()
    AND tenant_id IN (
      SELECT tm.tenant_id FROM public.tenant_members tm
      WHERE tm.user_id = auth.uid() AND tm.status = 'active'
    )
  );

CREATE POLICY "services: update" ON public.services
  FOR UPDATE TO authenticated
  USING (owner_id = auth.uid() OR public.is_saas_admin())
  WITH CHECK (owner_id = auth.uid() OR public.is_saas_admin());

CREATE POLICY "services: delete" ON public.services
  FOR DELETE TO authenticated
  USING (owner_id = auth.uid() OR public.is_saas_admin());

-- ─────────────────────────────────────────────────────────────────────────
-- V#2 medicos — mesmo padrão
-- -----------------------------------------------------------------------------
DROP POLICY IF EXISTS "medicos: owner full access" ON public.medicos;
DROP POLICY IF EXISTS "medicos: select" ON public.medicos;
DROP POLICY IF EXISTS "medicos: insert" ON public.medicos;
DROP POLICY IF EXISTS "medicos: update" ON public.medicos;
DROP POLICY IF EXISTS "medicos: delete" ON public.medicos;

CREATE POLICY "medicos: select" ON public.medicos
  FOR SELECT TO authenticated
  USING (
    owner_id = auth.uid()
    OR public.is_saas_admin()
    OR tenant_id IN (
      SELECT tm.tenant_id FROM public.tenant_members tm
      WHERE tm.user_id = auth.uid() AND tm.status = 'active'
    )
  );

CREATE POLICY "medicos: insert" ON public.medicos
  FOR INSERT TO authenticated
  WITH CHECK (
    owner_id = auth.uid()
    AND tenant_id IN (
      SELECT tm.tenant_id FROM public.tenant_members tm
      WHERE tm.user_id = auth.uid() AND tm.status = 'active'
    )
  );

CREATE POLICY "medicos: update" ON public.medicos
  FOR UPDATE TO authenticated
  USING (owner_id = auth.uid() OR public.is_saas_admin())
  WITH CHECK (owner_id = auth.uid() OR public.is_saas_admin());

CREATE POLICY "medicos: delete" ON public.medicos
  FOR DELETE TO authenticated
  USING (owner_id = auth.uid() OR public.is_saas_admin());

-- ─────────────────────────────────────────────────────────────────────────
-- V#1 (parte 2) insurance_plans — mesmo padrão
-- -----------------------------------------------------------------------------
DROP POLICY IF EXISTS "insurance_plans: owner full access" ON public.insurance_plans;
DROP POLICY IF EXISTS "insurance_plans: select" ON public.insurance_plans;
DROP POLICY IF EXISTS "insurance_plans: insert" ON public.insurance_plans;
DROP POLICY IF EXISTS "insurance_plans: update" ON public.insurance_plans;
DROP POLICY IF EXISTS "insurance_plans: delete" ON public.insurance_plans;

CREATE POLICY "insurance_plans: select" ON public.insurance_plans
  FOR SELECT TO authenticated
  USING (
    owner_id = auth.uid()
    OR public.is_saas_admin()
    OR tenant_id IN (
      SELECT tm.tenant_id FROM public.tenant_members tm
      WHERE tm.user_id = auth.uid() AND tm.status = 'active'
    )
  );

CREATE POLICY "insurance_plans: insert" ON public.insurance_plans
  FOR INSERT TO authenticated
  WITH CHECK (
    owner_id = auth.uid()
    AND tenant_id IN (
      SELECT tm.tenant_id FROM public.tenant_members tm
      WHERE tm.user_id = auth.uid() AND tm.status = 'active'
    )
  );

CREATE POLICY "insurance_plans: update" ON public.insurance_plans
  FOR UPDATE TO authenticated
  USING (owner_id = auth.uid() OR public.is_saas_admin())
  WITH CHECK (owner_id = auth.uid() OR public.is_saas_admin());

CREATE POLICY "insurance_plans: delete" ON public.insurance_plans
  FOR DELETE TO authenticated
  USING (owner_id = auth.uid() OR public.is_saas_admin());

-- ─────────────────────────────────────────────────────────────────────────
-- V#3 commitment_services — cascade via JOIN com services.tenant_id
-- (tabela N:N sem tenant_id próprio; herda do services pai)
-- -----------------------------------------------------------------------------
DROP POLICY IF EXISTS "commitment_services: owner full access" ON public.commitment_services;
DROP POLICY IF EXISTS "commitment_services: tenant_member" ON public.commitment_services;

CREATE POLICY "commitment_services: tenant_member" ON public.commitment_services
  FOR ALL TO authenticated
  USING (
    EXISTS (
      SELECT 1 FROM public.services s
      WHERE s.id = commitment_services.service_id
        AND (
          s.owner_id = auth.uid()
          OR public.is_saas_admin()
          OR s.tenant_id IN (
            SELECT tm.tenant_id FROM public.tenant_members tm
            WHERE tm.user_id = auth.uid() AND tm.status = 'active'
          )
        )
    )
  )
  WITH CHECK (
    EXISTS (
      SELECT 1 FROM public.services s
      WHERE s.id = commitment_services.service_id
        AND (s.owner_id = auth.uid() OR public.is_saas_admin())
    )
  );

-- ─────────────────────────────────────────────────────────────────────────
-- V#4 insurance_plan_services — cascade via JOIN com insurance_plans
-- -----------------------------------------------------------------------------
DROP POLICY IF EXISTS "insurance_plan_services_owner" ON public.insurance_plan_services;
DROP POLICY IF EXISTS "insurance_plan_services: tenant_member" ON public.insurance_plan_services;

CREATE POLICY "insurance_plan_services: tenant_member" ON public.insurance_plan_services
  FOR ALL TO authenticated
  USING (
    EXISTS (
      SELECT 1 FROM public.insurance_plans ip
      WHERE ip.id = insurance_plan_services.insurance_plan_id
        AND (
          ip.owner_id = auth.uid()
          OR public.is_saas_admin()
          OR ip.tenant_id IN (
            SELECT tm.tenant_id FROM public.tenant_members tm
            WHERE tm.user_id = auth.uid() AND tm.status = 'active'
          )
        )
    )
  )
  WITH CHECK (
    EXISTS (
      SELECT 1 FROM public.insurance_plans ip
      WHERE ip.id = insurance_plan_services.insurance_plan_id
        AND (ip.owner_id = auth.uid() OR public.is_saas_admin())
    )
  );

-- ─────────────────────────────────────────────────────────────────────────
-- V#5 — adicionar WITH CHECK em INSERT das 3 tabelas que não tinham
-- -----------------------------------------------------------------------------
DROP POLICY IF EXISTS ctl_insert_for_active_member ON public.commitment_time_logs;
CREATE POLICY ctl_insert_for_active_member ON public.commitment_time_logs
  FOR INSERT TO authenticated
  WITH CHECK (
    tenant_id IN (
      SELECT tm.tenant_id FROM public.tenant_members tm
      WHERE tm.user_id = auth.uid() AND tm.status = 'active'
    )
  );

DROP POLICY IF EXISTS dcf_insert_for_active_member ON public.determined_commitment_fields;
CREATE POLICY dcf_insert_for_active_member ON public.determined_commitment_fields
  FOR INSERT TO authenticated
  WITH CHECK (
    tenant_id IN (
      SELECT tm.tenant_id FROM public.tenant_members tm
      WHERE tm.user_id = auth.uid() AND tm.status = 'active'
    )
  );

DROP POLICY IF EXISTS dc_insert_for_active_member ON public.determined_commitments;
CREATE POLICY dc_insert_for_active_member ON public.determined_commitments
  FOR INSERT TO authenticated
  WITH CHECK (
    tenant_id IN (
      SELECT tm.tenant_id FROM public.tenant_members tm
      WHERE tm.user_id = auth.uid() AND tm.status = 'active'
    )
  );
