-- Migration 022: item_tags + shopping_item_tags (Fase 11)
--
-- Tags are scoped to a collective (a string in two collectives = two distinct
-- rows). No hierarchy. Color from an 8-preset palette so the UI can render
-- without a custom picker. The shopping_item_tags many-to-many is enforced by
-- RLS via the parent shopping_items row (which itself uses list_collective_id).
--
-- Reads (select): is_member — guests included, so they see tags too.
-- Writes (insert/update/delete): is_active_member — guests are read-only,
-- matching the policy shape used by shopping_items / shopping_lists.

-- ── item_tags ────────────────────────────────────────────────────────────────

CREATE TABLE public.item_tags (
    id            uuid        PRIMARY KEY DEFAULT gen_random_uuid(),
    collective_id uuid        NOT NULL REFERENCES public.collectives(id) ON DELETE CASCADE,
    name          text        NOT NULL,
    color         text        NOT NULL DEFAULT 'slate'
                              CHECK (color IN ('slate','red','amber','green','sky','indigo','pink','stone')),
    created_at    timestamptz NOT NULL DEFAULT now(),
    UNIQUE (collective_id, name)
);

ALTER TABLE public.item_tags ENABLE ROW LEVEL SECURITY;

CREATE INDEX item_tags_collective_idx ON public.item_tags (collective_id);

CREATE POLICY item_tags_select
    ON public.item_tags FOR SELECT
    USING (public.is_member(collective_id));

CREATE POLICY item_tags_insert
    ON public.item_tags FOR INSERT
    WITH CHECK (public.is_active_member(collective_id));

CREATE POLICY item_tags_update
    ON public.item_tags FOR UPDATE
    USING  (public.is_active_member(collective_id))
    WITH CHECK (public.is_active_member(collective_id));

CREATE POLICY item_tags_delete
    ON public.item_tags FOR DELETE
    USING (public.is_active_member(collective_id));

-- ── shopping_item_tags ───────────────────────────────────────────────────────

CREATE TABLE public.shopping_item_tags (
    item_id uuid NOT NULL REFERENCES public.shopping_items(id) ON DELETE CASCADE,
    tag_id  uuid NOT NULL REFERENCES public.item_tags(id) ON DELETE CASCADE,
    PRIMARY KEY (item_id, tag_id)
);

ALTER TABLE public.shopping_item_tags ENABLE ROW LEVEL SECURITY;

CREATE INDEX shopping_item_tags_tag_idx ON public.shopping_item_tags (tag_id);

-- Helper: resolve the collective for a shopping_items row.
-- STABLE + SECURITY DEFINER mirrors public.list_collective_id (Migration 005).
-- We inline it here rather than chain two calls inside policies so the planner
-- gets a single STABLE function call per row.
CREATE OR REPLACE FUNCTION public.item_collective_id(p_item_id uuid)
RETURNS uuid
LANGUAGE sql
STABLE
SECURITY DEFINER
SET search_path = public
AS $$
    SELECT sl.collective_id
    FROM   public.shopping_items si
    JOIN   public.shopping_lists sl ON sl.id = si.list_id
    WHERE  si.id = p_item_id;
$$;

CREATE POLICY shopping_item_tags_select
    ON public.shopping_item_tags FOR SELECT
    USING (public.is_member(public.item_collective_id(item_id)));

CREATE POLICY shopping_item_tags_insert
    ON public.shopping_item_tags FOR INSERT
    WITH CHECK (
        public.is_active_member(public.item_collective_id(item_id))
        -- Prevent attaching a tag from a different collective than the item.
        AND public.item_collective_id(item_id) = (
            SELECT collective_id FROM public.item_tags WHERE id = tag_id
        )
    );

CREATE POLICY shopping_item_tags_delete
    ON public.shopping_item_tags FOR DELETE
    USING (public.is_active_member(public.item_collective_id(item_id)));

-- ── Realtime publication ─────────────────────────────────────────────────────
-- Mirror the shape used by migration 007: add both tables and set REPLICA
-- IDENTITY FULL so UPDATE/DELETE events carry the full row (needed for the
-- item-id-based client filtering used by the lists detail view).

ALTER PUBLICATION supabase_realtime ADD TABLE public.item_tags;
ALTER PUBLICATION supabase_realtime ADD TABLE public.shopping_item_tags;

ALTER TABLE public.item_tags          REPLICA IDENTITY FULL;
ALTER TABLE public.shopping_item_tags REPLICA IDENTITY FULL;
