-- Cabinet memberships for sharing access

create table if not exists public.cabinet_memberships (
    id uuid default uuid_generate_v4() primary key,
    cabinet_id uuid not null references public.file_cabinets(id) on delete cascade,
    profile_id uuid not null references public.profiles(id) on delete cascade,
    role text not null check (role in ('owner','editor','viewer')),
    created_at timestamp with time zone default timezone('utc'::text, now()),
    updated_at timestamp with time zone default timezone('utc'::text, now()),
    unique(cabinet_id, profile_id)
);

create index if not exists idx_cabinet_memberships_cabinet on public.cabinet_memberships(cabinet_id);
create index if not exists idx_cabinet_memberships_profile on public.cabinet_memberships(profile_id);

-- Updated at trigger
drop trigger if exists trg_cabinet_memberships_updated_at on public.cabinet_memberships;
create trigger trg_cabinet_memberships_updated_at
    before update on public.cabinet_memberships
    for each row execute function public.handle_updated_at();

-- RLS and policies
alter table if exists public.cabinet_memberships enable row level security;

-- Members can select their own memberships; cabinet owners can also see memberships
drop policy if exists cm_read_self_or_owner on public.cabinet_memberships;
create policy cm_read_self_or_owner on public.cabinet_memberships for select to authenticated
using (
  profile_id = auth.uid() or exists (
    select 1 from public.file_cabinets c where c.id = cabinet_memberships.cabinet_id and c.user_id = auth.uid()
  )
);

-- Cabinet owners can insert memberships
drop policy if exists cm_insert_by_owner on public.cabinet_memberships;
create policy cm_insert_by_owner on public.cabinet_memberships for insert to authenticated
with check (exists (
  select 1 from public.file_cabinets c where c.id = cabinet_memberships.cabinet_id and c.user_id = auth.uid()
));

-- Cabinet owners can update memberships (e.g., role)
drop policy if exists cm_update_by_owner on public.cabinet_memberships;
create policy cm_update_by_owner on public.cabinet_memberships for update to authenticated
using (exists (
  select 1 from public.file_cabinets c where c.id = cabinet_memberships.cabinet_id and c.user_id = auth.uid()
))
with check (exists (
  select 1 from public.file_cabinets c where c.id = cabinet_memberships.cabinet_id and c.user_id = auth.uid()
));

-- Cabinet owners can delete memberships
drop policy if exists cm_delete_by_owner on public.cabinet_memberships;
create policy cm_delete_by_owner on public.cabinet_memberships for delete to authenticated
using (exists (
  select 1 from public.file_cabinets c where c.id = cabinet_memberships.cabinet_id and c.user_id = auth.uid()
));

-- Extend access to cabinets/files for members (after table exists)
drop policy if exists "User can access cabinets via membership" on public.file_cabinets;
create policy "User can access cabinets via membership" on public.file_cabinets for select to authenticated
using (exists (
  select 1 from public.cabinet_memberships m
  where m.cabinet_id = file_cabinets.id and m.profile_id = auth.uid()
));

drop policy if exists "User can access files via membership" on public.files;
create policy "User can access files via membership" on public.files for select to authenticated
using (exists (
  select 1 from public.cabinet_memberships m
  where m.cabinet_id = files.cabinet_id and m.profile_id = auth.uid()
));


