// SPDX-FileCopyrightText: 2024 Manuel Alcaraz Zambrano <manuel@alcarazzam.dev>
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QString>

using namespace Qt::StringLiterals;

constexpr auto SQLITE_NOTADB = "26"_L1;

// SQLite Application ID
constexpr int CHESSAMENT_MAGIC_APPLICATION_ID = 937847437;

constexpr auto ENABLE_FOREIGN_KEYS_QUERY = "PRAGMA foreign_keys = ON;"_L1;

const QString TOURNAMENTS_TABLE_SCHEMA =
    u"CREATE TABLE IF NOT EXISTS tournaments("_s
    u"id TEXT PRIMARY KEY"_s
    u");"_s;

const QString ADD_TOURNAMENT_QUERY = u"INSERT INTO tournaments(id) VALUES (:id);"_s;

const QString GET_TOURNAMENTS_QUERY = u"SELECT * FROM tournaments;"_s;

const QString OPTIONS_TABLE_SCHEMA =
    u"CREATE TABLE IF NOT EXISTS options("_s
    u"tournament TEXT NOT NULL,"_s
    u"name TEXT NOT NULL,"_s
    u"value TEXT,"_s
    u"PRIMARY KEY (tournament, name),"_s
    u"FOREIGN KEY (tournament) REFERENCES tournaments(id)"_s
    u");"_s;

const QString GET_OPTION_QUERY = u"SELECT value FROM options WHERE tournament = :tournament AND name = :name LIMIT 1;"_s;

const QString UPDATE_OPTION_QUERY = u"INSERT OR REPLACE INTO options(tournament, name, value) VALUES (:tournament, :name, :value);"_s;

const QString PLAYERS_TABLE_SCHEMA =
    u"CREATE TABLE IF NOT EXISTS players("_s
    u"id TEXT PRIMARY KEY,"_s
    u"startingRank INTEGER,"_s
    u"title TEXT,"_s
    u"name TEXT,"_s
    u"rating INTEGER,"_s
    u"nationalRating INTEGER,"_s
    u"playerId TEXT,"_s
    u"birthDate TEXT,"_s
    u"federation TEXT,"_s
    u"origin TEXT,"_s
    u"sex TEXT,"_s
    u"extra BLOB,"_s
    u"tournament TEXT NOT NULL,"_s
    u"FOREIGN KEY (tournament) REFERENCES tournaments(id)"_s
    u");"_s;

const QString ADD_PLAYER_QUERY =
    u"INSERT INTO players(id, startingRank, title, name, rating, nationalRating, playerId, birthDate, federation, origin, sex, extra, tournament) "_s
    u"VALUES (:id, :startingRank, :title, :name, :rating, :nationalRating, :playerId, :birthDate, :federation, :origin, :sex, :extra, :tournament);"_s;

const QString GET_PLAYERS_QUERY = u"SELECT * FROM players WHERE tournament = :tournament;"_s;

const QString UPDATE_PLAYER_QUERY =
    u"UPDATE players SET (startingRank, title, name, rating, nationalRating, playerId, birthDate, federation, origin, sex, extra, tournament) = "_s
    u"(:startingRank, :title, :name, :rating, :nationalRating, :playerId, :birthDate, :federation, :origin, :sex, :extra, :tournament) "_s
    u"WHERE id = :id;"_s;

const QString ROUNDS_TABLE_SCHEMA =
    u"CREATE TABLE IF NOT EXISTS rounds("_s
    u"id INTEGER PRIMARY KEY,"_s
    u"number INTEGER NOT NULL,"_s
    u"tournament TEXT NOT NULL,"_s
    u"datetime TEXT,"_s
    u"extra BLOB,"_s
    u"FOREIGN KEY (tournament) REFERENCES tournaments(id),"_s
    u"UNIQUE (tournament, number)"_s
    u");"_s;

const QString ADD_ROUND_QUERY =
    u"INSERT INTO rounds(number, tournament, extra) "_s
    u"VALUES (:number, :tournament, :extra);"_s;

const QString GET_ROUNDS_QUERY = u"SELECT * FROM rounds WHERE tournament = :tournament;"_s;

const QString UPDATE_ROUND_QUERY =
    u"UPDATE rounds SET (datetime, extra) = "_s
    u"(:datetime, :extra) "_s
    u"WHERE id = :id;"_s;

const QString PAIRINGS_TABLE_SCHEMA =
    u"CREATE TABLE IF NOT EXISTS pairings("_s
    u"id TEXT PRIMARY KEY,"_s
    u"board INTEGER,"_s
    u"whitePlayer TEXT NOT NULL,"_s
    u"blackPlayer TEXT,"_s
    u"whiteResult INTEGER NOT NULL,"_s
    u"blackResult INTEGER NOT NULL,"_s
    u"round INTEGER NOT NULL,"_s
    u"lastModified INTEGER,"_s
    u"extra BLOB,"_s
    u"FOREIGN KEY(whitePlayer) REFERENCES players(id),"_s
    u"FOREIGN KEY(blackPlayer) REFERENCES players(id),"_s
    u"FOREIGN KEY(round) REFERENCES rounds(id)"_s
    u");"_s;

const QString ADD_PAIRING_QUERY =
    u"INSERT INTO pairings(id, board, whitePlayer, blackPlayer, whiteResult, blackResult, round, lastModified, extra) "_s
    u"VALUES (:id, :board, :whitePlayer, :blackPlayer, :whiteResult, :blackResult, :round, :lastModified, :extra);"_s;

const QString GET_PAIRINGS_QUERY =
    u"SELECT * FROM pairings "_s
    u"JOIN rounds ON pairings.round = rounds.id "_s
    u"WHERE rounds.tournament = :tournament "_s
    u"ORDER BY rounds.number, pairings.board;"_s;

const QString UPDATE_PAIRING_QUERY =
    u"UPDATE pairings SET (board, whitePlayer, blackPlayer, whiteResult, blackResult, lastModified, extra) = "_s
    u"(:board, :whitePlayer, :blackPlayer, :whiteResult, :blackResult, :lastModified, :extra) "
    u"WHERE id = :id;"_s;

const QString DELETE_PAIRING_QUERY = u"DELETE FROM pairings WHERE id = :id;"_s;

const QString DELETE_PAIRINGS_QUERY = u"DELETE FROM pairings WHERE round = :round;"_s;

const QString DELETE_PAIRINGS_KEEP_BYES_QUERY = u"DELETE FROM pairings WHERE round = :round AND whiteResult NOT IN (9, 10, 11);"_s;
