import { drizzle } from 'drizzle-orm/better-sqlite3';
import Database from 'better-sqlite3';

let testDb: ReturnType<typeof drizzle> | null = null;
let sqlite: Database.Database | null = null;

const schemaSQL = `
    CREATE TABLE IF NOT EXISTS users (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      clerk_id TEXT NOT NULL UNIQUE,
      email TEXT NOT NULL UNIQUE,
      name TEXT,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
    );

    CREATE TABLE IF NOT EXISTS projects (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT NOT NULL,
      description TEXT,
      owner_id INTEGER NOT NULL REFERENCES users(id),
      is_public INTEGER NOT NULL DEFAULT 0,
      theme TEXT,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
    );

    CREATE TABLE IF NOT EXISTS characters (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      project_id INTEGER NOT NULL REFERENCES projects(id),
      name TEXT NOT NULL,
      slug TEXT NOT NULL,
      role TEXT NOT NULL DEFAULT 'supporting',
      bio TEXT,
      description TEXT,
      arc TEXT,
      arc_type TEXT,
      age INTEGER,
      gender TEXT,
      voice TEXT,
      traits TEXT,
      motivation TEXT,
      conflict TEXT,
      secret TEXT,
      image_url TEXT,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );

    CREATE TABLE IF NOT EXISTS character_relationships (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      character_a_id INTEGER NOT NULL REFERENCES characters(id),
      character_b_id INTEGER NOT NULL REFERENCES characters(id),
      relationship_type TEXT NOT NULL,
      description TEXT,
      strength INTEGER NOT NULL DEFAULT 50,
      is_antagonistic INTEGER NOT NULL DEFAULT 0,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );

    CREATE TABLE IF NOT EXISTS scenes (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      project_id INTEGER NOT NULL REFERENCES projects(id),
      title TEXT NOT NULL,
      content TEXT NOT NULL DEFAULT '',
      "order" INTEGER NOT NULL DEFAULT 0,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );

    CREATE TABLE IF NOT EXISTS scene_characters (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      scene_id INTEGER NOT NULL REFERENCES scenes(id),
      character_id INTEGER NOT NULL REFERENCES characters(id),
      screen_time INTEGER,
      dialogue_lines INTEGER DEFAULT 0
    );

    CREATE TABLE IF NOT EXISTS project_members (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      project_id INTEGER NOT NULL REFERENCES projects(id),
      user_id INTEGER NOT NULL REFERENCES users(id),
      role TEXT NOT NULL DEFAULT 'editor',
      added_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
    );

    CREATE TABLE IF NOT EXISTS scripts (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      project_id INTEGER NOT NULL REFERENCES projects(id),
      title TEXT NOT NULL,
      version TEXT NOT NULL DEFAULT '1.0',
      content TEXT,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
    );

CREATE TABLE IF NOT EXISTS revisions (
       id INTEGER PRIMARY KEY AUTOINCREMENT,
       script_id INTEGER NOT NULL REFERENCES scripts(id),
       version_number INTEGER NOT NULL,
       branch_name TEXT NOT NULL DEFAULT 'main',
       parent_revision_id INTEGER,
       title TEXT NOT NULL,
       summary TEXT,
       content TEXT NOT NULL,
       author_id INTEGER NOT NULL REFERENCES users(id),
       status TEXT NOT NULL DEFAULT 'draft' CHECK(status IN ('draft', 'pending_review', 'accepted', 'rejected')),
       reviewed_by_id INTEGER REFERENCES users(id),
       reviewed_at TIMESTAMP,
       created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
       updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
     );

CREATE TABLE IF NOT EXISTS revision_changes (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        revision_id INTEGER NOT NULL REFERENCES revisions(id),
        change_type TEXT NOT NULL CHECK(change_type IN ('addition', 'deletion', 'modification')),
        element_type TEXT,
        old_content TEXT,
        new_content TEXT,
        scene_number INTEGER,
        line_number INTEGER,
        page_number INTEGER,
        created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
      );

    CREATE TABLE IF NOT EXISTS teams (
      id TEXT PRIMARY KEY,
      name TEXT NOT NULL,
      owner_id INTEGER NOT NULL REFERENCES users(id),
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
    );

    CREATE TABLE IF NOT EXISTS team_members (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      team_id TEXT NOT NULL REFERENCES teams(id),
      user_id INTEGER NOT NULL REFERENCES users(id),
      role TEXT NOT NULL DEFAULT 'editor',
      joined_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
    );
  `;

export let globalSqlite: Database.Database | null = null;

export async function getTestDb(): Promise<ReturnType<typeof drizzle>> {
  if (testDb && sqlite) return testDb;

  sqlite = new Database(':memory:');
  globalSqlite = sqlite;
  sqlite.exec('PRAGMA foreign_keys = OFF;');
  sqlite.exec(schemaSQL);
  sqlite.exec('PRAGMA foreign_keys = ON;');
  
  // Insert a test user
  sqlite.exec("INSERT INTO users (id, clerk_id, email, name) VALUES (1, 'user_test', 'test@test.com', 'Test User');");
  
  // Insert a test project
  sqlite.exec("INSERT INTO projects (id, name, description, owner_id) VALUES (1, 'Test Project', 'A test project', 1);");
  
  // Insert a test script
  sqlite.exec("INSERT INTO scripts (id, project_id, title, version) VALUES (1, 1, 'Test Script', '1.0');");
  
  testDb = drizzle(sqlite);

  return testDb;
}

export async function resetTestDb(): Promise<ReturnType<typeof drizzle>> {
  testDb = null;
  sqlite = null;
  globalSqlite = null;
  return getTestDb();
}
