create type system_role as enum ('USER', 'SYS_ADMIN');
create type group_role as enum ('MEMBER', 'GROUP_ADMIN');

create table users(
  id bigserial primary key,
  email text not null unique,
  display_name text,
  password_hash text not null,
  system_role system_role not null default 'USER',
  created_at timestamptz not null default now()
);

create table sessions(
  id bigserial primary key,
  user_id bigint not null references users(id) on delete cascade,
  token_hash text not null unique,
  expires_at timestamptz not null,
  created_at timestamptz not null default now()
);

create table groups(
  id bigserial primary key,
  name text not null,
  invite_code text not null unique,
  created_by bigint not null references users(id),
  created_at timestamptz not null default now()
);

create table group_members(
  group_id bigint not null references groups(id) on delete cascade,
  user_id bigint not null references users(id) on delete cascade,
  role group_role not null default 'MEMBER',
  created_at timestamptz not null default now(),
  primary key(group_id, user_id)
);

create type spending_necessity as enum ('NECESSARY', 'BOTH', 'UNNECESSARY');

create table receipts(
  id bigserial primary key,
  content_type text not null,
  bytes bytea not null,
  created_by bigint not null references users(id),
  created_at timestamptz not null default now()
);

create table spendings(
  id bigserial primary key,
  group_id bigint not null references groups(id) on delete cascade,
  created_by bigint not null references users(id),
  amount_dollars numeric(12,2) not null check(amount_dollars >= 0),
  occurred_at date not null,
  necessity spending_necessity not null,
  purchase_type text not null,
  notes text,
  receipt_id bigint references receipts(id) on delete set null,
  created_at timestamptz not null default now()
);

create index idx_spendings_group_occurred on spendings(group_id, occurred_at desc);
create index idx_spendings_receipt on spendings(receipt_id);

create table user_settings(
  user_id bigint primary key references users(id) on delete cascade,
  data jsonb not null default '{}'::jsonb,
  updated_at timestamptz not null default now()
);

create table reports(
  id bigserial primary key,
  created_by bigint not null references users(id),
  title text not null,
  body text not null,
  status text not null default 'OPEN',
  created_at timestamptz not null default now()
);
