import query, { transaction } from '../server-utils/query.js';
import { PlanGatedFeature } from '../types/serverTypes.js';

const SERVICE_LIMITS = {
  lalala: {
    limit: 50,
    minutes: 3 * 60,
    feature: PlanGatedFeature.StemSplit,
  },
  demucs: {
    limit: 1000,
    minutes: 24 * 60,
    feature: PlanGatedFeature.StemSplit,
  },
  voiceConversion: {
    limit: 1000,
    minutes: 24 * 60,
    feature: PlanGatedFeature.ExecutePrototype,
  },
};

const runServiceWithQuota = async (
  user: { id: number; features: Partial<Record<PlanGatedFeature, true>> },
  service: keyof typeof SERVICE_LIMITS,
  fn: (q: typeof query) => Promise<any>,
  onQuotaExceeded: () => void
) => {
  if (!SERVICE_LIMITS[service]) {
    throw new Error(`No service ${service} found`);
  }

  if (!user) {
    throw new Error('Not authenticated');
  }

  const { limit, minutes, feature } = SERVICE_LIMITS[service];
  if (!user.features[feature]) {
    onQuotaExceeded();
    return;
  }

  return transaction(async (transactionQuery) => {
    const queryResult = await transactionQuery(
      `SELECT COUNT(*) FROM service_quotas WHERE user_id = $1 AND service = $2 AND created_at > NOW() - INTERVAL '1 MINUTE' * $3`,
      [user.id, service, minutes]
    );
    const count = queryResult.rows[0].count;
    if (count >= limit) {
      onQuotaExceeded();
    } else {
      const result = await fn(transactionQuery);
      await transactionQuery(`INSERT INTO service_quotas (user_id, service) VALUES ($1, $2)`, [user.id, service]);
      return result;
    }
  });
};

export default runServiceWithQuota;
