-- Migration 021: delete_account() RPC — Fase 10.5.
--
-- Hard-deletes the caller's account. The content they created stays in the
-- collectives (FKs were relaxed in migration 019 to SET NULL).
--
-- Guard (errcode P0003): if the caller is the only admin of any collective
-- AND no eligible member (member or admin, not guest) exists to be
-- auto-promoted, the deletion is blocked — otherwise the collective ends
-- up with zero admins and nobody can manage it. The user is asked to
-- promote someone manually or kick the remaining non-eligible members.
--
-- Order of deletes matters:
--   1. DELETE FROM public.users — fires `promote_oldest_member_on_admin_leave`
--      (migration 002) BEFORE the cascade removes collective_members. That
--      trigger promotes the oldest non-departing member to admin. Then the
--      cascade removes the user's memberships. Content rows with
--      created_by = v_user fall to NULL.
--   2. DELETE FROM auth.users — cascades sync_conflicts, removes the GoTrue
--      identity. We do NOT touch Keycloak; the user can re-register with a
--      new UUID (documented limitation, see plan/fase-10 §10.5.4).

CREATE OR REPLACE FUNCTION public.delete_account()
RETURNS void
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public, auth
AS $$
DECLARE
    v_user uuid := auth.uid();
    v_blocked boolean;
BEGIN
    IF v_user IS NULL THEN
        RAISE EXCEPTION 'not authenticated' USING ERRCODE = '28000';
    END IF;

    -- Pre-flight: is the user the sole admin of any collective that has
    -- members but no other promotable member?
    SELECT EXISTS (
        SELECT 1
        FROM public.collective_members cm
        WHERE cm.user_id = v_user
        AND   cm.role = 'admin'
        -- More than one member in the collective
        AND   (SELECT count(*) FROM public.collective_members c2
               WHERE c2.collective_id = cm.collective_id) > 1
        -- And nobody else is admin OR member (only guests + the caller)
        AND   NOT EXISTS (
            SELECT 1 FROM public.collective_members c3
            WHERE c3.collective_id = cm.collective_id
            AND   c3.user_id <> v_user
            AND   c3.role IN ('admin', 'member')
        )
    ) INTO v_blocked;

    IF v_blocked THEN
        RAISE EXCEPTION 'sole admin with non-promotable members'
            USING ERRCODE = 'P0003';
    END IF;

    -- Step 1: public.users — trigger promotes oldest member if needed,
    -- then cascade clears collective_members, SET NULL on content FKs.
    DELETE FROM public.users WHERE id = v_user;

    -- Step 2: auth.users — sweeps sync_conflicts (CASCADE) + GoTrue row.
    DELETE FROM auth.users WHERE id = v_user;
END;
$$;

REVOKE ALL ON FUNCTION public.delete_account() FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.delete_account() TO authenticated;
