-- Timestamps are declared `timestamp` and hold UTC 'YYYY-MM-DD HH:MM:SS': the declared type is what
-- makes the driver hand them back as time.Time, and a fixed-width UTC string is what makes
-- `order by created_at` and `expires_at > datetime('now')` mean what they say.

create table users (
    id            integer   primary key autoincrement,
    name          text      not null,
    email         text      not null unique,
    password_hash text      not null,
    avatar        text,
    banned        integer   not null default 0,
    created_at    timestamp not null default (datetime('now'))
);

create table sessions (
    token      text      primary key,
    user_id    integer   not null references users (id) on delete cascade,
    idle_ttl   integer   not null, -- seconds; SQLite has no interval type
    expires_at timestamp not null,
    created_at timestamp not null default (datetime('now'))
);

create index sessions_user on sessions (user_id);

create table invites (
    id         integer   primary key autoincrement,
    code       text      not null unique,
    is_valid   integer   not null default 1,
    created_at timestamp not null default (datetime('now'))
);

create table songs (
    id               integer   primary key autoincrement,
    title            text      not null,
    artist           text      not null,
    genre            text      not null,
    description      text,
    -- LRC or plain text, told apart by whether the first line starts with '['. Not covered by the
    -- lock: nobody reviewed the lyrics.
    lyrics           text,
    audio_file       text      not null,
    duration_seconds integer   not null,
    source_url       text,
    submitted_by     integer   not null references users (id),
    created_at       timestamp not null default (datetime('now'))
);

create index songs_created_at on songs (created_at desc);

create table submissions (
    id          integer   primary key autoincrement,
    user_id     integer   not null references users (id) on delete cascade,
    status      text      not null default 'queued',
    status_msg  text,
    source_url  text,
    tmp_path    text,
    title       text,
    artist      text,
    genre       text,
    description text,
    lyrics      text,
    created_at  timestamp not null default (datetime('now')),
    constraint submissions_status check (
        status in ('queued', 'downloading', 'converting', 'ready', 'failed')
    )
);

-- The submission quota (5 per rolling 24h, failures excluded) reads this.
create index submissions_user_created on submissions (user_id, created_at desc);

create table reviews (
    id          integer   primary key autoincrement,
    song_id     integer   not null references songs (id) on delete cascade,
    reviewer_id integer   not null references users (id),
    score       integer   not null check (score between 1 and 100),
    text        text      not null,
    created_at  timestamp not null default (datetime('now')),
    updated_at  timestamp not null default (datetime('now')),
    unique (song_id, reviewer_id)
);

create index reviews_song on reviews (song_id);

-- The queue asks "songs this member has not reviewed" — that lookup is by reviewer.
create index reviews_reviewer_song on reviews (reviewer_id, song_id);

create table reports (
    id          integer   primary key autoincrement,
    user_id     integer   not null references users (id) on delete cascade,
    body        text      not null,
    page        text,
    user_agent  text,
    resolved_at timestamp,
    created_at  timestamp not null default (datetime('now'))
);
