
-- Remove the insecure anon policies
DROP POLICY IF EXISTS "Anon can select own voter record by token" ON public.election_eligible_voters;
DROP POLICY IF EXISTS "Anon can update voted status by token" ON public.election_eligible_voters;

-- Function 1: Lookup voter by vote_token (used on vote page load)
CREATE OR REPLACE FUNCTION public.lookup_voter_by_token(p_vote_token uuid)
RETURNS TABLE(
  id uuid,
  election_id uuid,
  owner_id uuid,
  unit_id uuid,
  has_consent boolean,
  consent_date timestamptz,
  vote_token uuid,
  has_voted boolean,
  voted_at timestamptz,
  created_at timestamptz,
  access_code text
)
LANGUAGE sql
STABLE
SECURITY DEFINER
SET search_path = public
AS $$
  SELECT id, election_id, owner_id, unit_id, has_consent, consent_date,
         vote_token, has_voted, voted_at, created_at, access_code
  FROM public.election_eligible_voters
  WHERE election_eligible_voters.vote_token = p_vote_token
  LIMIT 1;
$$;

-- Function 2: Lookup vote_token by access code
CREATE OR REPLACE FUNCTION public.lookup_voter_by_access_code(p_election_id uuid, p_access_code text)
RETURNS TABLE(vote_token uuid)
LANGUAGE sql
STABLE
SECURITY DEFINER
SET search_path = public
AS $$
  SELECT vote_token
  FROM public.election_eligible_voters
  WHERE election_id = p_election_id
    AND access_code = p_access_code
  LIMIT 1;
$$;

-- Function 3: Mark voter as voted
CREATE OR REPLACE FUNCTION public.mark_voter_as_voted(p_vote_token uuid)
RETURNS void
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
BEGIN
  UPDATE public.election_eligible_voters
  SET has_voted = true, voted_at = now()
  WHERE vote_token = p_vote_token;
END;
$$;
