<?php
include 'common/function.php';
include "user/common.php";
$checkRedisResult = json_decode(CheckRedis::Run(__RedisLimit__ , __RedisInterval__));
$act = isset($_GET[ 'act' ]) ? purge($_GET[ 'act' ]) : '';

if ($act === 'context') {
    session_start();
    $context  = json_decode($_POST[ 'context' ] ?: "[]") ?: [];
    $postData = [
        "model"       => "gpt-3.5-turbo-0301" ,
        // gpt-3.5-turbo
        "temperature" => 0 ,
        "stream"      => true ,
        "messages"    => [] ,
    ];
    if ( !empty($context)) {
        $context = array_slice($context , -5);
        foreach ($context as $message) {
            $postData[ 'messages' ][] = [
                'role'    => 'user' ,
                'content' => str_replace("\n" , "\\n" , $message[ 0 ])
            ];
            $postData[ 'messages' ][] = [
                'role'    => 'assistant' ,
                'content' => str_replace("\n" , "\\n" , $message[ 1 ])
            ];
        }
    }
    $dataMessage = $_POST[ 'message' ];
    if (__BAD_WORDS__) {
        if (checkBadWords($dataMessage)) {
            exit(return_msg('500' , '触发违禁词,请重新发起会话'));
        }
    }
    $postData[ 'messages' ][] = [
        'role'    => 'user' ,
        'content' => $dataMessage
    ];
    $postData                 = json_encode($postData);

    $_SESSION[ 'data' ] = $postData;

    //用户信息
    try {
        if ($islogin) {
            if ( !empty(getUserMemberInfo($user_info[ 'id' ])[ 'chat_limit' ]) || getUserMemberInfo($user_info[ 'id' ])[ 'plans' ]) {
                $DbKey  = Db::table('app_keys' , 'AS K')
                            ->where(['key_status' => 1])
                            ->field('K.gpt_keys')
                            ->select();
                $ApiKey = '';
                if ($DbKey) {
                    $keys = [];
                    foreach ($DbKey as $value) {
                        $keys[] = $value[ 'gpt_keys' ];
                    }
                    $random_key = array_rand($keys);
                    $ApiKey     = $keys[ $random_key ];
                }
                if (getUserMemberInfo($user_info[ 'id' ])[ 'chat_limit' ] === '0') {
                    exit(return_msg(307 , '对话额度不足'));
                }
                $_SESSION[ 'key' ] = $ApiKey;
                reduceChatLimit($user_info[ 'id' ] , 1);
                exit(ReturnSuccess('success'));
            } else {
                exit(return_msg(306 , '对话额度不足，是否开通会员' , [
                    'btn_text' => '开通' ,
                    'url'      => 'user/plans.php'
                ]));
            }
        } else {
            if (__ENABLE_LOCAL_KEY_INPUT__) {
                if (( isset($_POST[ 'key' ]) ) && ( !empty($_POST[ 'key' ]) )) {
                    $_SESSION[ 'key' ] = $_POST[ 'key' ];
                    exit(ReturnSuccess('success'));
                } else {
                    exit(return_msg(305 , 'Secret Key 不能为空，如果没有，可以注册账户无需输入Key',[
                        'btn_text' => '登录' ,
                        'url'      => 'user/login.php'
                    ]));
                }
            } else {
                exit(return_msg(302 , '请先登录或注册' , [
                    'btn_text' => '登录' ,
                    'url'      => 'user/login.php'
                ]));
            }
        }
    }
    catch (Exception $e) {
        exit(ReturnError('服务器错误，请联系管理员'));
    }


    //    exit(ReturnSuccess('success'));
}

if ($act === 'comps') {
    header("Access-Control-Allow-Origin: *");
    header("Content-Type: text/event-stream");
    header("X-Accel-Buffering: no");
    header("Cache-Control: no-cache"); // 防止浏览器缓存
    session_start();
    $postData               = $_SESSION[ 'data' ];
    $_SESSION[ 'response' ] = "";
    $ch                     = curl_init();

    if (isset($_SESSION[ 'key' ])) {
        $openaiApiKey = $_SESSION[ 'key' ];
    }

    $headers = [
        'Accept: application/json' ,
        'Content-Type: application/json' ,
        'Authorization: Bearer ' . $openaiApiKey ,
    ];

    setcookie("errCode" , ""); //EventSource无法获取错误信息，通过cookie传递
    setcookie("errMsg" , "");

    $callback = function ($curl , $data) {
        $complete = json_decode($data);
        if (isset($complete->error)) {
            setcookie("errCode" , $complete->error->code);
            setcookie("errMsg" , $data);
            if (strpos($complete->error->message , "Rate limit reached") === 0) { //访问频率超限错误返回的code为空，特殊处理一下
                setcookie("errCode" , "rateLimitReached");
            }
            if (strpos($complete->error->message , "Your access was terminated") === 0) { //违规使用，被封禁，特殊处理一下
                setcookie("errCode" , "accessTerminated");
            }
            if (strpos($complete->error->message , "You didn't provide an API key") === 0) { //未提供API-KEY
                setcookie("errCode" , "noApiKey");
            }
            if (strpos($complete->error->message , "You exceeded your current quota") === 0) { //API-KEY余额不足
                setcookie("errCode" , "insufficientQuota");
            }
            if (strpos($complete->error->message , "That model is currently overloaded") === 0) { //OpenAI服务器超负荷
                setcookie("errCode" , "modelOverloaded");
            }
        } else {
            echo $data;
            $_SESSION[ 'response' ] .= $data;
        }
        return strlen($data);
    };

    curl_setopt($ch , CURLOPT_SSL_VERIFYPEER , false);
    curl_setopt($ch , CURLOPT_SSL_VERIFYHOST , false);
    curl_setopt($ch , CURLOPT_URL , GPTAPI . '/v1/chat/completions'); // 官方API：https://api.openai.com/v1/chat/completions
    curl_setopt($ch , CURLOPT_RETURNTRANSFER , 1);
    curl_setopt($ch , CURLOPT_HTTPHEADER , $headers);
    curl_setopt($ch , CURLOPT_POST , 1);
    curl_setopt($ch , CURLOPT_POSTFIELDS , $postData);
    curl_setopt($ch , CURLOPT_WRITEFUNCTION , $callback);
    curl_exec($ch);

    $answer = NULL;
    if (substr(trim($_SESSION[ 'response' ]) , -6) == "[DONE]") {
        $_SESSION[ 'response' ] = substr(trim($_SESSION[ 'response' ]) , 0 , -6) . "{";
    }
    $responseArr = explode("}\n\ndata: {" , $_SESSION[ 'response' ]);

    foreach ($responseArr as $msg) {
        $contentArr = json_decode("{" . trim($msg) . "}" , true);
        if (isset($contentArr[ 'choices' ][ 0 ][ 'delta' ][ 'content' ])) {
            $answer .= $contentArr[ 'choices' ][ 0 ][ 'delta' ][ 'content' ];
        }
    }

    $questionArr = json_decode($_SESSION[ 'data' ] , true);
    $fileContent = $_SERVER[ "REMOTE_ADDR" ] . " | " . date("Y-m-d H:i:s") . "\n";
    $fileContent .= "Q:" . end($questionArr[ 'messages' ])[ 'content' ] . "\nA:" . trim($answer) . "\n----------------\n";
    $myFile = fopen("./assets/log/log.txt" , "a") or die("Writing file failed.");
    fwrite($myFile , $fileContent);
    fclose($myFile);
    curl_close($ch);

}