create table if not exists users (
  id text primary key,
  email text not null unique,
  username text not null unique,
  password_hash text not null,
  status text not null,
  created_at timestamptz not null,
  updated_at timestamptz not null
);

create table if not exists admin_users (
  id text primary key,
  email text not null unique,
  password_hash text not null,
  role text not null,
  status text not null,
  created_at timestamptz not null,
  updated_at timestamptz not null
);

create table if not exists accounts (
  id text primary key,
  user_id text not null unique references users(id) on delete cascade,
  account_number text not null unique,
  currency char(3) not null,
  status text not null,
  created_at timestamptz not null
);

create table if not exists transactions (
  id text primary key,
  type text not null,
  status text not null,
  reference text not null unique,
  initiated_by_user_id text references users(id),
  initiated_by_admin_id text references admin_users(id),
  description text not null default '',
  created_at timestamptz not null
);

create table if not exists ledger_entries (
  id text primary key,
  transaction_id text not null references transactions(id) on delete cascade,
  account_id text not null references accounts(id) on delete cascade,
  entry_type text not null,
  amount_minor bigint not null check (amount_minor > 0),
  created_at timestamptz not null
);

create table if not exists user_sessions (
  id text primary key,
  user_id text not null references users(id) on delete cascade,
  token_hash text not null unique,
  expires_at timestamptz not null,
  created_at timestamptz not null
);

create table if not exists admin_sessions (
  id text primary key,
  admin_user_id text not null references admin_users(id) on delete cascade,
  token_hash text not null unique,
  expires_at timestamptz not null,
  created_at timestamptz not null
);

create table if not exists audit_logs (
  id text primary key,
  actor_admin_id text not null references admin_users(id),
  action text not null,
  target_type text not null,
  target_id text not null,
  metadata jsonb not null default '{}'::jsonb,
  created_at timestamptz not null
);

create index if not exists idx_accounts_account_number on accounts(account_number);
create index if not exists idx_ledger_entries_account_id_created_at on ledger_entries(account_id, created_at desc);
create index if not exists idx_transactions_created_at on transactions(created_at desc);
create index if not exists idx_user_sessions_token_hash on user_sessions(token_hash);
create index if not exists idx_admin_sessions_token_hash on admin_sessions(token_hash);
create index if not exists idx_audit_logs_created_at on audit_logs(created_at desc);
