<?php

namespace App\Services;

use Illuminate\Http\Client\PendingRequest;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class QuestionServiceApi
{
    protected string $mode;

    public function __construct(
        protected string $baseUrl = '',
        protected int $timeout = 10,
        protected int $cacheTtl = 300,
    ) {
        $this->baseUrl = '';
        $this->timeout = (int) config('question_bank.timeout', 10);
        $this->cacheTtl = (int) config('question_bank.cache_ttl', 300);
        $this->mode = 'local';
    }

    /**
     * 获取所有题目（分页）
     */
    public function listQuestions(int $page = 1, int $perPage = 50, array $filters = []): array
    {
        if ($this->useLocal()) {
            return $this->local()->listQuestions($page, $perPage, $filters);
        }

        // 移除缓存，直接请求最新数据
        $query = array_filter([
            'page' => $page,
            'per_page' => $perPage,
            'kp_code' => $filters['kp_code'] ?? null,
            'difficulty' => $filters['difficulty'] ?? null,
            'type' => $filters['type'] ?? null,
            'skill' => $filters['skill'] ?? null,
            'search' => $filters['search'] ?? null,
        ], fn ($value) => filled($value));

        // 使用更短的超时时间避免阻塞
        try {
            $response = Http::timeout(5) // 5秒超时
                ->get($this->baseUrl . '/questions', $query);

            if (!$response->successful()) {
                Log::warning('题目列表API调用失败', [
                    'status' => $response->status(),
                    'url' => $this->baseUrl . '/questions'
                ]);
                return [
                    'data' => [],
                    'meta' => [
                        'page' => $page,
                        'per_page' => $perPage,
                        'total' => 0,
                        'total_pages' => 0,
                    ]
                ];
            }

            $response = $response->json();
        } catch (\Illuminate\Http\Client\ConnectionException $e) {
            Log::error('题目列表API连接超时', [
                'error' => $e->getMessage()
            ]);
            // 返回空数据，避免页面卡死
            return [
                'data' => [],
                'meta' => [
                    'page' => $page,
                    'per_page' => $perPage,
                    'total' => 0,
                    'total_pages' => 0,
                ]
            ];
        }

        // 处理数学公式
        $data = $response['data'] ?? [];
        foreach ($data as &$question) {
            // 使用数学公式处理器处理题目数据
            $question = MathFormulaProcessor::processQuestionData($question);
        }

        return [
            'data' => $data,
            'meta' => $response['meta'] ?? [
                'page' => $page,
                'per_page' => $perPage,
                'total' => is_array($response) ? count($response) : 0,
                'total_pages' => 1,
            ],
        ];
    }

    /**
     * 获取技能点名称映射
     */
    public function getSkillNameMapping(?string $kpCode = null): array
    {
        if ($this->useLocal()) {
            return $this->local()->getSkillNameMapping($kpCode);
        }

        // 如果没有指定知识点，返回空映射
        if (empty($kpCode)) {
            return [];
        }

        try {
            // 从知识服务API获取知识点详情，包括技能点
            $baseUrl = config('knowledge.base_url', 'http://localhost:5011');
            $url = rtrim($baseUrl, '/') . '/graph/node/' . $kpCode;

            $response = Http::timeout(5)
                ->get($url);

            if (!$response->successful()) {
                Log::warning('获取知识点详情失败', [
                    'kp_code' => $kpCode,
                    'status' => $response->status(),
                    'url' => $url
                ]);
                return [];
            }

            $data = $response->json();
            $mapping = [];

            // 从响应中提取技能点信息
            $skills = $data['skills'] ?? [];
            foreach ($skills as $skill) {
                $code = $skill['skill_code'] ?? '';
                $name = $skill['skill_name'] ?? $skill['cn_name'] ?? $code;
                if (!empty($code)) {
                    $mapping[$code] = $name;
                }
            }

            Log::info('成功获取技能点映射', [
                'kp_code' => $kpCode,
                'skill_count' => count($mapping)
            ]);

            return $mapping;
        } catch (\Exception $e) {
            Log::warning('获取技能点名称映射失败', [
                'kp_code' => $kpCode,
                'error' => $e->getMessage()
            ]);
            return [];
        }
    }

    /**
     * 获取题目统计信息
     */
    public function getStatistics(array $filters = []): array
    {
        if ($this->useLocal()) {
            return $this->local()->getStatistics($filters);
        }

        // 移除缓存，直接请求最新数据
        try {
            $query = array_filter([
                'kp_code' => $filters['kp_code'] ?? null,
                'difficulty' => $filters['difficulty'] ?? null,
                'type' => $filters['type'] ?? null,
                'skill' => $filters['skill'] ?? null,
                'search' => $filters['search'] ?? null,
            ], fn ($value) => filled($value));

            $response = Http::timeout(5) // 5秒超时
                ->get($this->baseUrl . '/questions/statistics', $query);

            if (!$response->successful()) {
                Log::warning('统计API调用失败', [
                    'status' => $response->status(),
                    'filters' => $filters
                ]);
                return [
                    'total' => 0,
                    'by_difficulty' => [],
                    'by_type' => [],
                    'by_kp' => [],
                    'by_source' => [],
                ];
            }

            $response = $response->json();
        } catch (\Illuminate\Http\Client\ConnectionException $e) {
            Log::error('统计API连接超时', [
                'error' => $e->getMessage(),
                'filters' => $filters
            ]);
            return [
                'total' => 0,
                'by_difficulty' => [],
                'by_type' => [],
                'by_kp' => [],
                'by_source' => [],
            ];
        }

        return $response ?? [
            'total' => 0,
            'by_difficulty' => [],
            'by_type' => [],
            'by_source' => [],
        ];
    }

    /**
     * 根据知识点获取题型统计
     */
    public function getQuestionTypeStatisticsByKpCode(string $kpCode): array
    {
        if ($this->useLocal()) {
            $response = $this->local()->getQuestionsByKpCode($kpCode, 1000);
            $questions = $response['data'] ?? [];
            $typeStats = [];

            foreach ($questions as $question) {
                $type = $question['type'] ?? 'CALCULATION';
                $typeStats[$type] = ($typeStats[$type] ?? 0) + 1;
            }

            arsort($typeStats);
            return $typeStats;
        }

        try {
            // 获取该知识点下的所有题目
            $response = Http::timeout(5)
                ->get($this->baseUrl . '/questions', ['kp_code' => $kpCode, 'per_page' => 1000]);

            if (!$response->successful()) {
                return [];
            }

            $questions = $response['data'] ?? [];
            $typeStats = [];

            // 直接使用 question_type 字段统计，而不是猜测
            foreach ($questions as $question) {
                $type = $question['type'] ?? 'CALCULATION';
                if (!isset($typeStats[$type])) {
                    $typeStats[$type] = 0;
                }
                $typeStats[$type]++;
            }

            // 按数量排序
            arsort($typeStats);
            return $typeStats;
        } catch (\Exception $e) {
            Log::error('获取题型统计失败', [
                'kp_code' => $kpCode,
                'error' => $e->getMessage()
            ]);
            return [];
        }
    }

    /**
     * 根据 kp_code 获取题目
     */
    public function getQuestionsByKpCode(string $kpCode, int $limit = 100): array
    {
        if ($this->useLocal()) {
            return $this->local()->getQuestionsByKpCode($kpCode, $limit);
        }

        $response = $this->request('GET', '/questions', [
            'kp_code' => $kpCode,
            'limit' => $limit,
        ]);

        // 处理数学公式
        if ($response && isset($response['data']) && is_array($response['data'])) {
            foreach ($response['data'] as &$question) {
                $question = MathFormulaProcessor::processQuestionData($question);
            }
        }

        return $response;
    }

    /**
     * 语义搜索题目
     */
    public function searchQuestions(string $query, int $limit = 20): array
    {
        if ($this->useLocal()) {
            return $this->local()->searchQuestions($query, $limit);
        }

        $cacheKey = sprintf('question-search-%s-%d', md5($query), $limit);

        return Cache::remember(
            $cacheKey,
            now()->addSeconds($this->cacheTtl),
            function () use ($query, $limit): array {
                try {
                    $response = $this->request('POST', '/questions/search', [
                        'query' => $query,
                        'limit' => $limit,
                    ]);

                    // 处理数学公式
                    if ($response && is_array($response)) {
                        $response = MathFormulaProcessor::processArray($response, [
                            'stem', 'content', 'question_text', 'answer', 'explanation'
                        ]);
                    }

                    return $response ?? [];
                } catch (\Exception $e) {
                    \Log::error('Question search failed: ' . $e->getMessage());
                    return [];
                }
            }
        );
    }

    /**
     * 获取单个题目详情
     */
    public function getQuestionById(int $id): ?array
    {
        if ($this->useLocal()) {
            return $this->local()->getQuestionById($id);
        }

        $cacheKey = "question-{$id}";

        return Cache::remember(
            $cacheKey,
            now()->addSeconds($this->cacheTtl),
            function () use ($id): ?array {
                try {
                    $response = $this->request('GET', "/questions/{$id}");

                    // 处理数学公式
                    if ($response && is_array($response)) {
                        $response = MathFormulaProcessor::processQuestionData($response);
                    }

                    return $response ?: null;
                } catch (\Exception $e) {
                    \Log::error("Failed to get question {$id}: " . $e->getMessage());
                    return null;
                }
            }
        );
    }

    /**
     * 获取题目详情（通过 question_id）
     */
    public function getQuestionDetail(string $questionId): array
    {
        if ($this->useLocal()) {
            $question = null;
            if (is_numeric($questionId)) {
                $question = $this->local()->getQuestionById((int) $questionId);
            }
            if (!$question) {
                $question = $this->local()->getQuestionByCode($questionId);
            }

            return ['data' => $question];
        }

        try {
            // 先通过ID获取题目信息（使用批量接口）
            $batchResponse = Http::timeout(5)
                ->get($this->baseUrl . '/questions/batch', [
                    'ids' => $questionId
                ]);

            if (!$batchResponse->successful()) {
                Log::warning('批量获取题目详情失败', [
                    'question_id' => $questionId,
                    'status' => $batchResponse->status()
                ]);
                return ['data' => null];
            }

            $batchData = $batchResponse->json();
            $questions = $batchData['data'] ?? [];

            if (empty($questions)) {
                Log::warning('题目不存在', [
                    'question_id' => $questionId
                ]);
                return ['data' => null];
            }

            $question = $questions[0];

            // 处理数学公式
            $question = MathFormulaProcessor::processQuestionData($question);

            return ['data' => $question];
        } catch (\Exception $e) {
            Log::error('获取题目详情异常', [
                'question_id' => $questionId,
                'error' => $e->getMessage()
            ]);
            return ['data' => null];
        }
    }

    /**
     * 创建题目（通过 AI 生成）
     */
    public function generateQuestions(array $params): array
    {
        if ($this->useLocal()) {
            return $this->local()->generateQuestions($params);
        }

        try {
            $response = $this->request('POST', '/questions/generate', $params);

            return $response ?? [
                'success' => false,
                'message' => '生成失败',
            ];
        } catch (\Exception $e) {
            \Log::error('Question generation failed: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => '生成失败：' . $e->getMessage(),
            ];
        }
    }

    /**
     * 导入题目（JSON 批量导入）
     */
    public function importQuestions(array $questions): array
    {
        if ($this->useLocal()) {
            return $this->local()->importQuestions($questions);
        }

        try {
            $response = $this->request('POST', '/questions/import', [
                'questions' => $questions,
            ]);

            return $response ?? [
                'success' => false,
                'message' => '导入失败',
            ];
        } catch (\Exception $e) {
            \Log::error('Question import failed: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => '导入失败：' . $e->getMessage(),
            ];
        }
    }

    /**
     * 删除题目
     */
    public function deleteQuestion(int $id): bool
    {
        if ($this->useLocal()) {
            return $this->local()->deleteQuestionById($id);
        }

        try {
            $response = $this->request('DELETE', "/questions/{$id}");
            return $response['success'] ?? false;
        } catch (\Exception $e) {
            \Log::error("Failed to delete question {$id}: " . $e->getMessage());
            return false;
        }
    }

    /**
     * 获取知识点选项（从知识图谱服务）
     */
    public function getKnowledgePointOptions(): array
    {
        if ($this->useLocal()) {
            return $this->local()->getKnowledgePointOptions();
        }

        // 使用缓存来避免重复请求
        $cacheKey = 'knowledge-point-options';
        return Cache::remember(
            $cacheKey,
            now()->addHours(1), // 缓存1小时
            function () {
                try {
                    // 使用新的知识图谱API
                    $knowledgeApiBase = config('services.knowledge_api.base_url', 'http://localhost:5011');
                    $response = Http::timeout(30) // 增加超时时间到30秒
                        ->get($knowledgeApiBase . '/graph/export');

                    if ($response->successful()) {
                        $data = $response->json();
                        $nodes = $data['nodes'] ?? [];

                        // 转换为键值对格式
                        $options = [];
                        foreach ($nodes as $node) {
                            $code = $node['kp_code'] ?? null;
                            $name = $node['cn_name'] ?? null;

                            if ($code && $name) {
                                $options[$code] = $name;
                            }
                        }

                        // 按代码排序
                        ksort($options);

                        \Log::info('成功获取知识点选项', ['count' => count($options)]);
                        return $options;
                    }

                    \Log::warning('知识图谱API调用失败', [
                        'status' => $response->status(),
                        'url' => $knowledgeApiBase . '/graph/export'
                    ]);
                } catch (\Exception $e) {
                    \Log::error('Failed to get knowledge points: ' . $e->getMessage());
                }

                // 返回空数组作为fallback
                return [];
            }
        );
    }

    /**
     * 获取提示词模板列表
     */
    public function listPrompts(?string $type = null, ?string $active = null): array
    {
        return app(PromptService::class)->listPrompts($type, $active);
    }

    /**
     * 保存提示词模板
     */
    public function savePrompt(array $data): array
    {
        return app(PromptService::class)->savePrompt($data);
    }

    /**
     * @throws RequestException
     * @return mixed
     */
    protected function request(string $method, string $path, array $params = []): mixed
    {
        $response = $this->http()->send($method, ltrim($path, '/'), [
            'query' => $method === 'GET' ? $params : null,
            'json' => $method !== 'GET' ? $params : null,
        ]);

        return $response->throw()->json();
    }

    protected function http(): PendingRequest
    {
        return Http::baseUrl($this->baseUrl)
            ->acceptJson()
            ->timeout($this->timeout)
            ->retry(2, 200)
            ->withHeaders([
                'User-Agent' => 'Laravel/' . (app()->version()),
                'Accept' => 'application/json',
            ]);
    }

    protected function useLocal(): bool
    {
        return true;
    }

    protected function local(): QuestionLocalService
    {
        return app(QuestionLocalService::class);
    }
}
