-- Migration 006: item_frequency — per-collective item usage tracking.
--
-- Write path: SECURITY DEFINER trigger only. The app role has SELECT access only.
-- Names are normalized (lower + trim) before upsert so "Milk" and "milk" are the same entry.

-- ── item_frequency ────────────────────────────────────────────────────────────

CREATE TABLE public.item_frequency (
    collective_id uuid        NOT NULL REFERENCES public.collectives(id) ON DELETE CASCADE,
    name          text        NOT NULL,   -- normalized: lower(trim(original name))
    use_count     integer     NOT NULL DEFAULT 1,
    last_used_at  timestamptz NOT NULL DEFAULT now(),
    PRIMARY KEY (collective_id, name)
);

ALTER TABLE public.item_frequency ENABLE ROW LEVEL SECURITY;

-- Index for the suggestion query: ordered by use_count descending per collective
CREATE INDEX item_frequency_collective_count_idx
    ON public.item_frequency (collective_id, use_count DESC);

-- ── RLS ───────────────────────────────────────────────────────────────────────

-- Members (any role) can read frequency data for collectives they belong to.
CREATE POLICY item_frequency_select
    ON public.item_frequency FOR SELECT
    USING (public.is_member(collective_id));

-- All direct writes are blocked; the SECURITY DEFINER trigger below is the only
-- write path. This prevents clients from inflating suggestion scores artificially.
CREATE POLICY item_frequency_insert_deny
    ON public.item_frequency FOR INSERT
    WITH CHECK (false);

CREATE POLICY item_frequency_update_deny
    ON public.item_frequency FOR UPDATE
    USING (false);

CREATE POLICY item_frequency_delete_deny
    ON public.item_frequency FOR DELETE
    USING (false);

-- ── Trigger: upsert frequency on shopping_items insert ───────────────────────

CREATE OR REPLACE FUNCTION public.fn_record_item_frequency()
RETURNS TRIGGER
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
    v_collective_id uuid;
BEGIN
    SELECT collective_id INTO v_collective_id
    FROM   public.shopping_lists
    WHERE  id = NEW.list_id;

    INSERT INTO public.item_frequency (collective_id, name, use_count, last_used_at)
    VALUES (v_collective_id, lower(trim(NEW.name)), 1, now())
    ON CONFLICT (collective_id, name) DO UPDATE SET
        use_count    = item_frequency.use_count + 1,
        last_used_at = now();

    RETURN NEW;
END;
$$;

CREATE TRIGGER trg_item_frequency
    AFTER INSERT ON public.shopping_items
    FOR EACH ROW EXECUTE FUNCTION public.fn_record_item_frequency();
