-- pgTAP: leave_collective() RPC — Fase 10.1
-- Run with: psql -U postgres -d postgres -f supabase/tests/010_leave_collective.sql
--
-- Covers CU-H06:
--   * normal member abandons OK (membership row gone)
--   * sole admin with other members abandons OK + oldest member auto-promoted
--   * sole member rejected with errcode P0001 (must use dissolve_collective)

CREATE EXTENSION IF NOT EXISTS pgtap;

BEGIN;
SELECT plan(7);

-- ── Existence ────────────────────────────────────────────────────────────────
SELECT has_function(
    'public', 'leave_collective', ARRAY['uuid'],
    'public.leave_collective(uuid) RPC exists'
);

-- ── Setup: three test users + two collectives outside seed range ──────────────
INSERT INTO public.users (id, email, display_name, language, avatar_type)
VALUES
    ('e1000000-0000-0000-0000-000000000001', 'leave-admin@local',  'Leave Admin',  'es', 'initials'),
    ('e1000000-0000-0000-0000-000000000002', 'leave-member@local', 'Leave Member', 'es', 'initials'),
    ('e1000000-0000-0000-0000-000000000003', 'leave-solo@local',   'Leave Solo',   'es', 'initials')
ON CONFLICT (id) DO NOTHING;

-- Collective A: admin + member. created_by = Borja (so deleting admin row is safe).
INSERT INTO public.collectives (id, name, emoji, created_by)
VALUES ('cccccccc-1111-1111-1111-111111111111', 'Leave test A', '🚪',
        '22222222-2222-2222-2222-222222222222')
ON CONFLICT (id) DO NOTHING;

INSERT INTO public.collective_members (collective_id, user_id, role, joined_at)
VALUES
    ('cccccccc-1111-1111-1111-111111111111', 'e1000000-0000-0000-0000-000000000001', 'admin',  now() - INTERVAL '10 days'),
    ('cccccccc-1111-1111-1111-111111111111', 'e1000000-0000-0000-0000-000000000002', 'member', now() - INTERVAL '5 days')
ON CONFLICT (collective_id, user_id) DO NOTHING;

-- Collective B: sole member only.
INSERT INTO public.collectives (id, name, emoji, created_by)
VALUES ('cccccccc-2222-2222-2222-222222222222', 'Leave test B (solo)', '🚪',
        '22222222-2222-2222-2222-222222222222')
ON CONFLICT (id) DO NOTHING;

INSERT INTO public.collective_members (collective_id, user_id, role)
VALUES
    ('cccccccc-2222-2222-2222-222222222222', 'e1000000-0000-0000-0000-000000000003', 'admin')
ON CONFLICT (collective_id, user_id) DO NOTHING;

-- ── Case 1: normal member leaves ──────────────────────────────────────────────
-- Authenticate as leave-member
SELECT set_config('request.jwt.claim.sub', 'e1000000-0000-0000-0000-000000000002', true);

SELECT lives_ok(
    $$ SELECT public.leave_collective('cccccccc-1111-1111-1111-111111111111') $$,
    'L-01a: member can leave without error'
);

SELECT is(
    (SELECT count(*)::int FROM public.collective_members
     WHERE collective_id = 'cccccccc-1111-1111-1111-111111111111'
     AND   user_id       = 'e1000000-0000-0000-0000-000000000002'),
    0,
    'L-01a: membership row removed after leave'
);

-- ── Case 2: sole admin with other members ─────────────────────────────────────
-- Re-add the member to set up sole-admin scenario again.
INSERT INTO public.collective_members (collective_id, user_id, role, joined_at)
VALUES ('cccccccc-1111-1111-1111-111111111111',
        'e1000000-0000-0000-0000-000000000002', 'member', now() - INTERVAL '5 days')
ON CONFLICT (collective_id, user_id) DO UPDATE SET role = EXCLUDED.role;

-- Authenticate as the admin
SELECT set_config('request.jwt.claim.sub', 'e1000000-0000-0000-0000-000000000001', true);

SELECT lives_ok(
    $$ SELECT public.leave_collective('cccccccc-1111-1111-1111-111111111111') $$,
    'L-01b: sole admin can leave when other members exist'
);

SELECT is(
    (SELECT role::text FROM public.collective_members
     WHERE collective_id = 'cccccccc-1111-1111-1111-111111111111'
     AND   user_id       = 'e1000000-0000-0000-0000-000000000002'),
    'admin',
    'L-01b: remaining member auto-promoted to admin'
);

SELECT is(
    (SELECT count(*)::int FROM public.collective_members
     WHERE collective_id = 'cccccccc-1111-1111-1111-111111111111'
     AND   user_id       = 'e1000000-0000-0000-0000-000000000001'),
    0,
    'L-01b: departing admin row removed'
);

-- ── Case 3: sole member tries to leave ────────────────────────────────────────
-- Authenticate as leave-solo
SELECT set_config('request.jwt.claim.sub', 'e1000000-0000-0000-0000-000000000003', true);

SELECT throws_ok(
    $$ SELECT public.leave_collective('cccccccc-2222-2222-2222-222222222222') $$,
    'P0001',
    NULL,
    'L-01c: sole member rejected with errcode P0001'
);

SELECT * FROM finish();
ROLLBACK;
