// Latest schema version — bumped when a migration is added in ./migrations/
export const SCHEMA_VERSION = 5;

export const PRAGMA_SQL = `
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA temp_store = MEMORY;
PRAGMA mmap_size = 30000000;
PRAGMA cache_size = -64000;
PRAGMA foreign_keys = ON;
PRAGMA busy_timeout = 5000;
`;

// Declarative current schema. Used by syncSchemaFromTables() to
// auto-add missing tables/columns/indexes after versioned migrations.
// For destructive changes (drop/rename/type-change), write a migration file.
export const TABLES = {
  _meta: {
    columns: {
      key: "TEXT PRIMARY KEY",
      value: "TEXT NOT NULL",
    },
  },
  settings: {
    columns: {
      id: "INTEGER PRIMARY KEY CHECK (id = 1)",
      data: "TEXT NOT NULL",
    },
  },
  providerConnections: {
    columns: {
      id: "TEXT PRIMARY KEY",
      provider: "TEXT NOT NULL",
      authType: "TEXT NOT NULL",
      name: "TEXT",
      email: "TEXT",
      priority: "INTEGER",
      isActive: "INTEGER DEFAULT 1",
      data: "TEXT NOT NULL",
      createdAt: "TEXT NOT NULL",
      updatedAt: "TEXT NOT NULL",
    },
    indexes: [
      "CREATE INDEX IF NOT EXISTS idx_pc_provider ON providerConnections(provider)",
      "CREATE INDEX IF NOT EXISTS idx_pc_provider_active ON providerConnections(provider, isActive)",
      "CREATE INDEX IF NOT EXISTS idx_pc_priority ON providerConnections(provider, priority)",
    ],
  },
  providerNodes: {
    columns: {
      id: "TEXT PRIMARY KEY",
      type: "TEXT",
      name: "TEXT",
      data: "TEXT NOT NULL",
      createdAt: "TEXT NOT NULL",
      updatedAt: "TEXT NOT NULL",
    },
    indexes: ["CREATE INDEX IF NOT EXISTS idx_pn_type ON providerNodes(type)"],
  },
  proxyPools: {
    columns: {
      id: "TEXT PRIMARY KEY",
      isActive: "INTEGER DEFAULT 1",
      testStatus: "TEXT",
      data: "TEXT NOT NULL",
      createdAt: "TEXT NOT NULL",
      updatedAt: "TEXT NOT NULL",
    },
    indexes: [
      "CREATE INDEX IF NOT EXISTS idx_pp_active ON proxyPools(isActive)",
      "CREATE INDEX IF NOT EXISTS idx_pp_status ON proxyPools(testStatus)",
    ],
  },
  apiKeys: {
    columns: {
      id: "TEXT PRIMARY KEY",
      key: "TEXT UNIQUE NOT NULL",
      name: "TEXT",
      machineId: "TEXT",
      userId: "TEXT REFERENCES users(id) ON DELETE CASCADE",
      comment: "TEXT DEFAULT ''",
      isActive: "INTEGER DEFAULT 1",
      createdAt: "TEXT NOT NULL",
      rtkEnabled: "INTEGER NULL",
      cavemanEnabled: "INTEGER NULL",
      cavemanLevel: "TEXT NULL",
    },
    indexes: ["CREATE INDEX IF NOT EXISTS idx_ak_key ON apiKeys(key)"],
  },
  users: {
    columns: {
      id: "TEXT PRIMARY KEY",
      username: "TEXT UNIQUE NOT NULL",
      password_hash: "TEXT NOT NULL",
      role: "TEXT DEFAULT 'user' CHECK(role IN ('admin','user'))",
      is_active: "INTEGER DEFAULT 1",
      is_approved: "INTEGER DEFAULT 0",
      created_at: "TEXT DEFAULT (datetime('now'))",
    },
    indexes: [
      "CREATE INDEX IF NOT EXISTS idx_users_username ON users(username)",
    ],
  },
  rateLimits: {
    columns: {
      id: "TEXT PRIMARY KEY",
      userId: "TEXT NOT NULL UNIQUE REFERENCES users(id) ON DELETE CASCADE",
      packageId: "TEXT REFERENCES packages(id) ON DELETE SET NULL",
      rtpMinute: "INTEGER DEFAULT 100",
      rtpDay: "INTEGER DEFAULT 100000",
      tokenLimitMonthly: "INTEGER DEFAULT 1000000",
      creditLimit: "REAL DEFAULT 5.0",
      maxConcurrent: "INTEGER DEFAULT 5",
      created_at: "TEXT DEFAULT (datetime('now'))",
      updated_at: "TEXT DEFAULT (datetime('now'))",
    },
    indexes: [
      "CREATE INDEX IF NOT EXISTS idx_rl_userId ON rateLimits(userId)",
    ],
  },
  packages: {
    columns: {
      id: "TEXT PRIMARY KEY",
      name: "TEXT UNIQUE",
      description: "TEXT",
      rtpMinute: "INTEGER",
      rtpDay: "INTEGER",
      tokenLimitMonthly: "INTEGER",
      creditLimit: "REAL",
      creditToTokenRatio: "REAL DEFAULT 1000",
      maxConcurrent: "INTEGER",
      durationDays: "INTEGER",
      price: "REAL DEFAULT 0",
      isActive: "INTEGER DEFAULT 1",
      createdAt: "TEXT",
      updatedAt: "TEXT",
    },
    indexes: [
      "CREATE INDEX IF NOT EXISTS idx_packages_name ON packages(name)",
    ],
  },
  userPackages: {
    columns: {
      id: "TEXT PRIMARY KEY",
      userId: "TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE",
      packageId: "TEXT REFERENCES packages(id) ON DELETE SET NULL",
      rtpMinuteOverride: "INTEGER",
      rtpDayOverride: "INTEGER",
      tokenLimitMonthlyOverride: "INTEGER",
      creditLimitOverride: "REAL",
      maxConcurrentOverride: "INTEGER",
      assignedAt: "TEXT",
      expiresAt: "TEXT",
    },
    indexes: [
      "CREATE INDEX IF NOT EXISTS idx_up_userId ON userPackages(userId)",
      "CREATE INDEX IF NOT EXISTS idx_up_packageId ON userPackages(packageId)",
    ],
  },
  combos: {
    columns: {
      id: "TEXT PRIMARY KEY",
      name: "TEXT UNIQUE NOT NULL",
      kind: "TEXT",
      models: "TEXT NOT NULL",
      createdAt: "TEXT NOT NULL",
      updatedAt: "TEXT NOT NULL",
    },
    indexes: ["CREATE INDEX IF NOT EXISTS idx_combo_name ON combos(name)"],
  },
  kv: {
    columns: {
      scope: "TEXT NOT NULL",
      key: "TEXT NOT NULL",
      value: "TEXT NOT NULL",
    },
    primaryKey: "PRIMARY KEY (scope, key)",
    indexes: ["CREATE INDEX IF NOT EXISTS idx_kv_scope ON kv(scope)"],
  },
  usageHistory: {
    columns: {
      id: "INTEGER PRIMARY KEY AUTOINCREMENT",
      timestamp: "TEXT NOT NULL",
      provider: "TEXT",
      model: "TEXT",
      connectionId: "TEXT",
      apiKey: "TEXT",
      endpoint: "TEXT",
      promptTokens: "INTEGER DEFAULT 0",
      completionTokens: "INTEGER DEFAULT 0",
      cost: "REAL DEFAULT 0",
      status: "TEXT",
      tokens: "TEXT",
      meta: "TEXT",
    },
    indexes: [
      "CREATE INDEX IF NOT EXISTS idx_uh_ts ON usageHistory(timestamp DESC)",
      "CREATE INDEX IF NOT EXISTS idx_uh_provider ON usageHistory(provider)",
      "CREATE INDEX IF NOT EXISTS idx_uh_model ON usageHistory(model)",
      "CREATE INDEX IF NOT EXISTS idx_uh_conn ON usageHistory(connectionId)",
    ],
  },
  usageDaily: {
    columns: {
      dateKey: "TEXT PRIMARY KEY",
      data: "TEXT NOT NULL",
    },
  },
  requestDetails: {
    columns: {
      id: "TEXT PRIMARY KEY",
      timestamp: "TEXT NOT NULL",
      provider: "TEXT",
      model: "TEXT",
      connectionId: "TEXT",
      status: "TEXT",
      data: "TEXT NOT NULL",
    },
    indexes: [
      "CREATE INDEX IF NOT EXISTS idx_rd_ts ON requestDetails(timestamp DESC)",
      "CREATE INDEX IF NOT EXISTS idx_rd_provider ON requestDetails(provider)",
      "CREATE INDEX IF NOT EXISTS idx_rd_model ON requestDetails(model)",
      "CREATE INDEX IF NOT EXISTS idx_rd_conn ON requestDetails(connectionId)",
    ],
  },
  usageRecords: {
    columns: {
      id: "TEXT PRIMARY KEY",
      userId: "TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE",
      apiKeyId: "TEXT REFERENCES apiKeys(id) ON DELETE SET NULL",
      model: "TEXT NOT NULL",
      inputTokens: "INTEGER DEFAULT 0",
      outputTokens: "INTEGER DEFAULT 0",
      totalTokens: "INTEGER DEFAULT 0",
      cost: "REAL DEFAULT 0",
      creditUsed: "REAL DEFAULT 0",
      status: "TEXT",
      errorMessage: "TEXT",
      endpoint: "TEXT",
      timestamp: "TEXT NOT NULL",
    },
    indexes: [
      "CREATE INDEX IF NOT EXISTS idx_ur_user_ts ON usageRecords(userId, timestamp)",
      "CREATE INDEX IF NOT EXISTS idx_ur_apikey_ts ON usageRecords(apiKeyId, timestamp)",
    ],
  },
};

export function buildCreateTableSql(name, def) {
  const cols = Object.entries(def.columns).map(([k, v]) => `${k} ${v}`);
  if (def.primaryKey) cols.push(def.primaryKey);
  return `CREATE TABLE IF NOT EXISTS ${name} (${cols.join(", ")})`;
}
