create table if not exists public.profiles (
  id uuid primary key references auth.users(id) on delete cascade,
  display_name text,
  avatar_url text,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now()
);

alter table public.profiles enable row level security;

drop policy if exists "profiles_select_own" on public.profiles;
create policy "profiles_select_own"
  on public.profiles for select to authenticated
  using ((select auth.uid()) = id);

drop policy if exists "profiles_insert_own" on public.profiles;
create policy "profiles_insert_own"
  on public.profiles for insert to authenticated
  with check ((select auth.uid()) = id);

drop policy if exists "profiles_update_own" on public.profiles;
create policy "profiles_update_own"
  on public.profiles for update to authenticated
  using ((select auth.uid()) = id)
  with check ((select auth.uid()) = id);

grant select, insert, update on table public.profiles to authenticated;

-- Keep the profile row in sync with Supabase Auth. The trigger functions live
-- outside the exposed schemas so their SECURITY DEFINER privileges cannot be
-- reached through the Data API or an RPC call.
create schema if not exists catake_private;
revoke all on schema catake_private from public, anon, authenticated;

create or replace function catake_private.handle_new_catake_user()
returns trigger
language plpgsql
security definer
set search_path = ''
as $$
begin
  insert into public.profiles (id, display_name)
  values (new.id, nullif(new.raw_user_meta_data->>'display_name', ''))
  on conflict (id) do update
    set display_name = coalesce(excluded.display_name, public.profiles.display_name),
        updated_at = now();
  return new;
end;
$$;

revoke all on function catake_private.handle_new_catake_user() from public, anon, authenticated;

drop trigger if exists on_auth_user_created_catake on auth.users;
create trigger on_auth_user_created_catake
  after insert on auth.users
  for each row execute function catake_private.handle_new_catake_user();

create or replace function catake_private.touch_catake_profile()
returns trigger
language plpgsql
set search_path = ''
as $$
begin
  new.updated_at = now();
  return new;
end;
$$;

revoke all on function catake_private.touch_catake_profile() from public, anon, authenticated;

drop trigger if exists profiles_updated_at on public.profiles;
create trigger profiles_updated_at
  before update on public.profiles
  for each row execute function catake_private.touch_catake_profile();

-- The project currently contains a helper named rls_auto_enable() that the
-- Supabase security advisor reports as an anonymously executable SECURITY
-- DEFINER function.  It is not part of Catake and must not be callable through
-- the Data API.  Keep this guard idempotent so the migration also works on a
-- fresh project where the helper does not exist.
do $$
begin
  if exists (
    select 1
    from pg_proc p
    join pg_namespace n on n.oid = p.pronamespace
    where n.nspname = 'public'
      and p.proname = 'rls_auto_enable'
      and p.pronargs = 0
  ) then
    execute 'revoke execute on function public.rls_auto_enable() from public, anon, authenticated';
  end if;
end
$$;
