<?php

declare(strict_types=1);

namespace NeuronAI\Providers\Anthropic;

use NeuronAI\Exceptions\ProviderException;
use NeuronAI\Providers\ToolMapperInterface;
use NeuronAI\Tools\ProviderToolInterface;
use NeuronAI\Tools\ToolInterface;
use NeuronAI\Tools\ToolPropertyInterface;

use function array_reduce;
use function is_string;
use function array_merge;

class ToolMapper implements ToolMapperInterface
{
    /**
     * @throws ProviderException
     */
    public function map(array $tools): array
    {
        $mapping = [];

        foreach ($tools as $tool) {
            $mapping[] = match (true) {
                $tool instanceof ToolInterface => $this->mapTool($tool),
                $tool instanceof ProviderToolInterface => $this->mapProviderTool($tool),
                default => throw new ProviderException('Could not map tool type '.$tool::class),
            };
        }

        return $mapping;
    }

    protected function mapTool(ToolInterface $tool): array
    {
        $properties = array_reduce($tool->getProperties(), function (array $carry, ToolPropertyInterface $property): array {
            $carry[$property->getName()] = $property->getJsonSchema();
            return $carry;
        }, []);

        $payload = [
            'name' => $tool->getName(),
            'description' => $tool->getDescription(),
            'input_schema' => [
                'type' => 'object',
                'properties' => empty($properties) ? null : $properties,
                'required' => $tool->getRequiredProperties(),
            ],
        ];

        if ($tool->getParameters() !== []) {
            return array_merge($payload, $tool->getParameters());
        }

        return $payload;
    }

    protected function mapProviderTool(ProviderToolInterface $tool): array
    {
        $payload = [
            'type' => $tool->getType(),
            ...$tool->getOptions(),
        ];

        if (is_string($tool->getName())) {
            $payload['name'] = $tool->getName();
        }

        return $payload;
    }
}
