BEGIN;
SELECT plan(6);

DO $$
DECLARE
    owner_id uuid := gen_random_uuid();
    member_id uuid := gen_random_uuid();
    tablo_id text;
    parent_task_id text;
BEGIN
    -- Insert auth users
    INSERT INTO auth.users (id, instance_id, aud, role, email, encrypted_password, email_confirmed_at, created_at, updated_at)
    VALUES 
        (owner_id, '00000000-0000-0000-0000-000000000000', 'authenticated', 'authenticated', 'etape_owner_' || owner_id::text || '@test.com', 'encrypted', now(), now(), now()),
        (member_id, '00000000-0000-0000-0000-000000000000', 'authenticated', 'authenticated', 'etape_member_' || member_id::text || '@test.com', 'encrypted', now(), now(), now())
    ON CONFLICT DO NOTHING;

    -- Insert public profiles
    INSERT INTO public.profiles (id, email, first_name, last_name, short_user_id)
    VALUES
        (owner_id, 'etape_owner_' || owner_id::text || '@test.com', 'Etape', 'Owner', substring(owner_id::text from 1 for 8)),
        (member_id, 'etape_member_' || member_id::text || '@test.com', 'Etape', 'Member', substring(member_id::text from 1 for 8))
    ON CONFLICT DO NOTHING;

    -- Create tablo as owner
    PERFORM set_config('request.jwt.claims', json_build_object('sub', owner_id::text)::text, true);
    INSERT INTO public.tablos (owner_id, name, status, position)
    VALUES (owner_id, 'Parent Tasks Test Tablo', 'todo', 0)
    RETURNING id INTO tablo_id;

    -- Grant access to member
    INSERT INTO public.tablo_access (tablo_id, user_id, granted_by, is_active, is_admin)
    VALUES (tablo_id, member_id, owner_id, true, false);

    -- Create an Etape as owner
    INSERT INTO public.tasks (tablo_id, title, description, status, position, is_parent)
    VALUES (tablo_id, 'Initial Étape', 'Owner created etape', 'todo', 0, true)
    RETURNING id INTO parent_task_id;

    -- Persist identifiers for tests
    PERFORM set_config('test.owner_id', owner_id::text, true);
    PERFORM set_config('test.member_id', member_id::text, true);
    PERFORM set_config('test.tablo_id', tablo_id, true);
    PERFORM set_config('test.parent_task_id', parent_task_id, true);
END $$;

SELECT is(
    (SELECT is_parent FROM public.tasks WHERE id = current_setting('test.parent_task_id')),
    true,
    'Owner-created task is flagged as an Etape'
);

SELECT is(
    (SELECT parent_task_id FROM public.tasks WHERE id = current_setting('test.parent_task_id')),
    NULL,
    'Etape cannot reference another parent task'
);

DO $$
BEGIN
    PERFORM set_config('request.jwt.claims', json_build_object('sub', current_setting('test.owner_id'))::text, true);
    UPDATE public.tasks
    SET title = 'Renamed Étape'
    WHERE id = current_setting('test.parent_task_id');
END $$;

SELECT is(
    (SELECT title FROM public.tasks WHERE id = current_setting('test.parent_task_id')),
    'Renamed Étape',
    'Tablo owner can update an Etape'
);

DO $$
DECLARE
    failed boolean := false;
BEGIN
    PERFORM set_config('request.jwt.claims', json_build_object('sub', current_setting('test.member_id'))::text, true);
    BEGIN
        INSERT INTO public.tasks (tablo_id, title, status, position, is_parent)
        VALUES (current_setting('test.tablo_id'), 'Member Étape Attempt', 'todo', 1, true);
    EXCEPTION
        WHEN insufficient_privilege THEN
            failed := true;
        WHEN others THEN
            RAISE;
    END;
    PERFORM set_config('test.member_etape_insert_blocked', failed::text, true);
END $$;

SELECT is(
    current_setting('test.member_etape_insert_blocked', true)::boolean,
    true,
    'Non-owner cannot create an Etape'
);

DO $$
DECLARE
    failed boolean := false;
BEGIN
    PERFORM set_config('request.jwt.claims', json_build_object('sub', current_setting('test.member_id'))::text, true);
    BEGIN
        UPDATE public.tasks
        SET title = 'Member Update Attempt'
        WHERE id = current_setting('test.parent_task_id');
    EXCEPTION
        WHEN insufficient_privilege THEN
            failed := true;
        WHEN others THEN
            RAISE;
    END;
    PERFORM set_config('test.member_etape_update_blocked', failed::text, true);
END $$;

SELECT is(
    current_setting('test.member_etape_update_blocked', true)::boolean,
    true,
    'Non-owner cannot update an Etape'
);

DO $$
DECLARE
    child_task_id text;
BEGIN
    PERFORM set_config('request.jwt.claims', json_build_object('sub', current_setting('test.member_id'))::text, true);
    INSERT INTO public.tasks (tablo_id, title, status, position, is_parent, parent_task_id)
    VALUES (
        current_setting('test.tablo_id'),
        'Child Task',
        'todo',
        2,
        false,
        current_setting('test.parent_task_id')
    )
    RETURNING id INTO child_task_id;

    PERFORM set_config('test.child_task_id', child_task_id, true);
END $$;

SELECT ok(
    (
        SELECT EXISTS (
            SELECT 1 FROM public.tasks WHERE id = current_setting('test.child_task_id')
        )
    ),
    'Members can still create regular tasks assigned to an Etape'
);

SELECT * FROM finish();
ROLLBACK;

