import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../core/format.dart'; import '../../core/models.dart'; import '../../core/providers.dart'; import '../../core/theme.dart'; import '../../widgets/ui.dart'; import 'shop_sheet.dart'; class ShopDetailScreen extends ConsumerWidget { const ShopDetailScreen({super.key, required this.shopId}); final int shopId; @override Widget build(BuildContext context, WidgetRef ref) { final date = ref.watch(selectedDateProvider); final detail = ref.watch(shopDetailProvider((shopId, date))); final isAdmin = ref.watch(sessionProvider)?.isAdmin ?? false; return Scaffold( body: SafeArea( child: asyncView( detail, (d) => Column( children: [ ScreenHeader( title: d.shop.name, back: true, maxWidth: _maxW, trailing: isAdmin ? RoundIcon( Icons.edit_outlined, label: 'Edit shop', onTap: () => showShopSheet( context, shop: d.shop, onDeactivated: () { if (context.mounted) context.go('/shops'); }, ), ) : null, ), Expanded( child: _Body(d: d, date: date), ), ], ), retry: () => ref.invalidate(shopDetailProvider((shopId, date))), ), ), ); } } const _maxW = 960.0; class _Body extends StatelessWidget { const _Body({required this.d, required this.date}); final ShopDetail d; final DateTime date; @override Widget build(BuildContext context) { final out = d.draw.published; final wins = d.wins; return PageList( maxWidth: _maxW, top: 0, children: [ Row( children: [ Pill(d.shop.code, bg: C.chip, fg: C.navy), const SizedBox(width: S.s10), Expanded( child: Text( '${d.draw.label} · ${dateShort(date)}', maxLines: 1, overflow: TextOverflow.ellipsis, style: ts(13, c: C.muted), ), ), ], ), const SizedBox(height: S.s16), if (out) NavyCard( child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'WINNING ENDINGS', style: ts(10, w: w6, c: C.softOnNavy, ls: 1), ), const SizedBox(height: S.s8), Text( '${wins.length}', style: ts(34, w: w7, c: Colors.white, ls: -0.5), ), const SizedBox(height: S.s2), Text( 'of ${inr(d.endings.length)} endings', style: ts(12, c: C.softOnNavy), ), ], ), ), Container(width: 1, height: 64, color: C.onNavy20), const SizedBox(width: S.s22), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'PRIZE AMOUNT', style: ts(10, w: w6, c: C.softOnNavy, ls: 1), ), const SizedBox(height: S.s8), Text( rupees(d.prize), style: ts( 30, w: w7, c: d.prize > 0 ? C.gold : C.softOnNavy, ls: -0.5, ), ), const SizedBox(height: S.s2), Text( plural(d.winTickets, 'winning ticket'), style: ts(12, c: C.softOnNavy), ), ], ), ), ], ), ) else NavyCard( child: Row( children: [ const Icon(Icons.schedule_rounded, color: C.gold, size: 28), const SizedBox(width: S.s14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Results not yet published', style: ts(18, w: w7, c: Colors.white), ), const SizedBox(height: S.s4), Text( 'Prize details will appear here once results are published.', style: ts(12, c: C.softOnNavy), ), ], ), ), ], ), ), const SizedBox(height: S.s12), Row( children: [ Expanded( child: StatCard(label: 'TICKETS', value: inr(d.tickets)), ), const SizedBox(width: S.s12), Expanded( child: StatCard( label: 'PRIZE WON', value: out ? rupees(d.prize) : '—', valueColor: out && d.prize > 0 ? C.green : C.muted, ), ), ], ), if (out) ...[ SectionTitle( 'Winning endings', trailing: wins.isEmpty ? null : '${wins.length}', ), if (wins.isEmpty) const SrsCard( child: EmptyState( icon: Icons.sentiment_neutral_rounded, title: 'No winning endings', body: 'None of this shop’s endings matched a prize in this draw.', ), ) else CardGrid( minItemWidth: 320, maxColumns: 2, children: [for (final w in wins) _WinRow(w: w)], ), ], const SizedBox(height: S.s14), SrsCard( onTap: d.tickets == 0 ? null : () => context.push('/shops/${d.shop.id}/tickets'), child: Row( children: [ Container( width: 42, height: 42, decoration: BoxDecoration( color: C.chip, borderRadius: BorderRadius.circular(R.md), ), child: const Icon( Icons.confirmation_number_outlined, color: C.navy, size: 22, ), ), const SizedBox(width: S.s14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Tickets · ${inr(d.tickets)}', style: ts(15, w: w6)), const SizedBox(height: S.s2), Text( d.tickets == 0 ? 'No orders for this draw' : '${plural(d.endings.length, 'ending')} · ${plural(d.orders.length, 'order')}', style: ts(12, c: C.muted), ), ], ), ), if (d.tickets > 0) const Icon(Icons.chevron_right_rounded, color: C.placeholder), ], ), ), ], ); } } class _WinRow extends StatelessWidget { const _WinRow({required this.w}); final EndingQty w; @override Widget build(BuildContext context) => SrsCard( padding: const EdgeInsets.all(S.s14), child: Row( children: [ Container( width: 62, height: 46, alignment: Alignment.center, decoration: BoxDecoration( color: C.greenTint, borderRadius: BorderRadius.circular(R.input), ), child: Text( w.ending, style: ts(17, w: w7, c: C.green, ls: 0.5), ), ), const SizedBox(width: S.s14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('× ${plural(w.qty, 'ticket')}', style: ts(14, w: w6)), const SizedBox(height: S.s4), Text( '${w.tierText} · ${rupees(w.perTicket)} each', style: ts(12, c: C.muted), ), ], ), ), Text( rupees(w.prize), style: ts(16, w: w7, c: C.green), ), ], ), ); }