<?php

namespace App\Http\Controllers\DeepSeek;

use App\Facade\Site;
use App\Consts\ErrorConst;
use App\Exceptions\ApiException;
use App\Libs\ApiResponse;
use App\Libs\Utils;
use App\Services\DeepSeek\DeepSeekService;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Validator;

class DeepSeekController extends BaseController
{
    use ApiResponse;
    protected $deepseekService;

    public function __construct(
        DeepSeekService $deepseekService
    ) {
        $this->deepseekService = $deepseekService;
    }

    /**
     * 可选供应商
     *
     * @param Request $request
     * @return mixed
     */
    public function chatWithReasoner(Request $request) {
        // 忽略所有超时限制
        set_time_limit(0);
        ini_set('max_execution_time', '0');

        $data = $request->all();
        $result = $this->deepseekService->chatWithReasoner($data);
        return $this->success($result);
    }

    /**
     * 音色列表
     *
     * @param Request $request
     * @return mixed
     */
    public function timbreList(Request $request) {
        $data = $request->all();
        $result = $this->deepseekService->timbreList($data);
        return $this->success($result);
    }

    // 保存段落音频
    public function saveParagraphAudio(Request $request) {
        $data = $request->all();
        $result = $this->deepseekService->saveParagraphAudio($data);
        return $this->success(['success'=>$result ? 1 : 0]);
    }

    /**
     * 新增合成任务
     *
     * @param Request $request
     * @return mixed
     */
    public function addGenerateTask(Request $request) {
        $data = $request->all();
        $result = $this->deepseekService->addGenerateTask($data);
        return $this->success(['success'=>$result ? 1 : 0]);
    }

    // 获取火山临时token
    public function setStsToken(Request $request) {
        $data = $request->all();
        $result = $this->deepseekService->setStsToken($data);
        return $this->success($result);
    }

    public function sseLink(Request $request) {
        $data = $request->all();
        $bid = getProp($data, 'bid');
        $version_id = getProp($data, 'version_id');
        $cid = getProp($data, 'cid');

        // 禁用输出缓冲
        while (ob_get_level()) ob_end_clean();

        // 设置SSE所需的HTTP头
        header('Content-Type: text/event-stream');
        header('Cache-Control: no-cache');
        header('Connection: keep-alive');
        header('X-Accel-Buffering: no'); // 防止Nginx缓冲

        // 允许跨域请求（根据需求设置）
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Credentials: true');

        // 设置脚本执行时间无限
        set_time_limit(0);

        // 手动刷新输出缓冲区
        ob_implicit_flush(true);
        if(ob_get_level()>0) ob_flush();
        flush();

        // 客户端ID（用于多用户区分）
        $clientId = $_SERVER['REMOTE_ADDR'] . ':' . $_SERVER['REMOTE_PORT'];
        $lastEventId = isset($_SERVER['HTTP_LAST_EVENT_ID']) ? intval($_SERVER['HTTP_LAST_EVENT_ID']) : 0;
        // dd($clientId, $lastEventId);

        // 发送初始欢迎消息
        $this->sendEvent([
            // 'message' => "欢迎使用SSE服务! 你的客户端ID: {$clientId}",
            // 'type' => 'info',
            // 'timestamp' => date('H:i:s')
            'code'  => 0,
            'msg'   => "已连接! 你的客户端ID: {$clientId}",
            'data'  => [],
        ]);

        if (!$bid && !$version_id && !$cid) {
            $this->sendEvent([
                // 'message' => '参数异常',
                // 'type' => 'error',
                // 'timestamp' => date('H:i:s')
                'code'  => -1,
                'msg'   => "参数异常",
                'data'  => [],
            ]);
        }

        // 计数器
        $counter = 0;
        $tmp_url_count = 0;

        // 主循环 - 定期发送数据
        while (true) {
            // 检查客户端是否断开连接
            if (connection_aborted()) {
                exit();
            }
            
            $counter++;
            if ($counter % 10 == 0) {
                // 每10s判断是否有新url生成,如果有则发送消息
                $paragraph_urls = DB::table('mp_chapter_paragraph_audios')->where('bid', $bid)->where('version_id', $version_id)
                ->where('cid', $cid)->where(function($query) {
                    return $query->where('generate_status', '!=', '制作中')->orWhere('error_msg', '!=', '');
                })->select('sequence', 'paragraph_audio_url', 'error_msg')
                ->get()->map(function ($value) {
                    return (array)$value;
                })->toArray();
                if (count($paragraph_urls) != $tmp_url_count) {
                    $this->sendEvent([
                        'code'  => 0,
                        'msg'   => "",
                        'data'  => $paragraph_urls,
                        // 'message' => '数据更新',
                        // 'type' => 'update',
                        // 'timestamp' => date('H:i:s')
                    ]);
                    $tmp_url_count = count($paragraph_urls);
                }
            }
            
            // 等待1秒后发送下一条消息
            sleep(1);
        }
    }

    private function sendEvent($data, $event = null, $id = null) {
        // // 事件ID
        // if ($id !== null) {
        //     echo "id: {$id}\n";
        // }
        
        // 事件类型
        if ($event !== null) {
            echo "event: {$event}\n";
        }
        
        // 数据部分（JSON格式）
        echo "data: " . json_encode($data) . "\n\n";
        
        // 立即发送数据
        if(ob_get_level()>0) ob_flush();
        flush();
    }
}
