-- ============================================================================
-- Admin audit log — append-only journal of administrative actions. Writes
-- go through an RPC so the insert path is a single choke-point with input
-- validation; reads are admin-only via RLS.
-- ============================================================================
create table public.admin_audit_log (
  id          uuid primary key default gen_random_uuid(),
  actor_id    uuid not null references auth.users(id) on delete set null,
  action      text not null,
  target_type text,
  target_id   text,
  metadata    jsonb not null default '{}'::jsonb,
  created_at  timestamptz not null default now()
);

create index admin_audit_log_created_at_idx on public.admin_audit_log (created_at desc);
create index admin_audit_log_actor_idx on public.admin_audit_log (actor_id);

alter table public.admin_audit_log enable row level security;

create policy audit_log_select_admin on public.admin_audit_log
  for select to authenticated
  using (public.current_user_is_admin());

-- Insert via RPC only — no direct insert policy, so clients can't forge rows
-- with a different actor_id.
create or replace function public.admin_log_action(
  p_action text,
  p_target_type text default null,
  p_target_id text default null,
  p_metadata jsonb default '{}'::jsonb
) returns uuid
language plpgsql
security definer
set search_path = public
as $$
declare
  new_id uuid;
begin
  if not public.current_user_is_admin() then
    raise exception 'not an admin';
  end if;
  insert into public.admin_audit_log (actor_id, action, target_type, target_id, metadata)
    values (auth.uid(), p_action, p_target_type, p_target_id, coalesce(p_metadata, '{}'::jsonb))
    returning id into new_id;
  return new_id;
end;
$$;

revoke all on function public.admin_log_action(text, text, text, jsonb) from public;
grant execute on function public.admin_log_action(text, text, text, jsonb) to authenticated;

-- ============================================================================
-- Admin conversations view — lets admins list every conversation (bypassing
-- is_conversation_member). Read-only: no writes flow through the view.
-- ============================================================================
create policy conversations_select_admin on public.conversations
  for select to authenticated
  using (public.current_user_is_admin());

create policy conversation_members_select_admin on public.conversation_members
  for select to authenticated
  using (public.current_user_is_admin());
