import 'package:flutter/material.dart'; import '../../core/app_state.dart'; import '../../core/app_theme.dart'; import '../../core/courses/courses.dart'; import '../../widgets/app_widgets.dart'; /// 今天最该做的一件事:继续课程对话 → 到期复习 → 阶段评估/巩固 → 下一课。 class TodayTaskCard extends StatelessWidget { const TodayTaskCard({ super.key, required this.state, required this.onStartLesson, required this.onStartReview, required this.onResumeLessonDialogue, required this.onStartReinforcement, required this.onOpenAssessment, }); final AppState state; final VoidCallback onStartLesson; final VoidCallback onStartReview; final VoidCallback onResumeLessonDialogue; final VoidCallback onStartReinforcement; final ValueChanged onOpenAssessment; @override Widget build(BuildContext context) { final task = _todayTask(); return SectionCard( tint: AppColors.softGreen, child: SpacedColumn( children: [ Row( children: [ Expanded(child: Eyebrow(task.label)), Text(task.minutes, style: TextStyle(color: AppColors.green)), ], ), Text( task.title, style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w600), ), Text(task.note, style: Theme.of(context).textTheme.bodyMedium), PrimaryButton(label: task.action, onPressed: task.onPressed), ], ), ); } _TodayTask _todayTask() { var lessonId = state.activeLessonId; if (state.completedLessonIds.contains(lessonId)) { final next = state.nextIncompleteLessonId; if (next != null) { lessonId = next; } } final lesson = lessonById(lessonId); if (state.hasResumableLessonDialogue) { return _TodayTask( label: '未完成', title: '继续第 ${lesson.number} 课的课程对话', note: '已保留你的对话进度和提示状态。', action: '继续对话', minutes: '5 分钟', onPressed: onResumeLessonDialogue, ); } if (state.reviewIsPrimary) { final count = state.dueReviewCount; return _TodayTask( label: '今日复习', title: '先复习 $count 项', note: state.reviewBacklog ? '有积压项目;先花几分钟清掉到期复习,再开启新课。' : '之前练过的关键句,今天换个情境再用一次。', action: '开始复习', minutes: '${(count * 2).clamp(2, 10)} 分钟', onPressed: onStartReview, ); } // A0 课程学完、尚未通过阶段评估时,先巩固再评估;通过后回到下一课。 if (state.a0LessonsComplete && !state.a0Passed) return _stageTask(); if (state.allLessonsComplete) { return _TodayTask( label: '已学完', title: '所有课程已完成', note: '你已学完全部课程内容!建议保持日常到期复习或自由情境对话。', action: '去复习', minutes: '10 分钟', onPressed: onStartReview, ); } final segments = lesson.segments.length; final segmentIndex = state.activeSegmentIndexFor(lesson.id); final segment = segmentIndex + 1; final isSegmentResuming = segments > 1 && segmentIndex > 0; return _TodayTask( label: isSegmentResuming ? '继续课程' : '今日新课', title: '第 ${lesson.number} 课 · ${lesson.title}' '${segments > 1 ? ' · 第 $segment/$segments 段' : ''}', note: isSegmentResuming ? '第 $segmentIndex 段已学完;继续本课下一段情境训练。' : '预热词汇 → 听说读写 → 对话 → 独立尝试', action: isSegmentResuming ? '继续学习第 $segment 段' : '开始今天的学习', minutes: '12 分钟', onPressed: () { if (state.activeLessonId != lesson.id) { state.openLesson(lesson.id); } onStartLesson(); }, ); } _TodayTask _stageTask() { final usable = '可使用 ${state.coreUsableCount}/$a0UsableGoal · ' '已掌握 ${state.coreMasteredCount}/$a0MasteredGoal'; final packId = state.nextAssessmentPackId; if (state.a0AssessmentReady && packId != null) { return _TodayTask( label: '阶段评估', title: 'A0 阶段评估 · $packId', note: '$usable。可以开始阶段评估,两套评估间隔至少 24 小时。', action: '开始阶段评估', minutes: '15 分钟', onPressed: () => onOpenAssessment(packId), ); } return _TodayTask( label: 'A0 巩固', title: state.a0AssessmentReady ? '第二套评估 24 小时后开放' : 'A0 课程已学完', note: state.a0AssessmentReady ? '第一套评估已通过。等待期间继续巩固。' : '$usable。继续按时复习、做情境对话,达到要求后开放阶段评估。', action: '安排一题巩固练习', minutes: '3 分钟', onPressed: onStartReinforcement, ); } } class _TodayTask { const _TodayTask({ required this.label, required this.title, required this.note, required this.action, required this.minutes, required this.onPressed, }); final String label; final String title; final String note; final String action; final String minutes; final VoidCallback onPressed; }