import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../infrastructure/database/prisma.service';
import { RedisService } from '../../infrastructure/redis/redis.service';

const FF_PREFIX = 'ff:';
const FF_TTL = 30;

@Injectable()
export class FeatureFlagService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly redis: RedisService,
  ) {}

  /** Check if flag is enabled, with optional user-level whitelist */
  async isEnabled(name: string, userId?: string): Promise<boolean> {
    try {
      const cached = await this.redis.get(FF_PREFIX + name);
      if (cached !== null) return cached === '1';
    } catch {}

    const flag = await this.prisma.featureFlag.findUnique({ where: { name } });
    const enabled = flag?.enabled ?? false;

    // If user whitelist is set, only enabled for whitelisted users
    if (enabled && flag?.whitelist) {
      const whitelist = (flag.whitelist as string).split(',').map(s => s.trim());
      if (!userId || !whitelist.includes(userId)) return false;
    }
    try { await this.redis.set(FF_PREFIX + name, enabled ? '1' : '0', FF_TTL); } catch {}
    return enabled;
  }

  async setEnabled(name: string, enabled: boolean, updatedBy?: string): Promise<void> {
    const existing = await this.prisma.featureFlag.findUnique({ where: { name } });
    if (existing) {
      await this.prisma.featureFlag.update({ where: { name }, data: { enabled, updatedBy } });
      if (existing.enabled !== enabled) {
        await this.prisma.configChangeLog.create({ data: { entityType: 'FeatureFlag', entityId: existing.id, field: 'enabled', oldValue: String(existing.enabled), newValue: String(enabled), changedBy: updatedBy } });
      }
    } else {
      const created = await this.prisma.featureFlag.create({ data: { name, enabled, updatedBy } });
      await this.prisma.configChangeLog.create({ data: { entityType: 'FeatureFlag', entityId: created.id, field: 'enabled', newValue: String(enabled), changedBy: updatedBy } });
    }
    try { await this.redis.set(FF_PREFIX + name, enabled ? '1' : '0', FF_TTL); } catch {}
  }

  async setWhitelist(name: string, whitelist: string): Promise<void> {
    await this.prisma.featureFlag.update({ where: { name }, data: { whitelist } });
    try { await this.redis.del(FF_PREFIX + name); } catch {}
  }

  async getAll() { return this.prisma.featureFlag.findMany({ orderBy: { name: 'asc' } }) }
}
