-- 1. Add new role value
ALTER TYPE public.app_role ADD VALUE IF NOT EXISTS 'master_board_member';

-- 2. Assignments table
CREATE TABLE IF NOT EXISTS public.master_board_assignments (
  id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id UUID NOT NULL,
  association_id UUID NOT NULL REFERENCES public.associations(id) ON DELETE CASCADE,
  created_by UUID,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
  UNIQUE (user_id, association_id)
);

CREATE INDEX IF NOT EXISTS idx_master_board_assignments_user ON public.master_board_assignments(user_id);
CREATE INDEX IF NOT EXISTS idx_master_board_assignments_assoc ON public.master_board_assignments(association_id);

ALTER TABLE public.master_board_assignments ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS "Staff manage master board assignments" ON public.master_board_assignments;
CREATE POLICY "Staff manage master board assignments"
ON public.master_board_assignments
FOR ALL
TO authenticated
USING (public.has_role(auth.uid(), 'admin'::public.app_role) OR public.has_role(auth.uid(), 'manager'::public.app_role))
WITH CHECK (public.has_role(auth.uid(), 'admin'::public.app_role) OR public.has_role(auth.uid(), 'manager'::public.app_role));

DROP POLICY IF EXISTS "Master board members view own assignments" ON public.master_board_assignments;
CREATE POLICY "Master board members view own assignments"
ON public.master_board_assignments
FOR SELECT
TO authenticated
USING (user_id = auth.uid());

-- 3. Helper: is master board member of a given association
CREATE OR REPLACE FUNCTION public.is_master_board_member_of_association(_user_id uuid, _association_id uuid)
RETURNS boolean
LANGUAGE sql
STABLE SECURITY DEFINER
SET search_path TO 'public'
AS $$
  SELECT EXISTS (
    SELECT 1 FROM public.master_board_assignments mba
    WHERE mba.user_id = _user_id
      AND mba.association_id = _association_id
  )
$$;

-- 4. Helper: list master board association ids for a user
CREATE OR REPLACE FUNCTION public.get_master_board_association_ids(_user_id uuid DEFAULT auth.uid())
RETURNS SETOF uuid
LANGUAGE sql
STABLE SECURITY DEFINER
SET search_path TO 'public'
AS $$
  SELECT mba.association_id
  FROM public.master_board_assignments mba
  WHERE mba.user_id = _user_id
$$;

-- 5. Update is_board_member_of_association to also accept master board assignment
CREATE OR REPLACE FUNCTION public.is_board_member_of_association(_user_id uuid, _association_id uuid)
RETURNS boolean
LANGUAGE sql
STABLE SECURITY DEFINER
SET search_path TO 'public'
AS $$
  SELECT EXISTS (
    SELECT 1 FROM public.board_members bm
    WHERE bm.user_id = _user_id AND bm.association_id = _association_id
  )
  OR EXISTS (
    SELECT 1 FROM public.master_board_assignments mba
    WHERE mba.user_id = _user_id AND mba.association_id = _association_id
  )
$$;

-- 6. Update user_belongs_to_association to include master board assignments
CREATE OR REPLACE FUNCTION public.user_belongs_to_association(_user_id uuid, _association_id uuid)
RETURNS boolean
LANGUAGE sql
STABLE SECURITY DEFINER
SET search_path TO 'public'
AS $$
  SELECT
    public.has_role(_user_id, 'admin'::public.app_role)
    OR public.has_role(_user_id, 'manager'::public.app_role)
    OR EXISTS (
      SELECT 1 FROM public.owners o
      WHERE o.user_id = _user_id AND o.association_id = _association_id
    )
    OR EXISTS (
      SELECT 1 FROM public.board_members bm
      WHERE bm.user_id = _user_id AND bm.association_id = _association_id
    )
    OR EXISTS (
      SELECT 1 FROM public.master_board_assignments mba
      WHERE mba.user_id = _user_id AND mba.association_id = _association_id
    )
$$;

-- 7. Update get_user_association_ids to include master board assignments
CREATE OR REPLACE FUNCTION public.get_user_association_ids()
RETURNS SETOF uuid
LANGUAGE sql
STABLE SECURITY DEFINER
SET search_path TO 'public'
AS $$
  SELECT DISTINCT association_id FROM (
    SELECT association_id FROM public.owners WHERE user_id = auth.uid()
    UNION
    SELECT association_id FROM public.board_members WHERE user_id = auth.uid()
    UNION
    SELECT association_id FROM public.master_board_assignments WHERE user_id = auth.uid()
  ) sub
$$;