drop table if exists users cascade;
create table users (
	id uuid not null default gen_random_uuid() primary key,
	name text,
	username text not null,
	password_hash text not null,

	created_at timestamp with time zone not null,
	updated_at timestamp with time zone not null,

	check (created_at <= updated_at)
);
drop index if exists users_username_idx;
create index users_username_idx on users (username);
drop index if exists users_username_unique;
create unique index users_username_unique on users (lower(username));

drop table if exists plans cascade;
create table plans (
	id uuid not null default gen_random_uuid() primary key,
	title text,
	created_by uuid not null references users(id),
	start_time timestamp with time zone not null,

	created_at timestamp with time zone not null,
	updated_at timestamp with time zone not null,

	check (created_at <= updated_at)
);

drop type if exists half_hour cascade;
create type half_hour as enum (
	'Hour0Min0',
	'Hour0Min30',
	'Hour1Min0',
	'Hour1Min30',
	'Hour2Min0',
	'Hour2Min30',
	'Hour3Min0',
	'Hour3Min30',
	'Hour4Min0',
	'Hour4Min30',
	'Hour5Min0',
	'Hour5Min30',
	'Hour6Min0',
	'Hour6Min30',
	'Hour7Min0',
	'Hour7Min30',
	'Hour8Min0',
	'Hour8Min30',
	'Hour9Min0',
	'Hour9Min30',
	'Hour10Min0',
	'Hour10Min30',
	'Hour11Min0',
	'Hour11Min30',
	'Hour12Min0',
	'Hour12Min30',
	'Hour13Min0',
	'Hour13Min30',
	'Hour14Min0',
	'Hour14Min30',
	'Hour15Min0',
	'Hour15Min30',
	'Hour16Min0',
	'Hour16Min30',
	'Hour17Min0',
	'Hour17Min30',
	'Hour18Min0',
	'Hour18Min30',
	'Hour19Min0',
	'Hour19Min30',
	'Hour20Min0',
	'Hour20Min30',
	'Hour21Min0',
	'Hour21Min30',
	'Hour22Min0',
	'Hour22Min30',
	'Hour23Min0',
	'Hour23Min30'
);

drop table if exists plan_days cascade;
create table plan_days (
	id uuid not null default gen_random_uuid() primary key,
	plan_id uuid not null references plans(id),
	day_offset smallint not null,
	day_start half_hour not null,
	day_end half_hour not null,

	check (day_offset >= 0),
	unique(plan_id, day_offset)
);

drop table if exists day_tiles cascade;
create table day_tiles (
	day_id uuid not null references plan_days(id),
	user_id uuid not null references users(id),
	tiles half_hour[] not null,
	updated_at timestamp with time zone not null default now(),

	unique(day_id, user_id)
);

drop table if exists login_tokens cascade;
create table login_tokens (
	token text not null primary key,
	user_id uuid not null references users(id),
	created_at timestamp with time zone not null,
	expires_at timestamp with time zone not null,

	check (created_at < expires_at)
);
