/**
 * Billing Calculation and Cost Estimation
 *
 * Customer billing is based on source characters — the exact content
 * the customer sends for translation. No transformations are applied.
 */

/**
 * Count billable source characters.
 *
 * Counts the exact length of the content as received from the customer.
 * HTML tags are included in the count because they are part of the
 * customer's string (e.g. "Otto Reid <br><sub>Springfield, IL</sub>").
 * The translation engine handles HTML preservation separately.
 */
export function countSourceCharacters(content: string): number {
  return content.length;
}

/**
 * Calculate customer-facing cost based on characters used and per-char rate.
 *
 * @param charsUsed Number of source characters
 * @param costPerChar Customer's cost per character (subscription_price / credit_allocation)
 * @returns Customer cost in USD, rounded to 4 decimal places
 */
export function calculateCustomerCostByChars(charsUsed: number, costPerChar: number): number {
  const cost = charsUsed * costPerChar;
  return Math.round(cost * 10000) / 10000;
}

/**
 * Estimate token count from text content (internal use for Gemini cost estimation)
 *
 * Rough estimation: ~1 token per 4 characters for English
 * Includes overhead for translation prompt and output
 */
export function estimateTokens(content: string, _sourceLang: string = 'en', _targetLang: string = 'en'): number {
  const baseTokens = Math.ceil(content.length / 4);
  const promptOverhead = 50;
  const outputTokens = baseTokens;
  return baseTokens + promptOverhead + outputTokens;
}

/**
 * Calculate internal Gemini API cost for token usage
 *
 * @param tokens Number of tokens used
 * @returns Cost in USD
 */
const GEMINI_PROVIDER_PRICING_USD_PER_MILLION_TOKENS: Record<
  string,
  { input: number; output: number }
> = {
  'gemini-3.1-flash-lite': { input: 0.25, output: 1.5 },
  'gemini-2.5-flash': { input: 0.3, output: 2.5 },
};

export function calculateCost(
  inputTokens: number,
  outputTokens: number,
  model: string
): number {
  const pricing = GEMINI_PROVIDER_PRICING_USD_PER_MILLION_TOKENS[model];
  if (!pricing) {
    throw new Error(`Provider pricing is not configured for model ${model}`);
  }
  const cost = (
    inputTokens * pricing.input + outputTokens * pricing.output
  ) / 1_000_000;
  return Math.round(cost * 1_000_000) / 1_000_000;
}

/**
 * Calculate credit allocation for subscription tier (in characters)
 */
export function getCreditAllocationForTier(tier: 'starter' | 'professional' | 'enterprise'): number {
  const allocations = {
    starter: 1000000,      // 1M characters/month
    professional: 4000000, // 4M characters/month
    enterprise: 15000000,  // 15M characters/month
  };

  return allocations[tier];
}

/**
 * Estimate processing time based on content length
 *
 * @param content Content to translate
 * @returns Estimated time in milliseconds
 */
export function estimateProcessingTime(content: string): number {
  const tokens = estimateTokens(content);

  // AI translation processing rate (~35 tokens/second average)
  const tokensPerSecond = 35;
  const timeInSeconds = tokens / tokensPerSecond;

  // Add processing overhead (2 seconds)
  const overhead = 2000;

  // Convert to milliseconds
  const timeInMs = (timeInSeconds * 1000) + overhead;

  return Math.ceil(timeInMs);
}

/**
 * Format token count for display (e.g., "1.5K", "250K", "1.2M")
 */
export function formatTokenCount(tokens: number): string {
  if (tokens < 1000) {
    return tokens.toString();
  } else if (tokens < 1000000) {
    return `${(tokens / 1000).toFixed(1)}K`;
  } else {
    return `${(tokens / 1000000).toFixed(1)}M`;
  }
}

/**
 * Format cost for display (e.g., "$0.0012", "$1.50")
 */
export function formatCost(cost: number): string {
  if (cost < 0.01) {
    return `$${cost.toFixed(4)}`;
  } else if (cost < 1) {
    return `$${cost.toFixed(3)}`;
  } else {
    return `$${cost.toFixed(2)}`;
  }
}
