import type { AsukaLicenseEntitlements } from './license.types';

export type AsukaCommercialQuotaKey =
  | 'exports'
  | 'aiCredits';

export interface AsukaCommercialQuotaState {
  key: AsukaCommercialQuotaKey;
  limit: number | null;
  used: number | null;
  remaining: number | null;
  reached: boolean;
}

const LIMIT_KEY_MAP: Record<AsukaCommercialQuotaKey, string> = {
  exports: 'exportsPerMonth',
  aiCredits: 'aiCreditsPerMonth',
};

const USED_KEY_MAP: Record<AsukaCommercialQuotaKey, string> = {
  exports: 'exportsUsed',
  aiCredits: 'aiCreditsUsed',
};

const REMAINING_KEY_MAP: Record<AsukaCommercialQuotaKey, string> = {
  exports: 'exportsRemaining',
  aiCredits: 'aiCreditsRemaining',
};

function toNumber(value: unknown): number | null {
  if (typeof value === 'number' && Number.isFinite(value)) return value;
  if (typeof value === 'string' && value.trim()) {
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : null;
  }
  return null;
}

export function getCommercialLimit(
  license: AsukaLicenseEntitlements | null | undefined,
  key: AsukaCommercialQuotaKey,
): number | null {
  return toNumber(license?.limits?.[LIMIT_KEY_MAP[key]]);
}

export function getCommercialUsage(
  license: AsukaLicenseEntitlements | null | undefined,
  key: AsukaCommercialQuotaKey,
): number | null {
  return toNumber(license?.usage?.[USED_KEY_MAP[key]]);
}

export function getCommercialRemaining(
  license: AsukaLicenseEntitlements | null | undefined,
  key: AsukaCommercialQuotaKey,
): number | null {
  const explicitRemaining = toNumber(license?.usage?.[REMAINING_KEY_MAP[key]]);
  if (explicitRemaining !== null) return explicitRemaining;
  const limit = getCommercialLimit(license, key);
  const used = getCommercialUsage(license, key);
  if (limit === null || used === null) return limit;
  return Math.max(0, limit - used);
}

export function getCommercialQuotaState(
  license: AsukaLicenseEntitlements | null | undefined,
  key: AsukaCommercialQuotaKey,
): AsukaCommercialQuotaState {
  const limit = getCommercialLimit(license, key);
  const used = getCommercialUsage(license, key);
  const remaining = getCommercialRemaining(license, key);
  return {
    key,
    limit,
    used,
    remaining,
    reached: remaining !== null && remaining <= 0,
  };
}

export function isCommercialQuotaReached(
  license: AsukaLicenseEntitlements | null | undefined,
  key: AsukaCommercialQuotaKey,
): boolean {
  return getCommercialQuotaState(license, key).reached;
}
