<?php

declare(strict_types=1);

namespace App\Services\AiAssistant\Context;

use App\Models\AiConversation;
use Illuminate\Support\Collection;

class ConversationContext
{
    protected int $maxContextMessages;

    public function __construct()
    {
        $this->maxContextMessages = config('prism.max_context_messages', 50);
    }

    public function build(AiConversation $conversation): array
    {
        $messages = $conversation->messages()
            ->where('role', '!=', 'system')
            ->orderByDesc('id')
            ->take($this->maxContextMessages)
            ->get()
            ->sortBy('id')
            ->values();

        return [
            'messages' => $this->mapToPrismMessages($messages),
        ];
    }

    protected function mapToPrismMessages(Collection $messages): array
    {
        $prismMessages = [];

        foreach ($messages as $msg) {
            $prismMessages = [
                ...$prismMessages,
                ...$this->mapMessage($msg),
            ];
        }

        return $prismMessages;
    }

    protected function mapMessage(\App\Models\AiMessage $msg): array
    {
        return match ($msg->role) {
            'user' => [new \Prism\Prism\ValueObjects\Messages\UserMessage($msg->content)],
            'assistant' => $this->mapAssistantMessage($msg),
            default => [],
        };
    }

    protected function mapAssistantMessage(\App\Models\AiMessage $msg): array
    {
        $messages = [];

        $messages[] = new \Prism\Prism\ValueObjects\Messages\AssistantMessage(
            content: $msg->content ?? '',
            toolCalls: $this->buildToolCalls($msg->tool_calls),
        );

        foreach ($msg->toolCallsExecuted as $executed) {
            $messages[] = new \Prism\Prism\ValueObjects\Messages\ToolResultMessage([
                new \Prism\Prism\ValueObjects\ToolResult(
                    toolCallId: $executed->tool_call_id ?? '',
                    toolName: $executed->tool_name,
                    args: $executed->arguments ?? [],
                    result: $executed->result ?? '',
                ),
            ]);
        }

        return $messages;
    }

    protected function buildToolCalls(?array $toolCalls): array
    {
        if (! $toolCalls) {
            return [];
        }

        return array_map(fn ($tc) => new \Prism\Prism\ValueObjects\ToolCall(
            id: $tc['id'] ?? '',
            name: $tc['name'] ?? '',
            arguments: $tc['arguments'] ?? []
        ), $toolCalls);
    }
}
