<?php

namespace App\Services;

use App\Models\Textbook;
use App\Models\TextbookCatalog;
use App\Models\TextbookSeries;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class TextbookApiService
{
    protected string $baseUrl;
    protected bool $useDatabase;

    public function __construct()
    {
        $baseUrl = (string) config('services.textbook_api.base_url', '');
        $this->baseUrl = rtrim($baseUrl, '/');
        $this->useDatabase = true;
    }

    /**
     * 通用HTTP请求方法 - 减少重复代码，无缓存
     */
    protected function request(string $method, string $endpoint, array $data = []): array
    {
        try {
            $httpMethod = strtolower($method);
            $response = match($httpMethod) {
                'get' => Http::timeout(30)->get($this->baseUrl . $endpoint, $data),
                'post' => Http::timeout(300)->post($this->baseUrl . $endpoint, $data),
                'put' => Http::timeout(30)->put($this->baseUrl . $endpoint, $data),
                'delete' => Http::timeout(30)->delete($this->baseUrl . $endpoint, $data),
                default => throw new \InvalidArgumentException("Unsupported HTTP method: {$method}")
            };

            // 处理文件上传
            if (isset($data['file']) && $data['file'] instanceof \Illuminate\Http\UploadedFile) {
                $response = Http::timeout(300)
                    ->attach('file', file_get_contents($data['file']->getPathname()), $data['file']->getClientOriginalName())
                    ->{$httpMethod}($this->baseUrl . $endpoint, $data);
            }

            if ($response->successful()) {
                return $response->json();
            }

            // 记录错误并抛出异常
            $error = $this->handleErrorResponse($response, $endpoint);
            throw new \Exception($error);

        } catch (\Exception $e) {
            Log::error("API request failed: {$method} {$endpoint}", [
                'error' => $e->getMessage(),
                'data' => $data
            ]);
            throw $e;
        }
    }

    /**
     * 处理错误响应
     */
    private function handleErrorResponse($response, string $endpoint): string
    {
        $status = $response->status();
        $body = $response->body();

        // 常见错误类型的友好提示
        return match($status) {
            404 => "未找到资源: {$endpoint}",
            422 => "数据验证失败: {$body}",
            500 => "服务器内部错误: {$body}",
            default => "HTTP {$status}: {$body}"
        };
    }

    /**
     * 获取教材系列列表
     */
    public function getTextbookSeries(array $params = []): array
    {
        if ($this->useDatabase) {
            $query = TextbookSeries::query()->orderBy('sort_order');

            // 默认只返回启用的系列（is_active = true）
            // 除非显式传入 include_inactive=true
            if (!isset($params['include_inactive']) || $params['include_inactive'] !== 'true') {
                $query->where('is_active', true);
            }

            // 支持按学段筛选
            if (isset($params['stage'])) {
                $query->where('stages', 'like', '%' . $params['stage'] . '%');
            }

            $series = $query->get();
            return ['data' => $series->toArray(), 'meta' => ['total' => $series->count()]];
        }

        try {
            return $this->request('GET', '/textbooks/series', $params);
        } catch (\Exception $e) {
            // 失败时返回空数据而不是抛出异常，保持向后兼容
            Log::warning('Failed to fetch textbook series, returning empty result', ['error' => $e->getMessage()]);
            return ['data' => [], 'meta' => []];
        }
    }

    /**
     * 根据ID获取单个教材系列
     */
    public function getTextbookSeriesById(int $seriesId): ?array
    {
        if ($this->useDatabase) {
            return TextbookSeries::query()->find($seriesId)?->toArray();
        }

        try {
            $result = $this->request('GET', "/textbooks/series/{$seriesId}");
            return $result['data'] ?? null;
        } catch (\Exception $e) {
            Log::warning('Series not found or error occurred', [
                'series_id' => $seriesId,
                'error' => $e->getMessage()
            ]);
            return null;
        }
    }

    /**
     * 创建教材系列
     */
    public function createTextbookSeries(array $data): array
    {
        if ($this->useDatabase) {
            $series = TextbookSeries::query()->create($data);
            return ['data' => $series->toArray()];
        }

        try {
            return $this->request('POST', '/textbooks/series', $data);
        } catch (\Exception $e) {
            // 检查是否是series不存在的错误（虽然这里不太可能，但保持向后兼容）
            if (strpos($e->getMessage(), 'Series not found') !== false) {
                $seriesId = $data['id'] ?? 'unknown';
                throw new \Exception("系列ID {$seriesId} 不存在");
            }
            throw $e;
        }
    }

    /**
     * 更新教材系列
     */
    public function updateTextbookSeries(int $seriesId, array $data): array
    {
        if ($this->useDatabase) {
            $series = TextbookSeries::query()->findOrFail($seriesId);
            $series->fill($data);
            $series->save();
            return ['data' => $series->toArray()];
        }

        try {
            return $this->request('PUT', "/textbooks/series/{$seriesId}", $data);
        } catch (\Exception $e) {
            Log::error('Error updating textbook series', ['error' => $e->getMessage()]);
            throw $e;
        }
    }

    /**
     * 删除教材系列
     */
    public function deleteTextbookSeries(int $seriesId): bool
    {
        if ($this->useDatabase) {
            $series = TextbookSeries::query()->find($seriesId);
            return $series ? (bool) $series->delete() : false;
        }

        try {
            $this->request('DELETE', "/textbooks/series/{$seriesId}");
            return true;
        } catch (\Exception $e) {
            Log::error('Error deleting textbook series', ['error' => $e->getMessage()]);
            return false;
        }
    }

    /**
     * 删除教材
     */
    public function deleteTextbook(int $textbookId): bool
    {
        if ($this->useDatabase) {
            $textbook = Textbook::query()->find($textbookId);
            return $textbook ? (bool) $textbook->delete() : false;
        }

        try {
            $this->request('DELETE', "/textbooks/by-id/{$textbookId}");
            return true;
        } catch (\Exception $e) {
            Log::error('Error deleting textbook', ['error' => $e->getMessage(), 'textbook_id' => $textbookId]);
            return false;
        }
    }

    /**
     * 获取教材列表
     */
    public function getTextbooks(array $params = []): array
    {
        if ($this->useDatabase) {
            $query = Textbook::query()
                ->select('textbooks.*')
                ->join('textbook_series', 'textbooks.series_id', '=', 'textbook_series.id');

            // 默认只返回已发布且系列启用的教材
            // 除非显式传入 include_unpublished=true 或 include_inactive_series=true
            if (!isset($params['include_unpublished']) || $params['include_unpublished'] !== 'true') {
                $query->where('textbooks.status', 'published');
            }

            if (!isset($params['include_inactive_series']) || $params['include_inactive_series'] !== 'true') {
                $query->where('textbook_series.is_active', true);
            }

            // 支持按系列ID筛选
            if (isset($params['series_id'])) {
                $query->where('textbooks.series_id', $params['series_id']);
            }

            // 支持按学段筛选
            if (isset($params['stage'])) {
                $query->where('textbooks.stage', $params['stage']);
            }

            // 支持按年级筛选
            if (isset($params['grade'])) {
                $query->where('textbooks.grade', $params['grade']);
            }

            // 支持按学期筛选
            if (array_key_exists('semester', $params) && $params['semester'] !== null) {
                $query->where('textbooks.semester', $params['semester']);
            }

            // 显式按状态筛选（会覆盖默认的已发布筛选）
            if (isset($params['status'])) {
                $query->where('textbooks.status', $params['status']);
            }

            $textbooks = $query->orderBy('textbooks.id')->get();
            return ['data' => $textbooks->toArray(), 'meta' => ['total' => $textbooks->count()]];
        }

        try {
            return $this->request('GET', '/textbooks', $params);
        } catch (\Exception $e) {
            Log::warning('Failed to fetch textbooks, returning empty result', ['error' => $e->getMessage()]);
            return ['data' => [], 'meta' => []];
        }
    }

    /**
     * 获取单个教材
     */
    public function getTextbook(int $textbookId): ?array
    {
        if ($this->useDatabase) {
            return Textbook::query()->find($textbookId)?->toArray();
        }

        try {
            $result = $this->request('GET', "/textbooks/by-id/{$textbookId}");
            return $result['data'] ?? null;
        } catch (\Exception $e) {
            Log::warning('Textbook not found or error occurred', [
                'textbook_id' => $textbookId,
                'error' => $e->getMessage()
            ]);
            return null;
        }
    }

    /**
     * 创建教材
     */
    public function createTextbook(array $data): array
    {
        if ($this->useDatabase) {
            $textbook = Textbook::query()->create($data);
            return ['data' => $textbook->toArray()];
        }

        try {
            return $this->request('POST', '/textbooks', $data);
        } catch (\Exception $e) {
            // 检查是否是series不存在的错误
            if (strpos($e->getMessage(), 'Series not found') !== false) {
                $seriesId = $data['series_id'] ?? 'unknown';
                throw new \Exception("系列ID {$seriesId} 不存在，请先创建教材系列或检查ID是否正确");
            }
            throw $e;
        }
    }

    /**
     * 更新教材
     */
    public function updateTextbook(int $textbookId, array $data): array
    {
        if ($this->useDatabase) {
            $textbook = Textbook::query()->findOrFail($textbookId);
            $textbook->fill($data);
            $textbook->save();
            return ['data' => $textbook->toArray()];
        }

        try {
            return $this->request('PUT', "/textbooks/by-id/{$textbookId}", $data);
        } catch (\Exception $e) {
            Log::error('Error updating textbook', ['error' => $e->getMessage()]);
            throw $e;
        }
    }

    /**
     * 创建或更新教材（upsert模式）
     * 根据系列、学段、年级、学期、官方书名判断是否已存在
     */
    public function createOrUpdateTextbook(array $data): array
    {
        if ($this->useDatabase) {
            if (isset($data['id'])) {
                return $this->updateTextbook((int) $data['id'], $data);
            }
            $textbook = Textbook::query()->create($data);
            return ['data' => $textbook->toArray()];
        }

        try {
            return $this->request('POST', '/textbooks/upsert', $data);
        } catch (\Exception $e) {
            // 检查是否是series不存在的错误
            if (strpos($e->getMessage(), 'Series not found') !== false) {
                $seriesId = $data['series_id'] ?? 'unknown';
                throw new \Exception("系列ID {$seriesId} 不存在，请先创建教材系列或检查ID是否正确");
            }
            throw $e;
        }
    }

    /**
     * 删除教材目录节点
     */
    public function deleteTextbookCatalog(int $catalogId): bool
    {
        if ($this->useDatabase) {
            $catalog = TextbookCatalog::query()->find($catalogId);
            return $catalog ? (bool) $catalog->delete() : false;
        }

        try {
            $this->request('DELETE', "/textbooks/catalog/{$catalogId}");
            return true;
        } catch (\Exception $e) {
            Log::error('Error deleting textbook catalog', ['error' => $e->getMessage(), 'catalog_id' => $catalogId]);
            return false;
        }
    }

    /**
     * 获取教材目录树
     */
    public function getTextbookCatalog(int $textbookId, string $format = 'tree'): array
    {
        if ($this->useDatabase) {
            // 先验证教材是否存在且已发布，且其系列处于启用状态
            $textbook = Textbook::query()
                ->select('textbooks.*')
                ->join('textbook_series', 'textbooks.series_id', '=', 'textbook_series.id')
                ->where('textbooks.id', $textbookId)
                ->where('textbooks.status', 'published')
                ->where('textbook_series.is_active', true)
                ->first();

            if (!$textbook) {
                Log::warning('Textbook not found or not published or series inactive', [
                    'textbook_id' => $textbookId
                ]);
                return [];
            }

            $nodes = TextbookCatalog::query()
                ->where('textbook_id', $textbookId)
                ->orderBy('sort_order')
                ->get();

            if ($format === 'tree') {
                return $this->buildCatalogTree($nodes->toArray());
            }

            return $nodes->toArray();
        }

        try {
            $result = $this->request('GET', "/textbooks/by-id/{$textbookId}/catalog", ['format' => $format]);
            return $result['data'] ?? [];
        } catch (\Exception $e) {
            Log::warning('Failed to fetch textbook catalog, returning empty result', ['error' => $e->getMessage()]);
            return [];
        }
    }

    /**
     * 预览教材命名
     */
    public function previewTextbookNaming(array $textbookData, array $seriesData): array
    {
        if ($this->useDatabase) {
            $title = $textbookData['official_title'] ?? $textbookData['display_title'] ?? '';
            return ['data' => ['official_title' => $title]];
        }

        try {
            $result = $this->request('POST', '/textbooks/naming-preview', [
                'textbook' => $textbookData,
                'series' => $seriesData
            ]);
            return $result['data'] ?? [];
        } catch (\Exception $e) {
            Log::warning('Failed to preview textbook naming, returning empty result', ['error' => $e->getMessage()]);
            return [];
        }
    }

    /**
     * 导入教材元信息
     */
    public function importTextbookMetadata($file, string $commitMode = 'overwrite'): array
    {
        if ($this->useDatabase) {
            return [
                'data' => [],
                'meta' => [
                    'status' => 'pending',
                    'message' => 'Local import is pending implementation.',
                ],
            ];
        }

        try {
            return $this->request('POST', '/textbooks/import/meta', [
                'file' => $file,
                'commit_mode' => $commitMode
            ]);
        } catch (\Exception $e) {
            Log::error('Error importing textbook metadata', ['error' => $e->getMessage()]);
            throw $e;
        }
    }

    /**
     * 导入教材目录
     */
    public function importTextbookCatalog(int $textbookId, array $catalogData, string $commitMode = 'overwrite', ?int $seriesId = null): array
    {
        if ($this->useDatabase) {
            if (empty($catalogData)) {
                return [
                    'success' => false,
                    'message' => '目录数据为空',
                    'success_count' => 0,
                    'error_count' => 0,
                    'errors' => [],
                ];
            }

            $successCount = 0;
            $errorCount = 0;
            $errors = [];
            $parentStack = [];

            DB::transaction(function () use ($textbookId, $catalogData, $commitMode, $seriesId, &$successCount, &$errorCount, &$errors, &$parentStack) {
                if ($commitMode === 'overwrite') {
                    $textbook = Textbook::query()->find($textbookId);
                    if ($textbook && $seriesId !== null && (int) $textbook->series_id !== (int) $seriesId) {
                        throw new \RuntimeException('教材系列不匹配，已阻止覆盖更新');
                    }

                    TextbookCatalog::query()->where('textbook_id', $textbookId)->delete();
                }

                foreach ($catalogData as $index => $node) {
                    try {
                        $depth = (int) ($node['depth'] ?? 1);
                        $parentId = $node['parent_id'] ?? null;
                        $title = trim((string) ($node['title'] ?? ''));
                        if ($title === '') {
                            throw new \Exception('目录标题不能为空');
                        }

                        $tags = $node['tags'] ?? null;
                        if (is_array($tags)) {
                            $tags = empty($tags) ? null : json_encode($tags, JSON_UNESCAPED_UNICODE);
                        } elseif (is_string($tags) && $tags !== '') {
                            json_decode($tags, true);
                            if (json_last_error() !== JSON_ERROR_NONE) {
                                $tags = null;
                            }
                        }

                        $meta = $node['meta'] ?? null;
                        if (is_array($meta)) {
                            $meta = empty($meta) ? null : json_encode($meta, JSON_UNESCAPED_UNICODE);
                        } elseif (is_string($meta) && $meta !== '') {
                            json_decode($meta, true);
                            if (json_last_error() !== JSON_ERROR_NONE) {
                                $meta = null;
                            }
                        }

                        if (!$parentId && $depth > 1) {
                            $parentId = $parentStack[$depth - 1] ?? null;
                        }

                        $payload = [
                            'textbook_id' => $textbookId,
                            'parent_id' => $parentId,
                            'node_type' => $node['node_type'] ?? 'chapter',
                            'title' => $title,
                            'display_no' => $node['display_no'] ?? null,
                            'depth' => $depth,
                            'sort_order' => (int) ($node['sort_order'] ?? 0),
                            'path_key' => $node['path_key'] ?? null,
                            'is_required' => (bool) ($node['is_required'] ?? false),
                            'is_elective' => (bool) ($node['is_elective'] ?? false),
                            'tags' => $tags,
                            'page_start' => $node['page_start'] ?? null,
                            'page_end' => $node['page_end'] ?? null,
                            'meta' => $meta,
                        ];
                        $record = TextbookCatalog::create($payload);

                        $parentStack[$depth] = $record->id;
                        foreach (array_keys($parentStack) as $stackDepth) {
                            if ($stackDepth > $depth) {
                                unset($parentStack[$stackDepth]);
                            }
                        }

                        $successCount++;
                    } catch (\Throwable $e) {
                        $errorCount++;
                        $errors[] = '第' . ($index + 2) . '行: ' . $e->getMessage();
                    }
                }
            });

            return [
                'success' => $errorCount === 0,
                'success_count' => $successCount,
                'error_count' => $errorCount,
                'errors' => $errors,
                'message' => $errorCount === 0 ? '导入完成' : '部分导入失败',
            ];
        }

        try {
            // 将数组转换为JSON字符串
            $jsonData = json_encode($catalogData, JSON_UNESCAPED_UNICODE);

            // 直接发送 JSON 数据
            return $this->request('POST', '/textbooks/import/catalog', [
                'textbook_id' => $textbookId,
                'data' => $jsonData,
                'commit_mode' => $commitMode
            ]);
        } catch (\Exception $e) {
            Log::error('Error importing textbook catalog', ['error' => $e->getMessage()]);
            throw $e;
        }
    }

    /**
     * 提交导入任务
     */
    public function commitImportJob(int $jobId): array
    {
        if ($this->useDatabase) {
            return [
                'data' => [],
                'meta' => [
                    'status' => 'noop',
                    'message' => 'Local import jobs are not tracked yet.',
                ],
            ];
        }

        try {
            return $this->request('POST', "/api/textbooks/import/{$jobId}/commit");
        } catch (\Exception $e) {
            Log::error('Error committing import job', ['error' => $e->getMessage()]);
            throw $e;
        }
    }

    /**
     * 获取导入任务列表
     */
    public function getImportJobs(array $params = []): array
    {
        if ($this->useDatabase) {
            return ['data' => [], 'meta' => ['total' => 0]];
        }

        try {
            return $this->request('GET', '/textbooks/import/jobs', $params);
        } catch (\Exception $e) {
            Log::warning('Failed to fetch import jobs, returning empty result', ['error' => $e->getMessage()]);
            return ['data' => [], 'meta' => []];
        }
    }

    /**
     * 获取单个导入任务
     */
    public function getImportJob(int $jobId): ?array
    {
        if ($this->useDatabase) {
            return null;
        }

        try {
            $result = $this->request('GET', "/api/textbooks/import/jobs/{$jobId}");
            return $result['data'] ?? null;
        } catch (\Exception $e) {
            Log::warning('Import job not found or error occurred', ['error' => $e->getMessage()]);
            return null;
        }
    }

    /**
     * 完全同步教材系列到题库服务（清空+重新插入）
     */
    public function syncTextbookSeriesToQuestionBank(): array
    {
        if ($this->useDatabase) {
            return ['data' => [], 'meta' => ['status' => 'noop']];
        }

        try {
            // 获取MySQL中的所有系列
            $mysqlSeries = DB::connection('mysql')
                ->table('textbook_series')
                ->orderBy('id')
                ->get();

            if ($mysqlSeries->isEmpty()) {
                return [
                    'success' => false,
                    'message' => 'MySQL中没有找到教材系列数据'
                ];
            }

            // 准备数据
            $seriesData = [];
            foreach ($mysqlSeries as $series) {
                $seriesData[] = [
                    'id' => $series->id,
                    'name' => $series->name,
                    'slug' => $series->slug,
                    'publisher' => $series->publisher,
                    'region' => $series->region,
                    'stages' => json_decode($series->stages, true),
                    'is_active' => (bool)$series->is_active,
                    'sort_order' => (int)$series->sort_order,
                    'meta' => json_decode($series->meta, true),
                ];
            }

            // 调用API进行完全同步
            $result = $this->request('POST', '/textbooks/series/sync-all', [
                'series' => $seriesData
            ]);

            return [
                'success' => true,
                'synced_count' => count($seriesData),
                'data' => $result
            ];
        } catch (\Exception $e) {
            Log::error('Error syncing textbook series', ['error' => $e->getMessage()]);
            return [
                'success' => false,
                'message' => '同步失败: ' . $e->getMessage()
            ];
        }
    }

    /**
     * 根据教材系列、年级和学期获取教材及其目录结构
     *
     * @param int $seriesId 教材系列ID
     * @param int $grade 年级（1-12）
     * @param int $semesterCode 学期代码（1=上册，2=下册）
     * @param string $catalogFormat 目录格式（tree 或 flat）
     * @return array 包含教材信息和目录结构的数组
     */
    public function getTextbookByFilter(int $seriesId, int $grade, int $semesterCode, string $catalogFormat = 'tree'): array
    {
        if ($this->useDatabase) {
            try {
                // 先查找符合条件且已发布的教材
                $query = Textbook::query()
                    ->select('textbooks.*')
                    ->join('textbook_series', 'textbooks.series_id', '=', 'textbook_series.id')
                    ->where('textbooks.series_id', $seriesId)
                    ->where('textbooks.grade', $grade)
                    ->where('textbooks.semester', $semesterCode)
                    ->where('textbooks.status', 'published')
                    ->where('textbook_series.is_active', true);

                $textbook = $query->first();

                if (!$textbook) {
                    return [
                        'success' => false,
                        'message' => '未找到符合条件的教材',
                        'data' => null,
                        'meta' => [
                            'series_id' => $seriesId,
                            'grade' => $grade,
                            'semester_code' => $semesterCode,
                            'semester_label' => $this->getSemesterLabel($semesterCode),
                        ]
                    ];
                }

                // 获取教材目录
                $catalog = $this->getTextbookCatalog($textbook->id, $catalogFormat);

                // 格式化教材信息
                $textbookData = [
                    'id' => $textbook->id,
                    'name' => $textbook->official_title ?? '',
                    'display_name' => $textbook->official_title ?? '',
                    'cover' => $this->formatCoverUrl($textbook->cover_path ?? ''),
                    'series_id' => $textbook->series_id,
                    'series_name' => $textbook->series->name ?? '',
                    'publisher' => $textbook->series->publisher ?? '',
                    'stage' => $this->getStageLabel($textbook->stage ?? ''),
                    'stage_code' => $textbook->stage ?? '',
                    'grade' => $textbook->grade,
                    'grade_label' => $this->getGradeLabel($textbook->grade, $textbook->stage ?? ''),
                    'semester' => $this->getSemesterLabel($textbook->semester),
                    'semester_code' => $textbook->semester,
                    'module_type' => $textbook->module_type ?? null,
                    'volume_no' => $textbook->volume_no ?? null,
                    'isbn' => $textbook->isbn ?? '',
                    'approval_year' => $textbook->approval_year ?? null,
                    'curriculum_standard_year' => $textbook->curriculum_standard_year ?? null,
                    'status' => $textbook->status ?? 'draft',
                    'sort_order' => $textbook->sort_order ?? 0,
                ];

                return [
                    'success' => true,
                    'data' => [
                        'textbook' => $textbookData,
                        'catalog' => $catalog,
                    ],
                    'meta' => [
                        'series_id' => $seriesId,
                        'grade' => $grade,
                        'grade_label' => $textbookData['grade_label'],
                        'semester_code' => $semesterCode,
                        'semester_label' => $textbookData['semester'],
                        'catalog_format' => $catalogFormat,
                    ]
                ];

            } catch (\Exception $e) {
                Log::error('获取教材及目录失败', [
                    'series_id' => $seriesId,
                    'grade' => $grade,
                    'semester_code' => $semesterCode,
                    'error' => $e->getMessage()
                ]);

                return [
                    'success' => false,
                    'message' => '获取教材信息失败: ' . $e->getMessage(),
                    'data' => null,
                ];
            }
        }

        // 外部API调用（如果需要）
        try {
            $result = $this->request('GET', '/textbooks/filter', [
                'series_id' => $seriesId,
                'grade' => $grade,
                'semester_code' => $semesterCode,
                'catalog_format' => $catalogFormat,
            ]);

            return [
                'success' => true,
                'data' => $result['data'] ?? null,
                'meta' => $result['meta'] ?? []
            ];

        } catch (\Exception $e) {
            Log::warning('Failed to fetch textbook by filter, returning empty result', ['error' => $e->getMessage()]);
            return [
                'success' => false,
                'message' => '获取教材信息失败: ' . $e->getMessage(),
                'data' => null,
            ];
        }
    }

    /**
     * 获取学期标签
     */
    private function getSemesterLabel(?int $semester): string
    {
        return match ($semester) {
            1 => '上册',
            2 => '下册',
            default => '',
        };
    }

    /**
     * 获取学段标签
     */
    private function getStageLabel(string $stage): string
    {
        return match ($stage) {
            'primary' => '小学',
            'junior' => '初中',
            'senior' => '高中',
            default => $stage,
        };
    }

    /**
     * 格式化封面URL
     */
    private function formatCoverUrl(?string $coverPath): string
    {
        if (empty($coverPath)) {
            return '';
        }

        // 如果已经是完整URL，直接返回
        if (str_starts_with($coverPath, 'http://') || str_starts_with($coverPath, 'https://')) {
            return $coverPath;
        }

        // 本地存储路径，添加域名
        return url('/storage/' . ltrim($coverPath, '/'));
    }

    /**
     * 获取年级标签
     */
    private function getGradeLabel(?int $grade, string $stage): string
    {
        if ($grade === null) {
            return '';
        }

        return match ($stage) {
            'primary' => $grade . '年级',
            'junior' => match ($grade) {
                7 => '七年级',
                8 => '八年级',
                9 => '九年级',
                default => $grade . '年级',
            },
            'senior' => match ($grade) {
                10 => '高一',
                11 => '高二',
                12 => '高三',
                default => '高' . ($grade - 9),
            },
            default => $grade . '年级',
        };
    }

    private function buildCatalogTree(array $nodes): array
    {
        // 建立ID索引，包含children数组
        $indexed = [];
        foreach ($nodes as &$node) { // 使用引用
            $node['children'] = [];
            $indexed[$node['id']] = &$node;
        }
        unset($node); // 释放引用

        $tree = [];
        foreach ($nodes as &$node) { // 使用引用
            $parentId = $node['parent_id'] ?? null;
            if ($parentId && isset($indexed[$parentId])) {
                // 父节点存在，将当前节点添加到父节点的children中
                $indexed[$parentId]['children'][] = &$node;
            } else {
                // 根节点，直接添加到树中
                $tree[] = &$node;
            }
        }
        unset($node); // 释放引用

        return $tree;
    }
}
