import { eq } from 'drizzle-orm'
import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js'
import { moduleConfig } from '../db/schema/modules.js'

// In-memory cache of enabled module slugs — avoids DB query per request
let enabledCache: Set<string> | null = null

export const ModuleService = {
  async listAll(db: PostgresJsDatabase<any>) {
    return db.select().from(moduleConfig).orderBy(moduleConfig.name)
  },

  async isEnabled(db: PostgresJsDatabase<any>, slug: string): Promise<boolean> {
    if (!enabledCache) await this.refreshCache(db)
    return enabledCache!.has(slug)
  },

  async getEnabledSlugs(db: PostgresJsDatabase<any>): Promise<Set<string>> {
    if (!enabledCache) await this.refreshCache(db)
    return new Set(enabledCache!)
  },

  async setEnabled(db: PostgresJsDatabase<any>, slug: string, enabled: boolean): Promise<typeof moduleConfig.$inferSelect | null> {
    // Check that module exists and is licensed
    const [mod] = await db.select().from(moduleConfig).where(eq(moduleConfig.slug, slug)).limit(1)
    if (!mod) return null
    if (enabled && !mod.licensed) {
      throw new Error('Module is not licensed')
    }

    const [updated] = await db.update(moduleConfig)
      .set({ enabled, updatedAt: new Date() })
      .where(eq(moduleConfig.slug, slug))
      .returning()

    // Invalidate cache
    enabledCache = null

    return updated ?? null
  },

  async refreshCache(db: PostgresJsDatabase<any>) {
    const modules = await db.select({ slug: moduleConfig.slug, enabled: moduleConfig.enabled, licensed: moduleConfig.licensed })
      .from(moduleConfig)
    enabledCache = new Set(modules.filter((m) => m.enabled && m.licensed).map((m) => m.slug))
  },

  invalidateCache() {
    enabledCache = null
  },
}
