using MySqlConnector;

namespace SharpChat.EventStorage;

public partial class MariaDBEventStorage {
    private void DoMigration(string name, Action action) {
        bool done = RunQueryValue<long>(
            "SELECT COUNT(*) FROM `sqc_migrations` WHERE `migration_name` = @name",
            new MySqlParameter("name", name)
        ) > 0;
        if(!done) {
            Logger.Write($"Running migration '{name}'...");
            action();
            RunCommand(
                "INSERT INTO `sqc_migrations` (`migration_name`) VALUES (@name)",
                new MySqlParameter("name", name)
            );
        }
    }

    public void RunMigrations() {
        RunCommand(
            "CREATE TABLE IF NOT EXISTS `sqc_migrations` ("
            + "`migration_name` VARCHAR(255) NOT NULL,"
            + "`migration_completed` TIMESTAMP NOT NULL DEFAULT current_timestamp(),"
            + "UNIQUE INDEX `migration_name` (`migration_name`),"
            + "INDEX `migration_completed` (`migration_completed`)"
            + ") COLLATE='utf8mb4_unicode_ci' ENGINE=InnoDB;"
        );

        DoMigration("create_events_table", CreateEventsTable);
        DoMigration("allow_null_target", AllowNullTarget);
        DoMigration("event_data_as_medium_blob", EventDataAsMediumBlob);
        DoMigration("event_user_and_nick_name_to_1000", EventUserAndNickNameTo1000);
    }

    private void EventUserAndNickNameTo1000() {
        RunCommand(
            "ALTER TABLE `sqc_events`"
            + " CHANGE COLUMN `event_sender_name` `event_sender_name` VARCHAR(1000) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_520_ci' AFTER `event_sender`,"
            + " CHANGE COLUMN `event_sender_nick` `event_sender_nick` VARCHAR(1000) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_520_ci' AFTER `event_sender_rank`;"
        );
    }

    private void EventDataAsMediumBlob() {
        RunCommand(
            "ALTER TABLE `sqc_events`"
            + " CHANGE COLUMN `event_data` `event_data` MEDIUMBLOB NULL DEFAULT NULL AFTER `event_flags`;"
        );
    }

    private void AllowNullTarget() {
        RunCommand(
            "ALTER TABLE `sqc_events`"
            + " CHANGE COLUMN `event_target` `event_target` VARBINARY(255) NULL AFTER `event_type`;"
        );
    }

    private void CreateEventsTable() {
        RunCommand(
            "CREATE TABLE `sqc_events` ("
            + "`event_id` BIGINT(20) NOT NULL,"
            + "`event_sender` BIGINT(20) UNSIGNED NULL DEFAULT NULL,"
            + "`event_sender_name` VARCHAR(255) NULL DEFAULT NULL,"
            + "`event_sender_colour` INT(11) NULL DEFAULT NULL,"
            + "`event_sender_rank` INT(11) NULL DEFAULT NULL,"
            + "`event_sender_nick` VARCHAR(255) NULL DEFAULT NULL,"
            + "`event_sender_perms` INT(11) NULL DEFAULT NULL,"
            + "`event_created` TIMESTAMP NOT NULL DEFAULT current_timestamp(),"
            + "`event_deleted` TIMESTAMP NULL DEFAULT NULL,"
            + "`event_type` VARBINARY(255) NOT NULL,"
            + "`event_target` VARBINARY(255) NOT NULL,"
            + "`event_flags` TINYINT(3) UNSIGNED NOT NULL,"
            + "`event_data` BLOB NULL DEFAULT NULL,"
            + "PRIMARY KEY (`event_id`),"
            + "INDEX `event_target` (`event_target`),"
            + "INDEX `event_type` (`event_type`),"
            + "INDEX `event_sender` (`event_sender`),"
            + "INDEX `event_datetime` (`event_created`),"
            + "INDEX `event_deleted` (`event_deleted`)"
            + ") COLLATE='utf8mb4_unicode_ci' ENGINE=InnoDB;"
        );
    }
}