<?php

namespace Limb_Chatbot\Includes\AI_Providers\Deep_Seek\Services;

use Exception;
use Limb_Chatbot\Includes\Data_Objects\AI_Model;
use Limb_Chatbot\Includes\AI_Providers\Deep_Seek\Deep_Seek;

/**
 * Class AI_Model_Cost_Service
 *
 * Handles cost calculation for DeepSeek AI models.
 * DeepSeek uses flat-rate pricing with cache-based differentiation:
 * - Input tokens (cache hit): $0.028/1M tokens
 * - Input tokens (cache miss): $0.28/1M tokens
 * - Output tokens: $0.42/1M tokens
 *
 * @package Limb_Chatbot\Includes\AI_Providers\Deep_Seek\Services
 * @since 1.0.0
 */
class AI_Model_Cost_Service {

	/**
	 * Calculate the cost for a token usage based on cache hit/miss tokens.
	 *
	 * DeepSeek API returns prompt_cache_hit_tokens and prompt_cache_miss_tokens
	 * which allows for accurate cost calculation based on caching.
	 *
	 * @param AI_Model $model              The AI model used.
	 * @param int      $cache_hit_tokens   Number of tokens that hit the cache.
	 * @param int      $cache_miss_tokens  Number of tokens that missed the cache.
	 *
	 * @return float The calculated input cost.
	 * @throws Exception
	 * @since 1.0.0
	 */
	public static function calculate_input_cost( AI_Model $model, int $cache_hit_tokens, int $cache_miss_tokens ): float {
		$cache_hit_cost  = (float) $model->get_meta( 'input_token_cost_cache_hit' ) ?: 0.000000028;
		$cache_miss_cost = (float) $model->get_meta( 'input_token_cost_cache_miss' ) ?: 0.00000028;

		return ( $cache_hit_tokens * $cache_hit_cost ) + ( $cache_miss_tokens * $cache_miss_cost );
	}

	/**
	 * Calculate the output cost for a given number of output tokens.
	 *
	 * @param AI_Model $model         The AI model used.
	 * @param int      $output_tokens Number of output tokens.
	 *
	 * @return float The calculated output cost.
	 * @throws Exception
	 * @since 1.0.0
	 */
	public static function calculate_output_cost( AI_Model $model, int $output_tokens ): float {
		$output_cost = (float) $model->get_meta( 'output_token_cost' ) ?: 0.00000042;

		return $output_tokens * $output_cost;
	}

	/**
	 * Calculate total cost for a DeepSeek API response.
	 *
	 * @param AI_Model $model              The AI model used.
	 * @param int      $cache_hit_tokens   Number of prompt tokens that hit the cache.
	 * @param int      $cache_miss_tokens  Number of prompt tokens that missed the cache.
	 * @param int      $output_tokens      Number of completion tokens.
	 *
	 * @return float The total calculated cost.
	 * @throws Exception
	 * @since 1.0.0
	 */
	public static function calculate_total_cost( AI_Model $model, int $cache_hit_tokens, int $cache_miss_tokens, int $output_tokens ): float {
		$input_cost  = self::calculate_input_cost( $model, $cache_hit_tokens, $cache_miss_tokens );
		$output_cost = self::calculate_output_cost( $model, $output_tokens );

		return $input_cost + $output_cost;
	}

	/**
	 * Check if the model belongs to DeepSeek provider.
	 *
	 * @param AI_Model $model The AI model to check.
	 *
	 * @return bool True if the model is a DeepSeek model.
	 * @since 1.0.0
	 */
	public static function is_deep_seek_model( AI_Model $model ): bool {
		return $model->get_ai_provider_id() === Deep_Seek::$id;
	}
}

