-- ============================================================
--  RLS Policies — Sistema de Recolección Inteligente
--  Ejecutar en: Supabase > SQL Editor
--  Regla innegociable: el ciudadano NUNCA ve coordenadas ni datos ajenos.
-- ============================================================


-- ------------------------------------------------------------
-- 1. Tabla public.users  (espejo de auth.users con rol)
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS public.users (
    id         UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
    email      TEXT,
    phone      TEXT,
    role       TEXT DEFAULT 'citizen'
                   CHECK (role IN ('citizen', 'driver', 'admin')),
    created_at TIMESTAMPTZ DEFAULT NOW()
);

ALTER TABLE public.users ENABLE ROW LEVEL SECURITY;

-- Cada usuario ve y edita solo su propia fila
DROP POLICY IF EXISTS "users_select_own" ON public.users;
CREATE POLICY "users_select_own" ON public.users
    FOR SELECT USING (auth.uid() = id);

DROP POLICY IF EXISTS "users_update_own" ON public.users;
CREATE POLICY "users_update_own" ON public.users
    FOR UPDATE USING (auth.uid() = id);

-- El backend (service_role) inserta al registrar; no necesita policy
-- porque service_role bypasea RLS por diseño.


-- ------------------------------------------------------------
-- 2. Tabla public.addresses
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS public.addresses (
    id              UUID DEFAULT gen_random_uuid() PRIMARY KEY,
    user_id         UUID NOT NULL REFERENCES public.users(id) ON DELETE CASCADE,
    label           TEXT NOT NULL,
    calle           TEXT NOT NULL,
    colonia         TEXT NOT NULL,
    route_id        TEXT NOT NULL,
    verified        BOOLEAN DEFAULT FALSE,
    verified_method TEXT,
    verified_at     TIMESTAMPTZ,
    created_at      TIMESTAMPTZ DEFAULT NOW()
);

ALTER TABLE public.addresses ENABLE ROW LEVEL SECURITY;

-- Ciudadano: solo lee sus domicilios; admin lee todos
DROP POLICY IF EXISTS "addresses_select" ON public.addresses;
CREATE POLICY "addresses_select" ON public.addresses
    FOR SELECT USING (
        auth.uid() = user_id
        OR (SELECT role FROM public.users WHERE id = auth.uid()) = 'admin'
    );

-- Ciudadano solo inserta domicilios propios
DROP POLICY IF EXISTS "addresses_insert" ON public.addresses;
CREATE POLICY "addresses_insert" ON public.addresses
    FOR INSERT WITH CHECK (auth.uid() = user_id);

-- Ciudadano solo modifica los suyos (para verified=true tras OCR)
DROP POLICY IF EXISTS "addresses_update" ON public.addresses;
CREATE POLICY "addresses_update" ON public.addresses
    FOR UPDATE USING (
        auth.uid() = user_id
        OR (SELECT role FROM public.users WHERE id = auth.uid()) = 'admin'
    );


-- ------------------------------------------------------------
-- 3. Tabla public.route_positions  ← ÚNICA QUE TIENE LAT/LNG
--    Solo admin puede leerla. Regla innegociable #1 y #4.
-- ------------------------------------------------------------
ALTER TABLE public.route_positions ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS "route_positions_admin_only" ON public.route_positions;
CREATE POLICY "route_positions_admin_only" ON public.route_positions
    FOR SELECT USING (
        (SELECT role FROM public.users WHERE id = auth.uid()) = 'admin'
    );
-- Sin policy para INSERT/UPDATE/DELETE → el backend usa service_role para el seed.


-- ------------------------------------------------------------
-- 4. Tabla public.notifications
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS public.notifications (
    id        UUID DEFAULT gen_random_uuid() PRIMARY KEY,
    user_id   UUID REFERENCES public.users(id) ON DELETE CASCADE,
    route_id  TEXT,
    type      TEXT,
    payload   JSONB,
    sent_at   TIMESTAMPTZ DEFAULT NOW()
);

ALTER TABLE public.notifications ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS "notifications_select" ON public.notifications;
CREATE POLICY "notifications_select" ON public.notifications
    FOR SELECT USING (
        auth.uid() = user_id
        OR (SELECT role FROM public.users WHERE id = auth.uid()) = 'admin'
    );


-- ------------------------------------------------------------
-- 5. Tabla public.feedback
--    Las quejas van a target_unit_id (unidad), NUNCA al chofer.
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS public.feedback (
    id             UUID DEFAULT gen_random_uuid() PRIMARY KEY,
    user_id        UUID REFERENCES public.users(id) ON DELETE SET NULL,
    address_id     UUID REFERENCES public.addresses(id) ON DELETE SET NULL,
    type           TEXT,
    target_unit_id INT,   -- unidad (no chofer): privacidad del chofer
    message        TEXT,
    rating         SMALLINT CHECK (rating BETWEEN 1 AND 5),
    created_at     TIMESTAMPTZ DEFAULT NOW()
);

ALTER TABLE public.feedback ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS "feedback_select" ON public.feedback;
CREATE POLICY "feedback_select" ON public.feedback
    FOR SELECT USING (
        auth.uid() = user_id
        OR (SELECT role FROM public.users WHERE id = auth.uid()) = 'admin'
    );

DROP POLICY IF EXISTS "feedback_insert" ON public.feedback;
CREATE POLICY "feedback_insert" ON public.feedback
    FOR INSERT WITH CHECK (auth.uid() = user_id);


-- ------------------------------------------------------------
-- 6. Índices útiles para rendimiento
-- ------------------------------------------------------------
CREATE INDEX IF NOT EXISTS idx_addresses_user_id  ON public.addresses(user_id);
CREATE INDEX IF NOT EXISTS idx_addresses_route_id ON public.addresses(route_id);
CREATE INDEX IF NOT EXISTS idx_notifications_user ON public.notifications(user_id);
CREATE INDEX IF NOT EXISTS idx_feedback_user      ON public.feedback(user_id);
