<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

namespace gbtool_langflow;

use core\http_client;
use GuzzleHttp\Psr7\Response;
use local_gamibot_manager\local\prompt_response;
use local_gamibot_manager\local\request_response;
use local_gamibot_manager\local\unit;
use local_gamibot_manager\local\usage;
use local_gamibot_manager\request_options;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\StreamInterface;

/**
 * Connector for Langflow.
 *
 * # Get API key from environment variable
 *
 * if
 *
 * [
 * -z
 * "
 * $LANGFLOW_API_KEY
 * "
 *
 * ]
 * ;
 *
 * then
 *
 *
 * echo
 *
 * "Error: LANGFLOW_API_KEY environment variable not found. Please set your API key in the environment variables."
 *
 * fi
 *
 * curl
 * --request POST
 * \
 *
 * --url
 * 'https://langflow.hub.inov-norte.ipp.pt/api/v1/run/2c4a5955-6551-4baf-bc44-4ba4dc6b5f90?stream=false'
 *
 * \
 *
 * --header
 * 'Content-Type: application/json'
 *
 * \
 *
 * --header
 * "x-api-key:
 * $LANGFLOW_API_KEY
 * "
 *
 * \
 *
 * --data
 * '{
 * "input_value": "hello world!",
 * "output_type": "chat",
 * "input_type": "chat"
 * }'
 */
class connector extends \local_gamibot_manager\base_connector
{

    #[\Override]
    public function get_models_by_purpose(): array
    {
        return [
            'clarify' => [],
            'summarize' => [],
            'quiz' => [],
        ];
    }

    #[\Override]
    public function get_unit(): unit
    {
        return unit::COUNT;
    }

    #[\Override]
    protected function get_headers(): array
    {
        $headers = parent::get_headers();
        if (in_array('Authorization', array_keys($headers))) {
            unset($headers['Authorization']);
            $headers['x-api-key'] = $this->instance->get_apikey();
        }
        return $headers;
    }

    #[\Override]
    public function make_request(array $data, request_options $requestoptions): request_response
    {
        global $CFG, $USER;
        $client = new http_client([
            'timeout' => get_config('local_gamibot_manager', 'requesttimeout'),
            'verify' => !empty(get_config('local_gamibot_manager', 'verifyssl')),
        ]);

        $domain = str_ireplace('https://', '', str_ireplace('http://', '', $CFG->wwwroot));
        $courseid = strval($requestoptions->get_courseid());

        $options['headers'] = $this->get_headers();
        $body = [
            'input_value' => $data['messages']['content'],
            'input_type' => 'chat',
            'output_type' => 'chat',
            'stream' => true,
            'session_id' => str_ireplace(':', '_', $domain) . '_' . $courseid . '_' . $USER->id . '_' . $requestoptions->get_options()['itemid'],
            'tweaks' => []
        ];

        $body['tweaks'][$this->get_courseinput()] = [
            'input_value' => $courseid
        ];

        $body['tweaks'][$this->get_domaininput()] = [
            'input_value' => $domain
        ];

        if ($requestoptions->get_purpose()->get_plugin_name() === 'quiz') {
            $body['tweaks'][$this->get_additionalinput1()] = [
                'input_value' =>  get_config('local_gamibot_manager', 'nr_of_questions')
            ];
        }

        $options['body'] = json_encode($body);

        try {
            $response = $client->post($this->get_endpoint_url(), $options);
        } catch (ClientExceptionInterface $exception) {
            return $this->create_error_response_from_exception($exception);
        }

        if ($response->getStatusCode() === 200) {
            $return = request_response::create_from_result($response->getBody());
        } else {
            $return = request_response::create_from_error(
                $response->getStatusCode(),
                get_string('error_sendingrequestfailed', 'local_gamibot_manager'),
                $response->getBody()->getContents(),
                $response->getBody()
            );
        }
        return $return;
    }

    #[\Override]
    public function execute_prompt_completion(StreamInterface $result, request_options $requestoptions): prompt_response
    {

        $content = json_decode($result->getContents(), true);

        return prompt_response::create_from_result(null,
            new usage(1.0),
            $content['outputs'][0]['outputs'][0]['results']['message']['data']['text']);
    }

    #[\Override]
    public function get_prompt_data(string $prompttext, request_options $requestoptions): array
    {
        $options = $requestoptions->get_options();
        $messages = ['role' => 'user', 'content' => $prompttext];
        $data = [
            'model' => $this->instance->get_model(),
            'messages' => $messages,
            'stream' => false,
            'keep_alive' => '60m',
            'options' => [
            ],
        ];
        return $data;
    }
}
