import { Migration, MigrationManager } from "@lib/db/migrations.ts";
import { DatabaseClient } from "@lib/db/dbWrapper.ts";
import { Database } from "@db/sqlite";

const sqliteDbPath = Deno.env.get("KBRG_SQLITE_DB_PATH") || "./test.db";

const sqliteDB = new Database(sqliteDbPath);

const migrationManager = new MigrationManager(
    [
        Migration.create(
            "initial migration",
            "create necessery tables",
            [
                `
            CREATE TABLE IF NOT EXISTS admin (
                id INTEGER PRIMARY KEY AUTOINCREMENT CHECK(id = 1),
                passwordHash TEXT NOT NULL,
                createdAt TIMESTAMP NOT NULL DEFAULT (datetime('now')),
                updatedAt DATETIME NOT NULL DEFAULT (datetime('now'))
            );`,

                `CREATE TABLE IF NOT EXISTS adminSessions (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                token TEXT NOT NULL,
                createdAt DATETIME NOT NULL DEFAULT (datetime('now')),
                expiresAt DATETIME NOT NULL DEFAULT (datetime('now', '+15 minutes'))
            );`,

                `CREATE TABLE IF NOT EXISTS users (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                login TEXT NOT NULL UNIQUE,
                passwordHash TEXT NOT NULL,
                displayName TEXT DEFAULT NULL,
                telegramId TEXT DEFAULT NULL,
                phone TEXT DEFAULT NULL,
                email TEXT DEFAULT NULL,
                deleted BOOLEAN NOT NULL DEFAULT (false),
                createdAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
                updatedAt DATETIME DEFAULT (datetime('now'))
            );`,

                `CREATE TABLE IF NOT EXISTS userSessions (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                userId INT NOT NULL,
                token TEXT NOT NULL,
                createdAt DATETIME NOT NULL DEFAULT (datetime('now')),
                expiredAt DATETIME NOT NULL DEFAULT (datetime('now', '+3 hours')),

                FOREIGN KEY(userId) REFERENCES users(id)
                    ON DELETE CASCADE
                    ON UPDATE NO ACTION
            );`,

                `CREATE TABLE IF NOT EXISTS devices (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                busid TEXT NOT NULL,
                usbid TEXT NOT NULL,
                vendor TEXT NOT NULL DEFAULT 'unknown vendor',
                deviceName TEXT NOT NULL DEFAULT 'unknown device',
                displayName TEXT DEFAULT NULL,
                description TEXT DEFAULT NULL,
                connectedAt TIMESTAMP NOT NULL DEFAULT (datetime('now')),
                disconnectedAt TIMESTAMP DEFAULT NULL,
                updatedAt DATETIME NOT NULL DEFAULT (datetime('now'))
            );`,

                `CREATE TABLE IF NOT EXISTS deviceAttachedEvent (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                userId INTEGER,
                deviceId INTEGER,
                event TEXT NOT NULL CHECK(event IN ('exported', 'released')),

                FOREIGN KEY(userId) REFERENCES users(id)
                    ON DELETE CASCADE
                    ON UPDATE NO ACTION

                FOREIGN KEY(deviceId) REFERENCES users(id)
                    ON DELETE CASCADE
                    ON UPDATE NO ACTION
            );`,

                `CREATE TRIGGER update_admin_timestamp
            AFTER UPDATE ON admin
            FOR EACH ROW WHEN NEW.updatedAt = OLD.updatedAt
            BEGIN
                UPDATE admin
                SET updatedAt = datetime('now')
                WHERE id = OLD.id;
            END;`,

                `CREATE TRIGGER update_user_timestamp
            AFTER UPDATE ON users
            FOR EACH ROW WHEN NEW.updatedAt = OLD.updatedAt
            BEGIN
                UPDATE users
                SET updatedAt = datetime('now')
                WHERE id = OLD.id;
            END;`,

                `CREATE TRIGGER update_device_timestamp
            AFTER UPDATE ON devices
            FOR EACH ROW WHEN NEW.updatedAt = OLD.updatedAt
            BEGIN
                UPDATE devices
                SET updatedAt = datetime('now')
                WHERE id = OLD.id;
            END;`,
            ],
            [
                `DELETE TABLE admin;`,
                `DELETE TABLE adminSessions;`,
                `DELETE TABLE users;`,
                `DELETE TABLE userSessions;`,
                `DELETE TABLE devices;`,
            ],
        ),
    ],
    sqliteDB,
);

migrationManager.init();

const db = new DatabaseClient(sqliteDB);

export default db;
