<?php

namespace App\Filament\Traits;

use Illuminate\Support\Facades\Log;

trait HandlesMindmapDetails
{
    protected function getNodeDetails(string $nodeId, ?array $masteryData = null): array
    {
        $treePath = public_path('data/tree.json');
        $edgesPath = public_path('data/edges.json');

        if (!file_exists($treePath)) {
            return ['error' => 'Tree data not found'];
        }

        $tree = json_decode(file_get_contents($treePath), true);
        $edges = file_exists($edgesPath) ? json_decode(file_get_contents($edgesPath), true) : [];

        $node = $this->findNodeInTree($tree, $nodeId);
        if (!$node) {
            return ['error' => 'Node not found'];
        }

        $masteryMap = $masteryData ?? $this->getActiveMasteryData();
        $masteryInfo = $masteryMap[$nodeId] ?? null;
        $masteryLevel = $masteryInfo ? ($masteryInfo['mastery_level'] ?? 0) : 0;
        $totalAttempts = $masteryInfo ? ($masteryInfo['total_attempts'] ?? 0) : 0;
        $accuracy = $masteryInfo ? ($masteryInfo['accuracy_rate'] ?? 0) : 0;

        $prerequisites = [];
        $successors = [];

        foreach ($edges as $edge) {
            if (($edge['target'] ?? null) === $nodeId && ($edge['type'] ?? '') === 'prerequisite') {
                $prereqNode = $this->findNodeInTree($tree, $edge['source']);
                if ($prereqNode) {
                    $prerequisites[] = [
                        'id' => $edge['source'],
                        'name' => $prereqNode['name'] ?? $prereqNode['label'] ?? $edge['source'],
                        'mastery' => $masteryMap[$edge['source']]['mastery_level'] ?? 0,
                    ];
                }
            }

            if (($edge['source'] ?? null) === $nodeId && ($edge['type'] ?? '') === 'successor') {
                $succNode = $this->findNodeInTree($tree, $edge['target']);
                if ($succNode) {
                    $successors[] = [
                        'id' => $edge['target'],
                        'name' => $succNode['name'] ?? $succNode['label'] ?? $edge['target'],
                        'mastery' => $masteryMap[$edge['target']]['mastery_level'] ?? 0,
                    ];
                }
            }
        }

        $recommendations = $this->getRecommendations($nodeId);

        return [
            'id' => $nodeId,
            'name' => $node['name'] ?? $node['label'] ?? $nodeId,
            'code' => $node['code'] ?? $nodeId,
            'mastery_level' => $masteryLevel,
            'total_attempts' => $totalAttempts,
            'accuracy_rate' => $accuracy,
            'error_rate' => $totalAttempts > 0 ? (1 - $accuracy) : 0,
            'prerequisites' => $prerequisites,
            'successors' => $successors,
            'recommendations' => $recommendations,
            'skills' => $node['skills'] ?? [],
        ];
    }

    protected function findNodeInTree(array $node, string $targetId): ?array
    {
        $nodeId = $node['code'] ?? $node['id'] ?? $node['label'] ?? null;
        if ($nodeId === $targetId) {
            return $node;
        }

        if (isset($node['children'])) {
            foreach ($node['children'] as $child) {
                $found = $this->findNodeInTree($child, $targetId);
                if ($found) {
                    return $found;
                }
            }
        }

        return null;
    }

    protected function getRecommendations(string $nodeId): array
    {
        try {
            $questionBankService = app(\App\Services\QuestionBankService::class);
            $response = $questionBankService->getQuestionsByKpCode($nodeId, 3);

            if (empty($response['data'])) {
                return $this->getMockRecommendations($nodeId);
            }

            $recommendations = [];
            foreach ($response['data'] as $question) {
                $difficultyMap = [
                    0.3 => '简单',
                    0.6 => '中等',
                    0.9 => '困难',
                ];
                $difficulty = $difficultyMap[$question['difficulty'] ?? 0.6] ?? '中等';

                $typeMap = [
                    'choice' => '选择题',
                    'fill' => '填空题',
                    'answer' => '解答题',
                ];
                $rawType = strtolower((string) ($question['question_type'] ?? 'answer'));
                $normalizedType = match (true) {
                    str_contains($rawType, 'choice') || str_contains($rawType, '选择') => 'choice',
                    str_contains($rawType, 'fill') || str_contains($rawType, 'blank') || str_contains($rawType, '填空') => 'fill',
                    default => 'answer',
                };
                $type = $typeMap[$normalizedType] ?? '解答题';

                $stem = $question['stem'] ?? $question['content'] ?? '练习题';

                $recommendations[] = [
                    'id' => $question['id'] ?? $question['question_code'] ?? uniqid(),
                    'title' => mb_strimwidth($stem, 0, 50, '...'),
                    'difficulty' => $difficulty,
                    'type' => $type,
                ];
            }

            return $recommendations;
        } catch (\Exception $e) {
            Log::error('Failed to fetch recommendations', [
                'node_id' => $nodeId,
                'error' => $e->getMessage(),
            ]);

            return $this->getMockRecommendations($nodeId);
        }
    }

    protected function getMockRecommendations(string $nodeId): array
    {
        return [
            [
                'id' => 1,
                'title' => '基础练习：' . $nodeId,
                'difficulty' => '简单',
                'type' => '选择题',
            ],
            [
                'id' => 2,
                'title' => '进阶练习：' . $nodeId,
                'difficulty' => '中等',
                'type' => '填空题',
            ],
            [
                'id' => 3,
                'title' => '综合应用：' . $nodeId,
                'difficulty' => '困难',
                'type' => '解答题',
            ],
        ];
    }

    protected function getActiveMasteryData(): array
    {
        if (property_exists($this, 'masteryData')) {
            return $this->masteryData ?? [];
        }

        if (property_exists($this, 'mindmapMasteryData')) {
            return $this->mindmapMasteryData ?? [];
        }

        return [];
    }
}
