<?php

declare(strict_types=1);

namespace KimaAI\Ai\Providers\OpenRouter;

use KimaAI\Ai\Providers\Http\HttpClientInterface;
use KimaAI\Ai\Providers\OpenAI\OpenAiClient;
use KimaAI\Ai\Providers\Support\Capability;
use KimaAI\Ai\Providers\Support\ProviderMetadata;


/**
 * OpenRouter provider using the OpenAI-compatible API surface.
 */
class OpenRouterClient extends OpenAiClient {
  /**
   * Site URL sent to OpenRouter when available.
   *
   * @var string|null
   */
  private ?string $site_url;
  /**
   * Site name sent to OpenRouter when available.
   *
   * @var string|null
   */
  private ?string $site_name;

  public function __construct(
    string $api_key,
    ?string $organization = null,
    string $base_url = 'https://openrouter.ai/api/v1',
    ?HttpClientInterface $http_client = null,
    ?string $site_url = null,
    ?string $site_name = null
  ) {
    parent::__construct($api_key, null, $base_url, $http_client);
    $this->site_url = $site_url;
    $this->site_name = $site_name;

    $this->allowed_image_args = array_merge($this->allowed_image_args, [
      'modalities' => 'array',
      'image_config' => 'object',
      'aspect_ratio' => 'string',
      'image_size' => 'string',
    ]);
  }

  public function metadata(): ProviderMetadata {
    return new ProviderMetadata('openrouter', 'OpenRouter', $this->base_url, [
      Capability::CHAT,
      Capability::STREAMING_CHAT,
      Capability::RESPONSES,
      Capability::IMAGE,
      Capability::MODELS,
      Capability::TOOL_CALLING,
      Capability::OPENAI_COMPATIBLE,
    ]);
  }

  public function image(array $payload): array {
    $request = [
      'model' => (string) ($payload['model'] ?? ''),
      'messages' => $this->resolveImageMessages($payload),
      'modalities' => $this->resolveImageModalities($payload),
      'stream' => false,
    ];

    $image_config = $this->resolveImageConfig($payload);
    if ($image_config !== []) {
      $request['image_config'] = $image_config;
    }

    $response = $this->request('POST', '/chat/completions', $request);
    $images = $this->extractImageUrls($response);

    if ($images !== []) {
      $response['output'] = $images;
      $response['data'] = array_map(
        static fn(string $url): array => ['url' => $url],
        $images
      );
    }

    return $response;
  }

  private function resolveImageMessages(array $payload): array {
    if (!empty($payload['messages']) && is_array($payload['messages'])) {
      return $payload['messages'];
    }

    if (!empty($payload['input']) && is_array($payload['input'])) {
      return $payload['input'];
    }

    return [
      [
        'role' => 'user',
        'content' => (string) ($payload['prompt'] ?? ''),
      ],
    ];
  }

  private function resolveImageModalities(array $payload): array {
    if (!empty($payload['modalities']) && is_array($payload['modalities'])) {
      return array_values(array_map('strval', $payload['modalities']));
    }

    return ['image'];
  }

  private function resolveImageConfig(array $payload): array {
    if (!empty($payload['image_config']) && is_array($payload['image_config'])) {
      return $payload['image_config'];
    }

    $config = [];
    if (!empty($payload['aspect_ratio'])) {
      $config['aspect_ratio'] = (string) $payload['aspect_ratio'];
    }
    if (!empty($payload['image_size'])) {
      $config['image_size'] = (string) $payload['image_size'];
    }

    return $config;
  }

  private function extractImageUrls(array $response): array {
    $urls = [];

    foreach (($response['choices'] ?? []) as $choice) {
      if (!is_array($choice)) {
        continue;
      }

      $message = $choice['message'] ?? [];
      if (!is_array($message)) {
        continue;
      }

      foreach (($message['images'] ?? []) as $image) {
        if (!is_array($image)) {
          continue;
        }

        $url = $image['image_url']['url'] ?? $image['imageUrl']['url'] ?? null;
        if (is_string($url) && $url !== '') {
          $urls[] = $url;
        }
      }
    }

    return $urls;
  }

  protected function buildHeaders(bool $stream): array {
    $headers = [
      'Authorization: Bearer ' . $this->api_key,
      'Content-Type: application/json',
    ];

    $site_url = $this->site_url ?? (function_exists('get_bloginfo') ? get_bloginfo('url') : null);
    $site_name = $this->site_name ?? (function_exists('get_bloginfo') ? get_bloginfo('name') : null);

    if (is_string($site_url) && trim($site_url) !== '') {
      $headers[] = 'HTTP-Referer: ' . trim($site_url);
    }

    if (is_string($site_name) && trim($site_name) !== '') {
      $headers[] = 'X-OpenRouter-Title: ' . trim($site_name);
    }

    if ($stream) {
      $headers[] = 'Accept: text/event-stream';
    }

    return $headers;
  }
}
