import dotenv from 'dotenv'
import { sql } from 'drizzle-orm'
import { drizzle } from 'drizzle-orm/postgres-js'
import EventEmitter from 'events'
import { LRUCache } from 'lru-cache'
import { Pool } from 'pg'

dotenv.config()

interface FeatureFlag {
   name: string
   enabled: boolean
}

class FeatureFlagService {
   private db
   private cache
   private events

   constructor() {
      this.db = drizzle(new Pool({ connectionString: process.env.DATABASE_URL }))
      this.cache = new LRUCache<string, boolean>({ max: 100, ttl: 60000 })
      this.events = new EventEmitter()

      this.initialize()
   }

   private async initialize() {
      await this.loadFeatureFlags()
      this.listenForChanges()
   }

   private async loadFeatureFlags() {
      const flags: FeatureFlag[] = await this.db.execute(sql`SELECT name, enabled FROM hub_feature_flag`)
      flags.forEach((flag) => this.cache.set(flag.name, flag.enabled))
   }

   private async listenForChanges() {
      const client = new Pool({ connectionString: process.env.DATABASE_URL })
      const pgClient = await client.connect()
      pgClient.query('LISTEN feature_flag_changes')
      pgClient.on('notification', async () => {
         await this.loadFeatureFlags()
         this.events.emit('update')
      })
   }

   public isEnabled(flagName: string): boolean {
      return this.cache.get(flagName) ?? false
   }

   public onUpdate(callback: () => void) {
      this.events.on('update', callback)
   }

   static setDatabaseUrl(url: string) {
      process.env.DATABASE_URL = url
   }
}

export { FeatureFlagService }
