<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Services\TextbookApiService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;

class TextbookApiController extends Controller
{
    protected TextbookApiService $textbookService;

    public function __construct(TextbookApiService $textbookService)
    {
        $this->textbookService = $textbookService;
    }

    /**
     * 获取教材列表（按年级排序）
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function index(Request $request): JsonResponse
    {
        try {
            $params = [
                'page' => $request->get('page', 1),
                'per_page' => $request->get('per_page', 50),
            ];

            // 可选过滤参数
            if ($request->has('grade')) {
                $params['grade'] = $request->get('grade');
            }
            if ($request->has('stage')) {
                $params['stage'] = $this->convertStageToCode($request->get('stage'));
            }
            if ($request->has('semester')) {
                $params['semester'] = $this->convertSemesterToCode($request->get('semester'));
            }
            if ($request->has('series_id')) {
                $params['series_id'] = $request->get('series_id');
            }
            if ($request->has('status')) {
                $params['status'] = $request->get('status');
            }

            // 支持包含未发布的教材（默认只返回已发布的）
            if ($request->has('include_unpublished')) {
                $params['include_unpublished'] = $request->get('include_unpublished');
            }

            // 支持包含未启用系列的教材（默认只返回启用系列的）
            if ($request->has('include_inactive_series')) {
                $params['include_inactive_series'] = $request->get('include_inactive_series');
            }

            $result = $this->textbookService->getTextbooks($params);

            // 格式化返回数据
            $textbooks = $this->formatTextbookList($result['data'] ?? []);

            // 按年级排序
            usort($textbooks, function ($a, $b) {
                // 先按学段排序：小学 < 初中 < 高中
                $stageOrder = ['primary' => 1, 'junior' => 2, 'senior' => 3];
                $stageA = $stageOrder[$a['stage_code']] ?? 99;
                $stageB = $stageOrder[$b['stage_code']] ?? 99;

                if ($stageA !== $stageB) {
                    return $stageA - $stageB;
                }

                // 再按年级排序
                $gradeA = $a['grade'] ?? 0;
                $gradeB = $b['grade'] ?? 0;

                if ($gradeA !== $gradeB) {
                    return $gradeA - $gradeB;
                }

                // 最后按学期排序
                $semesterA = $a['semester_code'] ?? 0;
                $semesterB = $b['semester_code'] ?? 0;

                return $semesterA - $semesterB;
            });

            return response()->json([
                'success' => true,
                'data' => $textbooks,
                'meta' => array_merge($result['meta'] ?? [], [
                    'page' => $params['page'],
                    'per_page' => $params['per_page'],
                    'total' => count($textbooks),
                    'filters' => [
                        'grade' => $request->get('grade'),
                        'stage' => $request->get('stage'),
                        'semester' => $request->get('semester'),
                        'series_id' => $request->get('series_id'),
                        'status' => $request->get('status'),
                        'include_unpublished' => $request->get('include_unpublished') === 'true',
                        'include_inactive_series' => $request->get('include_inactive_series') === 'true',
                    ]
                ])
            ]);

        } catch (\Exception $e) {
            Log::error('获取教材列表失败', ['error' => $e->getMessage()]);

            return response()->json([
                'success' => false,
                'message' => '获取教材列表失败: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * 根据年级获取教材
     *
     * @param int $grade 年级（1-12）
     * @param Request $request
     * @return JsonResponse
     */
    public function getByGrade(int $grade, Request $request): JsonResponse
    {
        try {
            $schoolingSystem = (string) $request->get('schooling_system', '');
            $stageParam = $request->get('stage');

            $params = [
                'grade' => $grade,
                'per_page' => 100,
            ];

            if ($stageParam) {
                $params['stage'] = $this->convertStageToCode((string) $stageParam);
            } elseif ($schoolingSystem === '5-4') {
                $params['stage'] = $this->getStageByGrade($grade, $schoolingSystem);
            }

            if ($request->has('semester')) {
                $params['semester'] = $this->convertSemesterToCode($request->get('semester'));
            }
            if ($request->has('series_id')) {
                $params['series_id'] = $request->get('series_id');
            }
            if ($request->has('status')) {
                $params['status'] = $request->get('status');
            }

            // 支持包含未发布的教材（默认只返回已发布的）
            if ($request->has('include_unpublished')) {
                $params['include_unpublished'] = $request->get('include_unpublished');
            }

            // 支持包含未启用系列的教材（默认只返回启用系列的）
            if ($request->has('include_inactive_series')) {
                $params['include_inactive_series'] = $request->get('include_inactive_series');
            }

            $result = $this->textbookService->getTextbooks($params);
            $textbooks = $this->formatTextbookList($result['data'] ?? []);

            // 按学期排序
            usort($textbooks, function ($a, $b) {
                return ($a['semester_code'] ?? 0) - ($b['semester_code'] ?? 0);
            });

            return response()->json([
                'success' => true,
                'data' => $textbooks,
                'meta' => [
                    'grade' => $grade,
                    'stage' => $params['stage'] ?? null,
                    'stage_label' => isset($params['stage']) ? $this->getStageLabel($params['stage']) : null,
                    'total' => count($textbooks),
                    'filters' => [
                        'semester' => $request->get('semester'),
                        'series_id' => $request->get('series_id'),
                        'status' => $request->get('status'),
                        'include_unpublished' => $request->get('include_unpublished') === 'true',
                        'include_inactive_series' => $request->get('include_inactive_series') === 'true',
                    ]
                ]
            ]);

        } catch (\Exception $e) {
            Log::error('根据年级获取教材失败', [
                'grade' => $grade,
                'error' => $e->getMessage()
            ]);

            return response()->json([
                'success' => false,
                'message' => '获取教材失败: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * 获取单个教材详情
     *
     * @param int $id 教材ID
     * @return JsonResponse
     */
    public function show(int $id): JsonResponse
    {
        try {
            $textbook = $this->textbookService->getTextbook($id);

            if (!$textbook) {
                return response()->json([
                    'success' => false,
                    'message' => '教材不存在'
                ], 404);
            }

            return response()->json([
                'success' => true,
                'data' => $this->formatTextbook($textbook)
            ]);

        } catch (\Exception $e) {
            Log::error('获取教材详情失败', [
                'id' => $id,
                'error' => $e->getMessage()
            ]);

            return response()->json([
                'success' => false,
                'message' => '获取教材详情失败: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * 获取教材系列列表
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function getSeries(Request $request): JsonResponse
    {
        try {
            $params = [];

            // 支持按学段筛选
            if ($request->has('stage')) {
                $params['stage'] = $this->convertStageToCode($request->get('stage'));
            }

            // 支持包含未启用的系列（默认只返回启用的）
            if ($request->has('include_inactive')) {
                $params['include_inactive'] = $request->get('include_inactive');
            }

            $result = $this->textbookService->getTextbookSeries($params);

            $series = array_map(function ($item) {
                return [
                    'id' => $item['id'],
                    'name' => $item['name'],
                    'slug' => $item['slug'] ?? '',
                    'publisher' => $item['publisher'] ?? '',
                    'region' => $item['region'] ?? '全国',
                    'stages' => $this->formatStages($item['stages'] ?? '[]'),
                    'is_active' => $item['is_active'] ?? true,
                    'sort_order' => $item['sort_order'] ?? 0,
                ];
            }, $result['data'] ?? []);

            // 按排序字段排序
            usort($series, fn($a, $b) => ($a['sort_order'] ?? 0) - ($b['sort_order'] ?? 0));

            return response()->json([
                'success' => true,
                'data' => $series,
                'meta' => [
                    'total' => count($series),
                    'filters' => [
                        'stage' => $request->get('stage'),
                        'include_inactive' => $request->get('include_inactive') === 'true',
                    ]
                ]
            ]);

        } catch (\Exception $e) {
            Log::error('获取教材系列失败', ['error' => $e->getMessage()]);

            return response()->json([
                'success' => false,
                'message' => '获取教材系列失败: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * 年级枚举
     */
    public function getGradeEnums(): JsonResponse
    {
        $schoolingSystem = (string) request()->get('schooling_system', '');
        $grades = [];

        $primaryMax = $schoolingSystem === '5-4' ? 5 : 6;
        foreach (range(1, $primaryMax) as $grade) {
            $grades[] = [
                'grade' => $grade,
                'label' => $this->getGradeLabel($grade, 'primary'),
                'stage' => 'primary',
                'stage_label' => $this->getStageLabel('primary'),
            ];
        }

        $juniorStart = $schoolingSystem === '5-4' ? 6 : 7;
        foreach (range($juniorStart, 9) as $grade) {
            $grades[] = [
                'grade' => $grade,
                'label' => $this->getGradeLabel($grade, 'junior'),
                'stage' => 'junior',
                'stage_label' => $this->getStageLabel('junior'),
            ];
        }

        foreach (range(10, 12) as $grade) {
            $grades[] = [
                'grade' => $grade,
                'label' => $this->getGradeLabel($grade, 'senior'),
                'stage' => 'senior',
                'stage_label' => $this->getStageLabel('senior'),
            ];
        }

        return response()->json([
            'success' => true,
            'data' => $grades,
        ]);
    }

    /**
     * 获取教材目录
     *
     * @param int $textbookId 教材ID
     * @param Request $request
     * @return JsonResponse
     */
    public function getCatalog(int $textbookId, Request $request): JsonResponse
    {
        try {
            $format = $request->get('format', 'tree'); // tree 或 flat
            $catalog = $this->textbookService->getTextbookCatalog($textbookId, $format);

            return response()->json([
                'success' => true,
                'data' => $catalog,
                'meta' => [
                    'textbook_id' => $textbookId,
                    'format' => $format,
                ]
            ]);

        } catch (\Exception $e) {
            Log::error('获取教材目录失败', [
                'textbook_id' => $textbookId,
                'error' => $e->getMessage()
            ]);

            return response()->json([
                'success' => false,
                'message' => '获取教材目录失败: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * 根据教材系列、年级和学期获取教材及其目录结构
     *
     * @param int $seriesId 教材系列ID
     * @param int $grade 年级（1-12）
     * @param int $semesterCode 学期代码（1=上册，2=下册）
     * @param Request $request
     * @return JsonResponse
     */
    public function getTextbookByFilter(int $seriesId, int $grade, int $semesterCode, Request $request): JsonResponse
    {
        try {
            // 验证参数
            if (!in_array($semesterCode, [1, 2])) {
                return response()->json([
                    'success' => false,
                    'message' => '学期代码错误，应为 1（上册）或 2（下册）'
                ], 400);
            }

            if ($grade < 1 || $grade > 12) {
                return response()->json([
                    'success' => false,
                    'message' => '年级错误，应为 1-12'
                ], 400);
            }

            $catalogFormat = $request->get('format', 'tree'); // tree 或 flat

            $result = $this->textbookService->getTextbookByFilter($seriesId, $grade, $semesterCode, $catalogFormat);

            return response()->json($result);

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

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

    /**
     * 格式化教材列表
     */
    private function formatTextbookList(array $textbooks): array
    {
        return array_map(fn($item) => $this->formatTextbook($item), $textbooks);
    }

    /**
     * 格式化单个教材
     */
    private function formatTextbook(array $textbook): array
    {
        $stage = $textbook['stage'] ?? '';
        $semester = $textbook['semester'] ?? null;

        return [
            'id' => $textbook['id'],
            'name' => $textbook['official_title'] ?? '',
            'display_name' => $textbook['official_title'] ?? '',
            'cover' => $this->formatCoverUrl($textbook['cover_path'] ?? ''),
            'series_id' => $textbook['series_id'] ?? null,
            'series_name' => $textbook['series']['name'] ?? '',
            'publisher' => $textbook['series']['publisher'] ?? '',
            'stage' => $this->getStageLabel($stage),
            'stage_code' => $stage,
            'grade' => $textbook['grade'] ?? null,
            'grade_label' => $this->getGradeLabel($textbook['grade'] ?? null, $stage),
            'semester' => $this->getSemesterLabel($semester),
            'semester_code' => $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,
        ];
    }

    /**
     * 格式化封面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 getStageLabel(string $stage): string
    {
        return match ($stage) {
            'primary' => '小学',
            'junior' => '初中',
            'senior' => '高中',
            default => $stage,
        };
    }

    /**
     * 中文学段转代码
     */
    private function convertStageToCode(string $stage): string
    {
        return match ($stage) {
            '小学' => 'primary',
            '初中' => 'junior',
            '高中' => 'senior',
            default => $stage,
        };
    }

    /**
     * 学期代码转中文
     */
    private function getSemesterLabel(?int $semester): string
    {
        return match ($semester) {
            1 => '上册',
            2 => '下册',
            default => '',
        };
    }

    /**
     * 中文学期转代码
     */
    private function convertSemesterToCode(string $semester): ?int
    {
        return match ($semester) {
            '上册', '1' => 1,
            '下册', '2' => 2,
            default => null,
        };
    }

    /**
     * 年级标签
     */
    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 getStageByGrade(int $grade, string $schoolingSystem = ''): string
    {
        if ($schoolingSystem === '5-4') {
            if ($grade >= 1 && $grade <= 5) {
                return 'primary';
            }
            if ($grade >= 6 && $grade <= 9) {
                return 'junior';
            }
        }

        if ($grade >= 1 && $grade <= 6) {
            return 'primary';
        } elseif ($grade >= 7 && $grade <= 9) {
            return 'junior';
        } else {
            return 'senior';
        }
    }

    /**
     * 格式化学段数组
     */
    private function formatStages($stages): array
    {
        if (is_string($stages)) {
            $stages = json_decode($stages, true) ?? [];
        }

        if (!is_array($stages)) {
            return [];
        }

        return array_map(fn($s) => [
            'code' => $s,
            'label' => $this->getStageLabel($s),
        ], $stages);
    }
}
