begin;

create extension "basejump-supabase_test_helpers" version '0.0.6';

select no_plan();

-- =====================================================
-- Audit Trigger & Version Tests
-- Verifies triggers fire correctly on member changes
-- =====================================================

-- Setup
select tests.create_supabase_user('audit_owner', 'audit_owner@test.com');
select makerkit.set_identifier('audit_owner', 'audit_owner@test.com');

set local role service_role;
select public.create_team_account('Audit Verein', tests.get_supabase_uid('audit_owner'));

set local role postgres;
insert into public.role_permissions (role, permission)
values ('owner', 'members.write')
on conflict do nothing;

-- Get account ID
select makerkit.authenticate_as('audit_owner');

-- Insert a member (triggers audit INSERT)
set local role service_role;
insert into public.members (
  account_id, first_name, last_name, status, entry_date, member_number,
  created_by, updated_by
) values (
  (select id from public.accounts where slug = 'audit-verein' limit 1),
  'Audit', 'Test', 'active', current_date, '0001',
  tests.get_supabase_uid('audit_owner'),
  tests.get_supabase_uid('audit_owner')
);

-- -------------------------------------------------------
-- Test: INSERT creates audit entry
-- -------------------------------------------------------
select isnt_empty(
  $$ select * from public.member_audit_log
     where member_id = (select id from public.members where first_name = 'Audit' limit 1)
       and action = 'created' $$,
  'Member INSERT creates audit entry with action=created'
);

-- -------------------------------------------------------
-- Test: Version starts at 1
-- -------------------------------------------------------
select is(
  (select version from public.members where first_name = 'Audit' limit 1),
  1,
  'Initial version is 1'
);

-- -------------------------------------------------------
-- Test: UPDATE increments version
-- -------------------------------------------------------
update public.members
set first_name = 'AuditUpdated'
where first_name = 'Audit';

select is(
  (select version from public.members where first_name = 'AuditUpdated' limit 1),
  2,
  'Version incremented to 2 after update'
);

-- -------------------------------------------------------
-- Test: UPDATE creates audit entry with field diff
-- -------------------------------------------------------
select isnt_empty(
  $$ select * from public.member_audit_log
     where member_id = (select id from public.members where first_name = 'AuditUpdated' limit 1)
       and action = 'updated'
       and changes ? 'first_name' $$,
  'Member UPDATE creates audit entry with first_name change diff'
);

-- -------------------------------------------------------
-- Test: Status change creates status_changed audit entry
-- -------------------------------------------------------
update public.members
set status = 'inactive'
where first_name = 'AuditUpdated';

select isnt_empty(
  $$ select * from public.member_audit_log
     where member_id = (select id from public.members where first_name = 'AuditUpdated' limit 1)
       and action = 'status_changed' $$,
  'Status change creates audit entry with action=status_changed'
);

-- -------------------------------------------------------
-- Test: Archive creates archived audit entry
-- -------------------------------------------------------
update public.members
set is_archived = true
where first_name = 'AuditUpdated';

select isnt_empty(
  $$ select * from public.member_audit_log
     where member_id = (select id from public.members where first_name = 'AuditUpdated' limit 1)
       and action = 'archived' $$,
  'Archive creates audit entry with action=archived'
);

-- -------------------------------------------------------
-- Test: Multiple updates increment version correctly
-- -------------------------------------------------------
select is(
  (select version from public.members where first_name = 'AuditUpdated' limit 1),
  4,
  'Version is 4 after 3 updates (initial insert + 3 updates)'
);

select * from finish();

rollback;
