create table if not exists public.tenant_student_notes (
  id uuid primary key default gen_random_uuid(),
  tenant_id uuid not null references public.tenants(id) on delete cascade,
  student_user_id uuid not null references public.platform_users(id) on delete cascade,
  note_type text not null default 'general'
    check (note_type in ('general', 'learning', 'service', 'sales', 'risk', 'follow_up')),
  content text not null,
  visibility text not null default 'tenant_staff'
    check (visibility in ('tenant_staff', 'class_staff', 'author_only')),
  is_pinned boolean not null default false,
  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()
);

comment on table public.tenant_student_notes is
  'Tenant-scoped student operation notes for teachers, class advisers, operators and sales follow-up.';

create index if not exists idx_student_notes_tenant_student
  on public.tenant_student_notes(tenant_id, student_user_id, is_pinned desc, created_at desc);

create index if not exists idx_student_notes_tenant_creator
  on public.tenant_student_notes(tenant_id, created_by, created_at desc)
  where created_by is not null;

create table if not exists public.tenant_student_followups (
  id uuid primary key default gen_random_uuid(),
  tenant_id uuid not null references public.tenants(id) on delete cascade,
  student_user_id uuid not null references public.platform_users(id) on delete cascade,
  assigned_to_user_id uuid references public.platform_users(id) on delete set null,
  class_id uuid,
  title text not null,
  description text,
  followup_type text not null default 'learning'
    check (followup_type in ('learning', 'service', 'sales', 'renewal', 'risk', 'custom')),
  priority text not null default 'normal'
    check (priority in ('low', 'normal', 'high', 'urgent')),
  status text not null default 'open'
    check (status in ('open', 'in_progress', 'done', 'cancelled')),
  due_at timestamptz,
  completed_at timestamptz,
  completed_by uuid references public.platform_users(id) on delete set null,
  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(),
  foreign key (class_id) references public.tenant_classes(id) on delete set null
);

comment on table public.tenant_student_followups is
  'Tenant-scoped student follow-up tasks for learning supervision, service, sales and renewal operations.';

create index if not exists idx_student_followups_tenant_student
  on public.tenant_student_followups(tenant_id, student_user_id, status, due_at nulls last, created_at desc);

create index if not exists idx_student_followups_tenant_assignee
  on public.tenant_student_followups(tenant_id, assigned_to_user_id, status, due_at nulls last)
  where assigned_to_user_id is not null;

create index if not exists idx_student_followups_tenant_class
  on public.tenant_student_followups(tenant_id, class_id, status, due_at nulls last)
  where class_id is not null;

alter table public.tenant_student_notes enable row level security;
alter table public.tenant_student_followups enable row level security;

drop policy if exists tenant_isolation on public.tenant_student_notes;
create policy tenant_isolation on public.tenant_student_notes
  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_student_followups;
create policy tenant_isolation on public.tenant_student_followups
  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_student_notes;
create trigger set_updated_at
  before update on public.tenant_student_notes
  for each row
  execute function app.touch_updated_at();

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