/**
 * Voice Quota DB-Layer
 *
 * Tracks daily TTS seconds per user. Quota resets automatically when the
 * calendar day (UTC) changes since the last reset.
 *
 * Schema fields on `profiles`:
 *   voice_seconds_used_today  INTEGER  NOT NULL DEFAULT 0
 *   voice_quota_reset_at      TIMESTAMP
 */
import { usePrisma } from "../utils/prisma";
import { getPlanLimits } from "../utils/plan-features";

/** Midnight UTC for the current day (used as reset boundary). */
function todayUtcMidnight(): Date {
  const d = new Date();
  d.setUTCHours(0, 0, 0, 0);
  return d;
}

/**
 * Returns remaining quota seconds for the user today.
 * Automatically resets counter if last reset was before today (UTC).
 * Returns Infinity when dailyQuotaSeconds === 0 (Legend unlimited).
 */
export async function getRemainingVoiceQuota(
  userId: string,
  plan: string,
): Promise<number> {
  const limits = getPlanLimits(plan);
  const { dailyQuotaSeconds } = limits.voice;

  // Unlimited plan — short-circuit
  if (dailyQuotaSeconds === 0) return Infinity;

  const db = usePrisma();
  const midnight = todayUtcMidnight();

  const profile = await db.profile.findUnique({
    where: { id: userId },
    select: {
      voiceSecondsUsedToday: true,
      voiceQuotaResetAt: true,
    },
  });

  if (!profile) throw createError({ statusCode: 404, message: "Profil nicht gefunden" });

  // Reset if no reset-stamp yet OR stamp is before today's midnight UTC
  const needsReset =
    !profile.voiceQuotaResetAt ||
    profile.voiceQuotaResetAt < midnight;

  if (needsReset) {
    // Idempotent: even if two concurrent requests hit this, the result is the
    // same full quota — no race condition risk here.
    await db.profile.update({
      where: { id: userId },
      data: {
        voiceSecondsUsedToday: 0,
        voiceQuotaResetAt: midnight,
      },
    });
    return dailyQuotaSeconds;
  }

  const used = profile.voiceSecondsUsedToday ?? 0;
  return Math.max(0, dailyQuotaSeconds - used);
}

/**
 * Increment the used-seconds counter. No-op for unlimited plans (Legend).
 * Does NOT validate against quota — caller must check `getRemainingVoiceQuota`
 * first.
 */
export async function consumeVoiceQuota(
  userId: string,
  plan: string,
  seconds: number,
): Promise<void> {
  const limits = getPlanLimits(plan);
  if (limits.voice.dailyQuotaSeconds === 0) return; // unlimited — no tracking needed

  const db = usePrisma();
  const midnight = todayUtcMidnight();

  await db.profile.update({
    where: { id: userId },
    data: {
      voiceSecondsUsedToday: { increment: Math.max(0, Math.round(seconds)) },
      // Ensure reset-stamp is set (idempotent with getRemainingVoiceQuota reset)
      voiceQuotaResetAt: midnight,
    },
  });
}

/**
 * Estimate audio duration in seconds for a given text length.
 * Rule of thumb: German TTS ~13 chars/sec at default speed.
 * Minimum 1 second.
 */
export function estimateAudioSeconds(text: string): number {
  return Math.max(1, Math.ceil(text.length / 13));
}
