-- GNEFSHNG - Row Level Security Policies

-- Enable RLS on all tables
ALTER TABLE staff_users ENABLE ROW LEVEL SECURITY;
ALTER TABLE variant_sizes ENABLE ROW LEVEL SECURITY;
ALTER TABLE variant_colors ENABLE ROW LEVEL SECURITY;
ALTER TABLE products ENABLE ROW LEVEL SECURITY;
ALTER TABLE product_variants ENABLE ROW LEVEL SECURITY;
ALTER TABLE product_images ENABLE ROW LEVEL SECURITY;
ALTER TABLE collections ENABLE ROW LEVEL SECURITY;
ALTER TABLE collection_products ENABLE ROW LEVEL SECURITY;
ALTER TABLE carts ENABLE ROW LEVEL SECURITY;
ALTER TABLE cart_items ENABLE ROW LEVEL SECURITY;
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
ALTER TABLE order_items ENABLE ROW LEVEL SECURITY;
ALTER TABLE payments ENABLE ROW LEVEL SECURITY;
ALTER TABLE drops ENABLE ROW LEVEL SECURITY;

-- Helper: check if current user is staff/admin
CREATE OR REPLACE FUNCTION is_admin()
RETURNS BOOLEAN AS $$
BEGIN
  RETURN EXISTS (
    SELECT 1 FROM staff_users
    WHERE auth_user_id = auth.uid()
    AND is_active = true
  );
END;
$$ LANGUAGE plpgsql SECURITY DEFINER STABLE;

-- Helper: check if current user has admin role specifically
CREATE OR REPLACE FUNCTION is_admin_role()
RETURNS BOOLEAN AS $$
BEGIN
  RETURN EXISTS (
    SELECT 1 FROM staff_users
    WHERE auth_user_id = auth.uid()
    AND is_active = true
    AND role = 'admin'
  );
END;
$$ LANGUAGE plpgsql SECURITY DEFINER STABLE;

-- ===== PUBLIC READ POLICIES =====

-- Variant sizes: public read (active only)
CREATE POLICY "variant_sizes_public_read" ON variant_sizes
  FOR SELECT TO anon, authenticated USING (is_active = true);

-- Variant colors: public read (active only)
CREATE POLICY "variant_colors_public_read" ON variant_colors
  FOR SELECT TO anon, authenticated USING (is_active = true);

-- Products: public read (active only)
CREATE POLICY "products_public_read" ON products
  FOR SELECT TO anon, authenticated USING (is_active = true);

-- Product variants: public read (active, parent product active)
CREATE POLICY "product_variants_public_read" ON product_variants
  FOR SELECT TO anon, authenticated USING (
    is_active = true AND
    EXISTS (SELECT 1 FROM products WHERE products.id = product_variants.product_id AND products.is_active = true)
  );

-- Product images: public read (parent product active)
CREATE POLICY "product_images_public_read" ON product_images
  FOR SELECT TO anon, authenticated USING (
    EXISTS (SELECT 1 FROM products WHERE products.id = product_images.product_id AND products.is_active = true)
  );

-- Collections: public read (active only)
CREATE POLICY "collections_public_read" ON collections
  FOR SELECT TO anon, authenticated USING (is_active = true);

-- Collection products: public read
CREATE POLICY "collection_products_public_read" ON collection_products
  FOR SELECT TO anon, authenticated USING (true);

-- Drops: public read (published only)
CREATE POLICY "drops_public_read" ON drops
  FOR SELECT TO anon, authenticated USING (is_published = true);

-- ===== ADMIN POLICIES =====

-- Staff users
CREATE POLICY "staff_admin_select" ON staff_users
  FOR SELECT TO authenticated USING (is_admin());
CREATE POLICY "staff_admin_insert" ON staff_users
  FOR INSERT TO authenticated WITH CHECK (is_admin_role());
CREATE POLICY "staff_admin_update" ON staff_users
  FOR UPDATE TO authenticated USING (is_admin_role());
CREATE POLICY "staff_admin_delete" ON staff_users
  FOR DELETE TO authenticated USING (is_admin_role());

-- Variant sizes: admin write
CREATE POLICY "variant_sizes_admin_all" ON variant_sizes
  FOR SELECT TO authenticated USING (is_admin());
CREATE POLICY "variant_sizes_admin_insert" ON variant_sizes
  FOR INSERT TO authenticated WITH CHECK (is_admin());
