create table if not exists public.tenant_classes (
  id uuid primary key default gen_random_uuid(),
  tenant_id uuid not null references public.tenants(id) on delete cascade,
  region_id uuid references public.regions(id) on delete set null,
  legacy_id text,
  code text,
  name text not null,
  description text,
  status text not null default 'active' check (status in ('active', 'disabled', 'archived')),
  sort_order integer not null default 0,
  metadata jsonb not null default '{}'::jsonb,
  created_by uuid references public.platform_users(id) on delete set null,
  updated_by uuid references public.platform_users(id) on delete set null,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now(),
  unique (tenant_id, id),
  unique (tenant_id, legacy_id)
);

comment on table public.tenant_classes is
  'Tenant-scoped class/cohort records used for teacher, head-teacher, assistant and student data scopes.';

create unique index if not exists idx_tenant_classes_code_unique
  on public.tenant_classes(tenant_id, lower(code))
  where code is not null and code <> '';

create index if not exists idx_tenant_classes_tenant_status
  on public.tenant_classes(tenant_id, status, sort_order, created_at desc);

create index if not exists idx_tenant_classes_region
  on public.tenant_classes(tenant_id, region_id)
  where region_id is not null;

create table if not exists public.tenant_class_members (
  id uuid primary key default gen_random_uuid(),
  tenant_id uuid not null references public.tenants(id) on delete cascade,
  class_id uuid not null,
  user_id uuid not null references public.platform_users(id) on delete cascade,
  member_type text not null check (member_type in ('student', 'teacher', 'assistant', 'head_teacher')),
  status text not null default 'active' check (status in ('active', 'disabled', 'removed')),
  joined_at timestamptz not null default now(),
  left_at timestamptz,
  metadata jsonb not null default '{}'::jsonb,
  created_by uuid references public.platform_users(id) on delete set null,
  updated_by uuid references public.platform_users(id) on delete set null,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now(),
  unique (tenant_id, class_id, user_id, member_type),
  foreign key (tenant_id, class_id) references public.tenant_classes(tenant_id, id) on delete cascade
);

comment on table public.tenant_class_members is
  'Class membership assignments. Students can belong to multiple classes; teachers gain scoped visibility through active class memberships.';

create index if not exists idx_class_members_tenant_class
  on public.tenant_class_members(tenant_id, class_id, status, member_type);

create index if not exists idx_class_members_tenant_user
  on public.tenant_class_members(tenant_id, user_id, status, member_type);

alter table public.tenant_classes enable row level security;
alter table public.tenant_class_members enable row level security;

drop policy if exists tenant_isolation on public.tenant_classes;
create policy tenant_isolation on public.tenant_classes
  for all
  using (tenant_id = app.current_tenant_id() or app.is_platform_admin())
  with check (tenant_id = app.current_tenant_id() or app.is_platform_admin());

drop policy if exists tenant_isolation on public.tenant_class_members;
create policy tenant_isolation on public.tenant_class_members
  for all
  using (tenant_id = app.current_tenant_id() or app.is_platform_admin())
  with check (tenant_id = app.current_tenant_id() or app.is_platform_admin());

drop trigger if exists set_updated_at on public.tenant_classes;
create trigger set_updated_at
  before update on public.tenant_classes
  for each row
  execute function app.touch_updated_at();

drop trigger if exists set_updated_at on public.tenant_class_members;
create trigger set_updated_at
  before update on public.tenant_class_members
  for each row
  execute function app.touch_updated_at();
