import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../common/prisma.service';

export const CONFIG_KEYS = {
  SEAT_HOLD_DURATION_MINUTES: 'seat_hold_duration_minutes',
  HOLD_CUTOFF_HOURS_BEFORE_DEPARTURE: 'hold_cutoff_hours_before_departure',
  BOARDING_WINDOW_HOURS_BEFORE_DEPARTURE: 'boarding_window_hours_before_departure',
  THROTTLE_AUTH_LIMIT: 'throttle_auth_limit',
  THROTTLE_AUTH_TTL_MS: 'throttle_auth_ttl_ms',
  THROTTLE_STRICT_LIMIT: 'throttle_strict_limit',
  THROTTLE_STRICT_TTL_MS: 'throttle_strict_ttl_ms',
  THROTTLE_DEFAULT_LIMIT: 'throttle_default_limit',
  THROTTLE_DEFAULT_TTL_MS: 'throttle_default_ttl_ms',
} as const;

const DEFAULTS: Record<string, string> = {
  [CONFIG_KEYS.SEAT_HOLD_DURATION_MINUTES]: '5',
  [CONFIG_KEYS.HOLD_CUTOFF_HOURS_BEFORE_DEPARTURE]: '2',
  [CONFIG_KEYS.BOARDING_WINDOW_HOURS_BEFORE_DEPARTURE]: '4',
  [CONFIG_KEYS.THROTTLE_AUTH_LIMIT]: '5',
  [CONFIG_KEYS.THROTTLE_AUTH_TTL_MS]: '60000',
  [CONFIG_KEYS.THROTTLE_STRICT_LIMIT]: '20',
  [CONFIG_KEYS.THROTTLE_STRICT_TTL_MS]: '60000',
  [CONFIG_KEYS.THROTTLE_DEFAULT_LIMIT]: '100',
  [CONFIG_KEYS.THROTTLE_DEFAULT_TTL_MS]: '60000',
};

@Injectable()
export class SystemConfigService {
  constructor(private prisma: PrismaService) {}

  async getAll(): Promise<Record<string, string>> {
    const rows = await this.prisma.systemConfig.findMany();
    const result: Record<string, string> = { ...DEFAULTS };
    for (const row of rows) result[row.key] = row.value;
    return result;
  }

  async getValue(key: string): Promise<string> {
    const row = await this.prisma.systemConfig.findUnique({ where: { key } });
    return row?.value ?? DEFAULTS[key] ?? '';
  }

  async getNumber(key: string): Promise<number> {
    return parseInt(await this.getValue(key), 10) || parseInt(DEFAULTS[key] ?? '0', 10);
  }

  async set(key: string, value: string): Promise<void> {
    await this.prisma.systemConfig.upsert({
      where: { key },
      update: { value },
      create: { key, value },
    });
  }

  async updateMany(entries: Record<string, string>): Promise<Record<string, string>> {
    await Promise.all(Object.entries(entries).map(([k, v]) => this.set(k, v)));
    return this.getAll();
  }
}
