<?php

namespace OtomaticAi\Models\Presets;

use OtomaticAi\Api\OpenAi\Client as OpenAiClient;
use OtomaticAi\Api\OpenAi\PoolClient as PoolOpenAiClient;

class OpenAIPreset extends Preset
{
    /**
     * Create the OpenAI Chat API payload
     *
     * @param array $params
     * @return array
     */
    public function payload(array $params = []): array
    {
        $model = $this->model;

        $messages = $this->replaceMessagesVariables($params);

        if ($model === "gpt-4-5") {
            $model = "gpt-4.5-preview";
        }

        if ($model === "o1-mini") {
            $messages = array_map(function ($message) {
                if ($message["role"] === "system") {
                    $message["role"] = "user";
                }
                return $message;
            }, $messages);
        }

        $payload = [
            "model" => $model,
            "temperature" => $this->temperature ? intval($this->temperature) : 1,
            "top_p" => $this->top_p ? intval($this->top_p) : 1,
            "presence_penalty" => $this->presence_penalty ? round($this->presence_penalty, 2) : 0,
            "frequency_penalty" => $this->frequency_penalty ? round($this->frequency_penalty, 2) : 0,
            "n" => 1,
            "stream" => false,
            "messages" => $messages,
        ];

        if ($this->is_json && $model !== "o1-mini") {
            $payload["response_format"] = [
                "type" => "json_object"
            ];
        };

        return $payload;
    }

    /**
     * Create the OpenAI Response API payload
     *
     * @param array $params
     * @return array
     */
    public function payloadResponse(array $params = []): array
    {
        $payload = $this->payload($params);

        $input = [];

        foreach ($payload["messages"] as $message) {
            $input[] = [
                "role" => $message["role"],
                "content" => $message["content"],
                "type" => "message",
            ];
        }
        
        $newPayload = [
            "model" => $payload["model"],
            "store" => false,
            "input" => $input,
        ];

        if ($payload["response_format"]) {
            $newPayload["text"] = [
                "format" => $payload["response_format"],
            ];
        }

        return $newPayload;
    }

    public function formatResponse(array $response)
    {
        $newResponse = $response;
        $text = "";

        foreach ($response["output"] as $output) {
            if ($output["role"] === "assistant") {
                foreach ($output["content"] as $content) {
                    if ($content["type"] === "output_text") {
                        $text .= $content["text"];
                    }
                }
                break;
            }
        }

        $newResponse["choices"] = [
            [
                "message" => [
                    "content" => $text,
                ],
            ],
        ];

        return $newResponse;
    }    

    public function process(array $params = [])
    {
        $api = new OpenAiClient;
        $response = $api->response($this->payloadResponse($params));

        return $this->formatResponse($response);
    }

    public function processPool(array $params = [])
    {
        $api = new PoolOpenAiClient;
        $params = array_map(function ($p) {
            return $this->payloadResponse($p);
        }, $params);

        $responses = $api->response($params);

        for($i = 0; $i < count($responses); $i++) {
            $responses[$i] = $this->formatResponse($responses[$i]);
        }

        return $responses;
    }
}
