<?php
/**
 * Anthropic Claude Provider
 *
 * Handles communication with Anthropic Claude API.
 *
 * @package Askany
 * @since 1.0.0
 */

namespace Askany\Providers;

/**
 * Claude provider class.
 */
class ClaudeProvider extends AbstractProvider {
	/**
	 * {@inheritdoc}
	 */
	public function get_provider_name(): string {
		return 'claude';
	}

	/**
	 * {@inheritdoc}
	 */
	public function get_provider_display_name(): string {
		return 'Anthropic Claude';
	}

	/**
	 * {@inheritdoc}
	 */
	public function get_available_models(): array {
		return array(
			'claude-sonnet-4-20250514'    => array(
				'name'               => 'Claude Sonnet 4.6',
				'description'        => 'Latest Sonnet - Fast & capable (Recommended)',
				'max_tokens'         => 200000,
				'cost_per_1k_tokens' => 0.003,
				'recommended'        => true,
			),
			'claude-opus-4-20250514'      => array(
				'name'               => 'Claude Opus 4.6',
				'description'        => 'Most capable model for complex tasks',
				'max_tokens'         => 200000,
				'cost_per_1k_tokens' => 0.015,
			),
			'claude-3-5-sonnet-20241022'  => array(
				'name'               => 'Claude 3.5 Sonnet',
				'description'        => 'Best for agents & coding',
				'max_tokens'         => 200000,
				'cost_per_1k_tokens' => 0.003,
			),
			'claude-3-5-haiku-20241022'   => array(
				'name'               => 'Claude 3.5 Haiku',
				'description'        => 'Fastest & most cost-effective',
				'max_tokens'         => 200000,
				'cost_per_1k_tokens' => 0.0008,
			),
			'claude-3-opus-20240229'      => array(
				'name'               => 'Claude 3 Opus',
				'description'        => 'Previous generation flagship',
				'max_tokens'         => 200000,
				'cost_per_1k_tokens' => 0.015,
			),
			'claude-3-sonnet-20240229'    => array(
				'name'               => 'Claude 3 Sonnet',
				'description'        => 'Balanced performance',
				'max_tokens'         => 200000,
				'cost_per_1k_tokens' => 0.003,
			),
			'claude-3-haiku-20240307'     => array(
				'name'               => 'Claude 3 Haiku',
				'description'        => 'Fast and cost-effective',
				'max_tokens'         => 200000,
				'cost_per_1k_tokens' => 0.00025,
			),
		);
	}

	/**
	 * {@inheritdoc}
	 */
	public function get_default_model(): string {
		return 'claude-sonnet-4-20250514';
	}

	/**
	 * {@inheritdoc}
	 */
	public function get_default_endpoint(): string {
		return 'https://api.anthropic.com/v1/messages';
	}

	/**
	 * {@inheritdoc}
	 */
	public function send_chat_request( array $messages, array $options = array() ) {
		$defaults = array(
			'model'       => $this->get_default_model(),
			'temperature' => 0.3,
			'max_tokens'  => 800,
		);

		$params = array_merge( $defaults, $options );

		// Extract system message if present
		$system_message = '';
		$claude_messages = array();

		foreach ( $messages as $message ) {
			if ( 'system' === $message['role'] ) {
				$system_message = $message['content'];
			} else {
				// Claude uses 'assistant' instead of 'ai'
				$role = 'user' === $message['role'] ? 'user' : 'assistant';
				$claude_messages[] = array(
					'role'    => $role,
					'content' => $message['content'],
				);
			}
		}

		// Build request data
		$request_data = array(
			'model'       => $params['model'],
			'messages'    => $claude_messages,
			'max_tokens'  => intval( $params['max_tokens'] ),
			'temperature' => floatval( $params['temperature'] ),
		);

		// Add system message if present
		if ( ! empty( $system_message ) ) {
			$request_data['system'] = $system_message;
		}

		// Add optional parameters
		if ( isset( $params['top_p'] ) ) {
			$request_data['top_p'] = floatval( $params['top_p'] );
		}
		if ( isset( $params['top_k'] ) ) {
			$request_data['top_k'] = intval( $params['top_k'] );
		}

		$headers = array(
			'x-api-key'         => $this->api_key,
			'anthropic-version' => '2023-06-01',
		);

		$data = $this->make_request( $this->api_url, $request_data, $headers );

		if ( ! $data ) {
			return false;
		}

		// Check for error in response
		if ( isset( $data['error'] ) ) {
			$error_msg = isset( $data['error']['message'] ) ? $data['error']['message'] : 'Unknown error';
			$this->last_error = $error_msg;
			return false;
		}

		// Extract text from response
		if ( ! isset( $data['content'][0]['text'] ) ) {
			$this->last_error = 'Unexpected response structure';
			return false;
		}

		return array(
			'text' => $data['content'][0]['text'],
		);
	}
}
