import { Injectable } from '@nestjs/common';
import { PlanRepository } from '../../infrastructure/repositories/plan.repository';
import { SubscriptionRepository } from '../../infrastructure/repositories/subscription.repository';
import { UsageAggregateRepository } from '../../infrastructure/repositories/usage-aggregate.repository';

export interface QuotaCheckResult {
  allowed: boolean;
  remaining: number;
  usedTokens: number;
  limitTokens: number;
  isHardLimit: boolean;
  overageAllowed: boolean;
}

@Injectable()
export class CheckTokenQuotaUseCase {
  constructor(
    private readonly planRepo: PlanRepository,
    private readonly subscriptionRepo: SubscriptionRepository,
    private readonly usageAggRepo: UsageAggregateRepository,
  ) {}

  async execute(tenantId: string): Promise<QuotaCheckResult> {
    const subscription = await this.subscriptionRepo.findByTenantId(tenantId);
    if (!subscription) {
      // No subscription: block all usage
      return { allowed: false, remaining: 0, usedTokens: 0, limitTokens: 0, isHardLimit: true, overageAllowed: false };
    }

    const plan = await this.planRepo.findById(subscription.planId);
    if (!plan) {
      return { allowed: false, remaining: 0, usedTokens: 0, limitTokens: 0, isHardLimit: true, overageAllowed: false };
    }

    const now = new Date();
    const usage = await this.usageAggRepo.findByTenantAndPeriod(
      tenantId,
      now.getFullYear(),
      now.getMonth() + 1,
    );

    const usedTokens = usage?.totalTokens ?? 0;
    const baseLimit = plan.includedTokens;

    // Enterprise: no limit (-1)
    if (baseLimit === -1) {
      return {
        allowed: true,
        remaining: Number.MAX_SAFE_INTEGER,
        usedTokens,
        limitTokens: -1,
        isHardLimit: false,
        overageAllowed: true,
      };
    }

    const hardLimitTokens = Math.floor(baseLimit * (plan.hardLimitPercent / 100));
    const overageAllowed = plan.overageRateCentsPerMTokenUsd > 0;

    // Hard limit check (applies to all plans)
    if (plan.hardLimitPercent > 0 && usedTokens >= hardLimitTokens) {
      return {
        allowed: false,
        remaining: 0,
        usedTokens,
        limitTokens: hardLimitTokens,
        isHardLimit: true,
        overageAllowed,
      };
    }

    const remaining = hardLimitTokens - usedTokens;
    return {
      allowed: true,
      remaining,
      usedTokens,
      limitTokens: hardLimitTokens,
      isHardLimit: false,
      overageAllowed,
    };
  }
}