CREATE POLICY "variant_sizes_admin_update" ON variant_sizes
  FOR UPDATE TO authenticated USING (is_admin());
CREATE POLICY "variant_sizes_admin_delete" ON variant_sizes
  FOR DELETE TO authenticated USING (is_admin());

-- Variant colors: admin write
CREATE POLICY "variant_colors_admin_all" ON variant_colors
  FOR SELECT TO authenticated USING (is_admin());
CREATE POLICY "variant_colors_admin_insert" ON variant_colors
  FOR INSERT TO authenticated WITH CHECK (is_admin());
CREATE POLICY "variant_colors_admin_update" ON variant_colors
  FOR UPDATE TO authenticated USING (is_admin());
CREATE POLICY "variant_colors_admin_delete" ON variant_colors
  FOR DELETE TO authenticated USING (is_admin());

-- Products: admin full (including inactive)
CREATE POLICY "products_admin_select" ON products
  FOR SELECT TO authenticated USING (is_admin());
CREATE POLICY "products_admin_insert" ON products
  FOR INSERT TO authenticated WITH CHECK (is_admin());
CREATE POLICY "products_admin_update" ON products
  FOR UPDATE TO authenticated USING (is_admin());
CREATE POLICY "products_admin_delete" ON products
  FOR DELETE TO authenticated USING (is_admin());

-- Product variants: admin write
CREATE POLICY "product_variants_admin_select" ON product_variants
  FOR SELECT TO authenticated USING (is_admin());
CREATE POLICY "product_variants_admin_insert" ON product_variants
  FOR INSERT TO authenticated WITH CHECK (is_admin());
CREATE POLICY "product_variants_admin_update" ON product_variants
  FOR UPDATE TO authenticated USING (is_admin());
CREATE POLICY "product_variants_admin_delete" ON product_variants
  FOR DELETE TO authenticated USING (is_admin());

-- Product images: admin write
CREATE POLICY "product_images_admin_select" ON product_images
  FOR SELECT TO authenticated USING (is_admin());
CREATE POLICY "product_images_admin_insert" ON product_images
  FOR INSERT TO authenticated WITH CHECK (is_admin());
CREATE POLICY "product_images_admin_update" ON product_images
  FOR UPDATE TO authenticated USING (is_admin());
CREATE POLICY "product_images_admin_delete" ON product_images
  FOR DELETE TO authenticated USING (is_admin());

-- Collections: admin full
CREATE POLICY "collections_admin_select" ON collections
  FOR SELECT TO authenticated USING (is_admin());
CREATE POLICY "collections_admin_insert" ON collections
  FOR INSERT TO authenticated WITH CHECK (is_admin());
CREATE POLICY "collections_admin_update" ON collections
  FOR UPDATE TO authenticated USING (is_admin());
CREATE POLICY "collections_admin_delete" ON collections
  FOR DELETE TO authenticated USING (is_admin());

-- Collection products: admin write
CREATE POLICY "collection_products_admin_insert" ON collection_products
  FOR INSERT TO authenticated WITH CHECK (is_admin());
CREATE POLICY "collection_products_admin_delete" ON collection_products
  FOR DELETE TO authenticated USING (is_admin());

-- Orders: admin read/update
CREATE POLICY "orders_admin_select" ON orders
  FOR SELECT TO authenticated USING (is_admin());
CREATE POLICY "orders_admin_update" ON orders
  FOR UPDATE TO authenticated USING (is_admin());

-- Order items: admin read
CREATE POLICY "order_items_admin_select" ON order_items
  FOR SELECT TO authenticated USING (is_admin());

-- Payments: admin read
CREATE POLICY "payments_admin_select" ON payments
  FOR SELECT TO authenticated USING (is_admin());

-- Drops: admin full
CREATE POLICY "drops_admin_select" ON drops
  FOR SELECT TO authenticated USING (is_admin());
CREATE POLICY "drops_admin_insert" ON drops
  FOR INSERT TO authenticated WITH CHECK (is_admin());
CREATE POLICY "drops_admin_update" ON drops
  FOR UPDATE TO authenticated USING (is_admin());
CREATE POLICY "drops_admin_delete" ON drops
  FOR DELETE TO authenticated USING (is_admin());

-- Note: carts and cart_items have NO public or anon policies.
-- All cart operations go through service role via server actions.
-- The session_id from the httpOnly cookie is the authorization boundary.
