import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/time.dart'; import '../../domain/models/tracker_entry.dart'; import '../../domain/streak/compute_streak.dart'; import '../../state/providers.dart'; class StreakScreen extends ConsumerWidget { final String habitId; const StreakScreen({super.key, required this.habitId}); @override Widget build(BuildContext context, WidgetRef ref) { final db = ref.watch(appDatabaseProvider); final habitFuture = (db.select(db.habits) ..where((t) => t.id.equals(habitId))) .getSingle(); final entriesFuture = ref.read(trackerDaoProvider).entriesForHabit(habitId); return Scaffold( appBar: AppBar(title: const Text('스트릭')), body: FutureBuilder( future: Future.wait([habitFuture, entriesFuture]), builder: (context, snap) { if (!snap.hasData) { return const Center(child: CircularProgressIndicator()); } if (snap.hasError) { return Center(child: Text('실패: ${snap.error}')); } final habit = snap.data![0] as dynamic; final entryRows = snap.data![1] as List; final entries = entryRows.map((r) { return TrackerEntryModel( id: r.id as String, habitId: r.habitId as String, date: r.date as String, value: (r.value as String) == 'done' ? TrackerValue.done : TrackerValue.blank, variantId: r.variantId as String?, ctxLocation: r.ctxLocation as String?, ctxCondition: r.ctxCondition as String?, note: r.note as String?, loggedAt: r.loggedAt as String?, ); }).toList(); final state = computeStreak( entries: entries, asOf: nowKst(), habitStartedAt: habit.startedAt as String, ); return Padding( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(habit.title as String, style: Theme.of(context).textTheme.titleLarge), const SizedBox(height: 24), _Row('현재 스트릭', '${state.currentStreak}일'), _Row('최장 스트릭', '${state.longestStreak}일'), _Row('최근 30일 / 완료', '${state.doneCountInWindow30}회'), _Row('Phase 42일 / 완료', '${state.doneCountInPhase42}회'), const Divider(height: 32), _Row('현재 티어', state.currentTier.dbValue), if (state.neverMissTwiceBroken) const Padding( padding: EdgeInsets.only(top: 12), child: Text( '⚠ Never miss twice 발동 — 티어 강등', style: TextStyle(color: Colors.redAccent), ), ), ], ), ); }, ), ); } } class _Row extends StatelessWidget { final String label; final String value; const _Row(this.label, this.value); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6), child: Row( children: [ Expanded(child: Text(label)), Text(value, style: const TextStyle(fontWeight: FontWeight.w600)), ], ), ); } }