<?php

namespace App\Http\Controllers\DeepSeek;

use App\Transformer\DeepSeek\DeepSeekTransformer;
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 resetParagraphAudio(Request $request) {
        $data = $request->all();
        $result = $this->deepseekService->resetParagraphAudio($data);
        return $this->success(['success'=>$result ? 1 : 0]);
    }

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

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

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

    /**
     * 获取段落视频
     */
    public function paragraphAudios(Request $request) {
        $data = $request->all();
        $result = $this->deepseekService->getParagraphAudios($data);
        return $this->success($result);
    }

    /**
     * 新增合成任务
     *
     * @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'  => [],
            ]);
        }

        $redis_key = "select-{$bid}-{$version_id}-{$cid}";
        // 主循环 - 定期发送数据
        while (true) {
            // 检查客户端是否断开连接
            if (connection_aborted()) {
                exit();
            }

            // 判断是否有待更新数据,有则查询
            $ids = Redis::smembers($redis_key);
            if (count($ids) > 0) {
                $count = DB::table('mp_chapter_paragraph_audios')->whereIn('id', $ids)->where(function($query) {
                    return $query->where('generate_status', '!=', '制作中')->orWhere('error_msg', '!=', '');
                })->count('id');

                // 如果有更新数据,则发送消息
                if ($count > 0) {
                    // 查询更新后的信息
                    $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('id', 'sequence', 'generate_status', 'paragraph_audio_url', 'error_msg')
                    ->get()->map(function ($value) {
                        return (array)$value;
                    })->toArray();
                    $rem_ids = [];
                    foreach ($paragraph_urls as $item) {
                        $rem_ids[] = getProp($item, 'id');
                    }
                    
                    // 发送消息
                    $this->sendEvent([
                        'code'  => 0,
                        'msg'   => "",
                        'data'  => $paragraph_urls,
                        // 'message' => '数据更新',
                        // 'type' => 'update',
                        // 'timestamp' => date('H:i:s')
                    ]);

                    // 删除有数据的id
                    Redis::srem($redis_key, $rem_ids);
                }
            }
            
            // 等待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();
    }

    public function emotionGroups(Request $request) {
        $data = $request->all();
        $result = $this->deepseekService->emotionGroups($data);
        return $this->success($result);
    }


    /**
     * 剧本列表
     *
     * @param Request $request
     * @return mixed
     */
    public function scriptList(Request $request) {
        $data = $request->all();
        $result = $this->deepseekService->scriptList($data);
        return $this->success($result, [new DeepSeekTransformer(), 'newBuildScriptList']);
    }

    public function scripts(Request $request) {
        $data = $request->all();
        $result = $this->deepseekService->scripts($data);
        return $this->success($result);
    }

    // 剧本详情
    public function scriptInfo(Request $request) {
        $data = $request->all();

        $result = $this->deepseekService->scriptInfo($data);
        return $this->success($result);

    }

    /**
     * 创建剧本
     *
     * @param Request $request
     * @return mixed
     */
    public function createScript(Request $request) {
        $data = $request->all();
        $result = $this->deepseekService->createScript($data);
        return $this->success(['script_id' => $result]);
    }

    /**
     * 与DeepSeek对话(带文件上传)
     * @param Request $request
     * @return mixed
     * @throws ApiException
     */
    public function chatWithFile(Request $request) {
        // 忽略所有超时限制
        set_time_limit(0);
        ini_set('max_execution_time', '0');

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

    /**
     * 与DeepSeek对话(带文件上传 - 流式输出版本)
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\StreamedResponse
     * @throws ApiException
     */
    public function chatWithFileStream(Request $request) {
        // 忽略所有超时限制
        set_time_limit(0);
        ini_set('max_execution_time', '0');

        $data = $request->all();

        return response()->stream(function () use ($data) {
            // 禁用所有输出缓冲
            if (ob_get_level()) {
                ob_end_clean();
            }
            
            // 设置输出缓冲为关闭
            ini_set('output_buffering', 'off');
            ini_set('zlib.output_compression', 'off');
            
            // 立即刷新
            if (function_exists('apache_setenv')) {
                apache_setenv('no-gzip', '1');
            }

            try {
                $generator = $this->deepseekService->chatWithFileStream($data);
                
                foreach ($generator as $chunk) {
                    // 发送 SSE 格式的数据
                    $jsonData = json_encode($chunk, JSON_UNESCAPED_UNICODE);
                    echo "data: {$jsonData}\n\n";
                    
                    // 强制刷新输出缓冲区
                    if (ob_get_level() > 0) {
                        ob_flush();
                    }
                    flush();
                    
                    // 检查客户端是否断开连接
                    if (connection_aborted()) {
                        break;
                    }
                }
                
                // 发送结束标记
                echo "data: [DONE]\n\n";
                if (ob_get_level() > 0) {
                    ob_flush();
                }
                flush();
                
            } catch (\Exception $e) {
                // 发送错误信息
                $error = [
                    'type' => 'error',
                    'msg'   => $e->getMessage(),
                    'code' => $e->getCode()
                ];
                $jsonError = json_encode($error, JSON_UNESCAPED_UNICODE);
                echo "data: {$jsonError}\n\n";
                if (ob_get_level() > 0) {
                    ob_flush();
                }
                flush();
            }
        }, 200, [
            'Content-Type' => 'text/event-stream',
            'Cache-Control' => 'no-cache',
            'Connection' => 'keep-alive',
            'X-Accel-Buffering' => 'no', // 防止 Nginx 缓冲
            'Access-Control-Allow-Origin' => '*',
            'Access-Control-Allow-Credentials' => 'true'
        ]);
    }

    // 保存剧本
    public function saveScript(Request $request) {
        $data = $request->all();
        $result = $this->deepseekService->saveScript($data);
        return $this->success(['success'=>$result ? 1 : 0]);
    }

    // 导出剧本
    public function exportScript(Request $request) {
        $data = $request->all();
        
        // 验证必要参数
        if (empty($data['script_id'])) {
            return $this->error('20003:缺少剧本ID参数');
        }
        
        // 直接调用导出服务，该方法会直接输出文件并退出
        $this->deepseekService->exportScript($data);
    }

    // 新建对话
    public function addChat(Request $request) {
        // 忽略所有超时限制
        set_time_limit(0);
        ini_set('max_execution_time', '0');


        $data = $request->all();
        return response()->stream(function () use ($data) {
            // 禁用所有输出缓冲
            if (ob_get_level()) {
                ob_end_clean();
            }
            
            // 设置输出缓冲为关闭
            ini_set('output_buffering', 'off');
            ini_set('zlib.output_compression', 'off');
            
            // 立即刷新
            if (function_exists('apache_setenv')) {
                apache_setenv('no-gzip', '1');
            }

            try {
                $generator = $this->deepseekService->addChat($data);
                
                foreach ($generator as $chunk) {
                    // 发送 SSE 格式的数据
                    $jsonData = json_encode($chunk, JSON_UNESCAPED_UNICODE);
                    echo "data: {$jsonData}\n\n";
                    
                    // 强制刷新输出缓冲区
                    if (ob_get_level() > 0) {
                        ob_flush();
                    }
                    flush();
                    
                    // 检查客户端是否断开连接
                    if (connection_aborted()) {
                        break;
                    }
                }
                
                // 发送结束标记
                echo "data: [DONE]\n\n";
                if (ob_get_level() > 0) {
                    ob_flush();
                }
                flush();
                
            } catch (\Exception $e) {
                // 发送错误信息
                $error = [
                    'type' => 'error',
                    'msg' => $e->getMessage(),
                    'code' => $e->getCode()
                ];
                $jsonError = json_encode($error, JSON_UNESCAPED_UNICODE);
                echo "data: {$jsonError}\n\n";
                if (ob_get_level() > 0) {
                    ob_flush();
                }
                flush();
            }
        }, 200, [
            'Content-Type' => 'text/event-stream',
            'Cache-Control' => 'no-cache',
            'Connection' => 'keep-alive',
            'X-Accel-Buffering' => 'no', // 防止 Nginx 缓冲
            'Access-Control-Allow-Origin' => '*',
            'Access-Control-Allow-Credentials' => 'true'
        ]);
    }

    // 调整大纲
    public function reGenerateAnime(Request $request) {
        // 忽略所有超时限制
        set_time_limit(0);
        ini_set('max_execution_time', '0');


        $data = $request->all();
        return response()->stream(function () use ($data) {
            // 禁用所有输出缓冲
            if (ob_get_level()) {
                ob_end_clean();
            }
            
            // 设置输出缓冲为关闭
            ini_set('output_buffering', 'off');
            ini_set('zlib.output_compression', 'off');
            
            // 立即刷新
            if (function_exists('apache_setenv')) {
                apache_setenv('no-gzip', '1');
            }

            try {
                $generator = $this->deepseekService->reGenerateAnime($data);
                
                foreach ($generator as $chunk) {
                    // 发送 SSE 格式的数据
                    $jsonData = json_encode($chunk, JSON_UNESCAPED_UNICODE);
                    echo "data: {$jsonData}\n\n";
                    
                    // 强制刷新输出缓冲区
                    if (ob_get_level() > 0) {
                        ob_flush();
                    }
                    flush();
                    
                    // 检查客户端是否断开连接
                    if (connection_aborted()) {
                        break;
                    }
                }
                
                // 发送结束标记
                echo "data: [DONE]\n\n";
                if (ob_get_level() > 0) {
                    ob_flush();
                }
                flush();
                
            } catch (\Exception $e) {
                // 发送错误信息
                $error = [
                    'type' => 'error',
                    'msg' => $e->getMessage(),
                    'code' => $e->getCode()
                ];
                $jsonError = json_encode($error, JSON_UNESCAPED_UNICODE);
                echo "data: {$jsonError}\n\n";
                if (ob_get_level() > 0) {
                    ob_flush();
                }
                flush();
            }
        }, 200, [
            'Content-Type' => 'text/event-stream',
            'Cache-Control' => 'no-cache',
            'Connection' => 'keep-alive',
            'X-Accel-Buffering' => 'no', // 防止 Nginx 缓冲
            'Access-Control-Allow-Origin' => '*',
            'Access-Control-Allow-Credentials' => 'true'
        ]);
    }

    public function chat(Request $request) {
        // 忽略所有超时限制
        set_time_limit(0);
        ini_set('max_execution_time', '0');

        $data = $request->all();
        return response()->stream(function () use ($data) {
            // 禁用所有输出缓冲
            if (ob_get_level()) {
                ob_end_clean();
            }
            
            // 设置输出缓冲为关闭
            ini_set('output_buffering', 'off');
            ini_set('zlib.output_compression', 'off');
            
            // 立即刷新
            if (function_exists('apache_setenv')) {
                apache_setenv('no-gzip', '1');
            }

            try {
                $generator = $this->deepseekService->chat($data);
                
                foreach ($generator as $chunk) {
                    // 发送 SSE 格式的数据
                    $jsonData = json_encode($chunk, JSON_UNESCAPED_UNICODE);
                    echo "data: {$jsonData}\n\n";
                    
                    // 强制刷新输出缓冲区
                    if (ob_get_level() > 0) {
                        ob_flush();
                    }
                    flush();
                    
                    // 检查客户端是否断开连接
                    if (connection_aborted()) {
                        break;
                    }
                }
                
                // 发送结束标记
                echo "data: [DONE]\n\n";
                if (ob_get_level() > 0) {
                    ob_flush();
                }
                flush();
                
            } catch (\Exception $e) {
                // 发送错误信息
                $error = [
                    'type' => 'error',
                    'msg' => $e->getMessage(),
                    'code' => $e->getCode()
                ];
                $jsonError = json_encode($error, JSON_UNESCAPED_UNICODE);
                echo "data: {$jsonError}\n\n";
                if (ob_get_level() > 0) {
                    ob_flush();
                }
                flush();
            }
        }, 200, [
            'Content-Type' => 'text/event-stream',
            'Cache-Control' => 'no-cache',
            'Connection' => 'keep-alive',
            'X-Accel-Buffering' => 'no', // 防止 Nginx 缓冲
            'Access-Control-Allow-Origin' => '*',
            'Access-Control-Allow-Credentials' => 'true'
        ]);
    }

    // 对话改图
    public function chatChangeImg(Request $request) {
        $data = $request->all();

        $result = $this->deepseekService->chatChangeImg($data);
        return $this->success($result);
    }

    /**
     * 通用文生文接口 - 流式输出
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\StreamedResponse
     */
    public function generateText(Request $request) {
        // 忽略所有超时限制
        set_time_limit(0);
        ini_set('max_execution_time', '0');

        $data = $request->all();
        
        // 处理上传的图片文件
        if ($request->hasFile('images')) {
            $data['images'] = $request->file('images');
        } else if ($request->hasFile('image')) {
            // 支持单张图片
            $data['images'] = [$request->file('image')];
        }

        return response()->stream(function () use ($data) {
            // 禁用所有输出缓冲
            if (ob_get_level()) {
                ob_end_clean();
            }
            
            // 设置输出缓冲为关闭
            ini_set('output_buffering', 'off');
            ini_set('zlib.output_compression', 'off');
            
            // 立即刷新
            if (function_exists('apache_setenv')) {
                apache_setenv('no-gzip', '1');
            }

            try {
                $generator = $this->deepseekService->generateText($data);
                
                foreach ($generator as $chunk) {
                    // 发送 SSE 格式的数据
                    $jsonData = json_encode($chunk, JSON_UNESCAPED_UNICODE);
                    echo "data: {$jsonData}\n\n";
                    
                    // 强制刷新输出缓冲区
                    if (ob_get_level() > 0) {
                        ob_flush();
                    }
                    flush();
                    
                    // 检查客户端是否断开连接
                    if (connection_aborted()) {
                        break;
                    }
                }
                
                // 发送结束标记
                echo "data: [DONE]\n\n";
                if (ob_get_level() > 0) {
                    ob_flush();
                }
                flush();
                
            } catch (\Exception $e) {
                // 发送错误信息
                $error = [
                    'type' => 'error',
                    'msg' => $e->getMessage(),
                    'code' => $e->getCode()
                ];
                $jsonError = json_encode($error, JSON_UNESCAPED_UNICODE);
                echo "data: {$jsonError}\n\n";
                if (ob_get_level() > 0) {
                    ob_flush();
                }
                flush();
            }
        }, 200, [
            'Content-Type' => 'text/event-stream',
            'Cache-Control' => 'no-cache',
            'Connection' => 'keep-alive',
            'X-Accel-Buffering' => 'no', // 防止 Nginx 缓冲
            'Access-Control-Allow-Origin' => '*',
            'Access-Control-Allow-Credentials' => 'true'
        ]);
    }
}
