<?php

declare(strict_types=1);

namespace LolaCore\LLM\Providers\DeepSeek;

use WordPress\AiClient\Messages\Enums\ModalityEnum;
use WordPress\AiClient\Providers\Http\DTO\Request;
use WordPress\AiClient\Providers\Http\DTO\Response;
use WordPress\AiClient\Providers\Http\Enums\HttpMethodEnum;
use WordPress\AiClient\Providers\Http\Exception\ResponseException;
use WordPress\AiClient\Providers\Models\DTO\ModelMetadata;
use WordPress\AiClient\Providers\Models\DTO\SupportedOption;
use WordPress\AiClient\Providers\Models\Enums\CapabilityEnum;
use WordPress\AiClient\Providers\Models\Enums\OptionEnum;
use WordPress\AiClient\Providers\OpenAiCompatibleImplementation\AbstractOpenAiCompatibleModelMetadataDirectory;

/**
 * Class for the DeepSeek model metadata directory.
 */
class DeepSeekModelMetadataDirectory extends AbstractOpenAiCompatibleModelMetadataDirectory
{
    /**
     * {@inheritDoc}
     */
    protected function createRequest(HttpMethodEnum $method, string $path, array $headers = [], $data = null): Request
    {
        return new Request(
            $method,
            DeepSeekProvider::url($path),
            $headers,
            $data
        );
    }

    /**
     * {@inheritDoc}
     */
    protected function parseResponseToModelMetadataList(Response $response): array
    {
        $responseData = $response->getData();
        if (!isset($responseData['data']) || !$responseData['data']) {
            throw ResponseException::fromMissingData('DeepSeek', 'data');
        }

        $capabilities = [
            CapabilityEnum::textGeneration(),
            CapabilityEnum::chatHistory(),
        ];
        
        $options = [
            new SupportedOption(OptionEnum::systemInstruction()),
            new SupportedOption(OptionEnum::maxTokens()),
            new SupportedOption(OptionEnum::temperature()),
            new SupportedOption(OptionEnum::topP()),
            new SupportedOption(OptionEnum::stopSequences()),
            new SupportedOption(OptionEnum::outputMimeType(), ['text/plain', 'application/json']),
            new SupportedOption(OptionEnum::outputSchema()),
            new SupportedOption(OptionEnum::functionDeclarations()),
            new SupportedOption(
                OptionEnum::inputModalities(),
                [
                    [ModalityEnum::text()],
                ]
            ),
            new SupportedOption(OptionEnum::outputModalities(), [[ModalityEnum::text()]]),
        ];

        $modelsData = (array) $responseData['data'];

        $models = array();
        foreach ($modelsData as $modelData) {
            if (! is_array($modelData) || ! isset($modelData['id'])) {
                continue;
            }
            $modelId = (string) $modelData['id'];
            if (! DeepSeekModelSupport::isV4Model($modelId)) {
                continue;
            }
            $models[] = new ModelMetadata(
                $modelId,
                $modelId,
                $capabilities,
                $options
            );
        }

        usort($models, [$this, 'modelSortCallback']);

        return $models;
    }

    /**
     * Sorts models to put flagship V4 models first.
     * Priority: deepseek-v4-pro → deepseek-v4-flash → other v4 variants.
     */
    protected function modelSortCallback(ModelMetadata $a, ModelMetadata $b): int
    {
        $aId = $a->getId();
        $bId = $b->getId();

        $priority = static function (string $id): int {
            if (str_starts_with($id, 'deepseek-v4-pro')) {
                return 0;
            }
            if (str_starts_with($id, 'deepseek-v4-flash')) {
                return 1;
            }
            if (str_starts_with($id, 'deepseek-v4')) {
                return 2;
            }
            return 9;
        };

        $pA = $priority($aId);
        $pB = $priority($bId);

        if ($pA !== $pB) {
            return $pA <=> $pB;
        }

        return strcmp($aId, $bId);
    }
}
