
CREATE TABLE public.board_vote_email_tokens (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  board_vote_id uuid NOT NULL REFERENCES public.board_votes(id) ON DELETE CASCADE,
  board_member_id uuid NOT NULL REFERENCES public.board_members(id) ON DELETE CASCADE,
  token uuid NOT NULL UNIQUE DEFAULT gen_random_uuid(),
  email text NOT NULL,
  member_name text,
  sent_at timestamp with time zone,
  voted_at timestamp with time zone,
  vote_option text,
  created_at timestamp with time zone NOT NULL DEFAULT now(),
  UNIQUE (board_vote_id, board_member_id)
);

CREATE INDEX idx_bvet_token ON public.board_vote_email_tokens(token);
CREATE INDEX idx_bvet_vote ON public.board_vote_email_tokens(board_vote_id);

ALTER TABLE public.board_vote_email_tokens ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Staff manage board vote tokens"
  ON public.board_vote_email_tokens
  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));

CREATE OR REPLACE FUNCTION public.lookup_board_vote_by_token(p_token uuid)
RETURNS TABLE(
  token_id uuid,
  board_vote_id uuid,
  vote_title text,
  vote_description text,
  vote_options text[],
  vote_status text,
  association_name text,
  member_name text,
  email text,
  voted_at timestamp with time zone,
  vote_option text
)
LANGUAGE sql STABLE SECURITY DEFINER SET search_path = public
AS $$
  SELECT t.id, bv.id, bv.title, bv.description, bv.vote_options, bv.status,
         a.name, t.member_name, t.email, t.voted_at, t.vote_option
  FROM public.board_vote_email_tokens t
  JOIN public.board_votes bv ON bv.id = t.board_vote_id
  LEFT JOIN public.associations a ON a.id = bv.association_id
  WHERE t.token = p_token
  LIMIT 1;
$$;

CREATE OR REPLACE FUNCTION public.record_board_vote_by_token(p_token uuid, p_option text)
RETURNS jsonb
LANGUAGE plpgsql SECURITY DEFINER SET search_path = public
AS $$
DECLARE
  v_token RECORD;
  v_vote RECORD;
BEGIN
  SELECT * INTO v_token FROM public.board_vote_email_tokens WHERE token = p_token;
  IF v_token IS NULL THEN
    RETURN jsonb_build_object('ok', false, 'error', 'Invalid token');
  END IF;
  IF v_token.voted_at IS NOT NULL THEN
    RETURN jsonb_build_object('ok', false, 'error', 'Vote already recorded', 'already_voted', true);
  END IF;

  SELECT * INTO v_vote FROM public.board_votes WHERE id = v_token.board_vote_id;
  IF v_vote.status <> 'open' THEN
    RETURN jsonb_build_object('ok', false, 'error', 'Voting is closed for this item');
  END IF;
  IF NOT (p_option = ANY(v_vote.vote_options)) THEN
    RETURN jsonb_build_object('ok', false, 'error', 'Invalid vote option');
  END IF;

  UPDATE public.board_vote_email_tokens
  SET voted_at = now(), vote_option = p_option
  WHERE id = v_token.id;

  RETURN jsonb_build_object('ok', true);
END;
$$;

GRANT EXECUTE ON FUNCTION public.lookup_board_vote_by_token(uuid) TO anon, authenticated;
GRANT EXECUTE ON FUNCTION public.record_board_vote_by_token(uuid, text) TO anon, authenticated;
