import { MigrationInterface, QueryRunner } from 'typeorm';

export class InitialSchema1000000000000 implements MigrationInterface {
  name = 'InitialSchema1000000000000';

  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`
      CREATE TABLE IF NOT EXISTS "messages" (
        "id"          TEXT PRIMARY KEY NOT NULL,
        "roomId"      TEXT NOT NULL,
        "channelId"   TEXT,
        "senderId"    TEXT NOT NULL,
        "senderName"  TEXT NOT NULL,
        "content"     TEXT NOT NULL,
        "timestamp"   INTEGER NOT NULL,
        "editedAt"    INTEGER,
        "reactions"   TEXT NOT NULL DEFAULT '[]',
        "isDeleted"   INTEGER NOT NULL DEFAULT 0,
        "replyToId"   TEXT
      )
    `);
    await queryRunner.query(`CREATE INDEX IF NOT EXISTS "idx_messages_roomId" ON "messages" ("roomId")`);

    await queryRunner.query(`
      CREATE TABLE IF NOT EXISTS "users" (
        "id"               TEXT PRIMARY KEY NOT NULL,
        "oderId"           TEXT,
        "username"         TEXT,
        "displayName"      TEXT,
        "avatarUrl"        TEXT,
        "status"           TEXT,
        "role"             TEXT,
        "joinedAt"         INTEGER,
        "peerId"           TEXT,
        "isOnline"         INTEGER NOT NULL DEFAULT 0,
        "isAdmin"          INTEGER NOT NULL DEFAULT 0,
        "isRoomOwner"      INTEGER NOT NULL DEFAULT 0,
        "voiceState"       TEXT,
        "screenShareState" TEXT
      )
    `);

    await queryRunner.query(`
      CREATE TABLE IF NOT EXISTS "rooms" (
        "id"            TEXT PRIMARY KEY NOT NULL,
        "name"          TEXT NOT NULL,
        "description"   TEXT,
        "topic"         TEXT,
        "hostId"        TEXT NOT NULL,
        "password"      TEXT,
        "isPrivate"     INTEGER NOT NULL DEFAULT 0,
        "createdAt"     INTEGER NOT NULL,
        "userCount"     INTEGER NOT NULL DEFAULT 0,
        "maxUsers"      INTEGER,
        "icon"          TEXT,
        "iconUpdatedAt" INTEGER,
        "permissions"   TEXT,
        "channels"      TEXT
      )
    `);

    await queryRunner.query(`
      CREATE TABLE IF NOT EXISTS "reactions" (
        "id"        TEXT PRIMARY KEY NOT NULL,
        "messageId" TEXT NOT NULL,
        "oderId"    TEXT,
        "userId"    TEXT,
        "emoji"     TEXT NOT NULL,
        "timestamp" INTEGER NOT NULL
      )
    `);
    await queryRunner.query(`CREATE INDEX IF NOT EXISTS "idx_reactions_messageId" ON "reactions" ("messageId")`);

    await queryRunner.query(`
      CREATE TABLE IF NOT EXISTS "bans" (
        "oderId"      TEXT NOT NULL,
        "roomId"      TEXT NOT NULL,
        "userId"      TEXT,
        "bannedBy"    TEXT NOT NULL,
        "displayName" TEXT,
        "reason"      TEXT,
        "expiresAt"   INTEGER,
        "timestamp"   INTEGER NOT NULL,
        PRIMARY KEY ("oderId", "roomId")
      )
    `);
    await queryRunner.query(`CREATE INDEX IF NOT EXISTS "idx_bans_roomId" ON "bans" ("roomId")`);

    await queryRunner.query(`
      CREATE TABLE IF NOT EXISTS "attachments" (
        "id"             TEXT PRIMARY KEY NOT NULL,
        "messageId"      TEXT NOT NULL,
        "filename"       TEXT NOT NULL,
        "size"           INTEGER NOT NULL,
        "mime"           TEXT NOT NULL,
        "isImage"        INTEGER NOT NULL DEFAULT 0,
        "uploaderPeerId" TEXT,
        "filePath"       TEXT,
        "savedPath"      TEXT
      )
    `);
    await queryRunner.query(`CREATE INDEX IF NOT EXISTS "idx_attachments_messageId" ON "attachments" ("messageId")`);

    await queryRunner.query(`
      CREATE TABLE IF NOT EXISTS "meta" (
        "key"   TEXT PRIMARY KEY NOT NULL,
        "value" TEXT
      )
    `);
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`DROP TABLE IF EXISTS "meta"`);
    await queryRunner.query(`DROP TABLE IF EXISTS "attachments"`);
    await queryRunner.query(`DROP TABLE IF EXISTS "bans"`);
    await queryRunner.query(`DROP TABLE IF EXISTS "reactions"`);
    await queryRunner.query(`DROP TABLE IF EXISTS "rooms"`);
    await queryRunner.query(`DROP TABLE IF EXISTS "users"`);
    await queryRunner.query(`DROP TABLE IF EXISTS "messages"`);
  }
}
