import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../providers/reports_provider.dart'; import 'report_card_wrapper.dart'; /// Horizontal bar chart — top 10 offices by ticket count. /// Uses custom Flutter widgets so labels sit genuinely inside each bar. class TopOfficesTicketsChart extends ConsumerWidget { const TopOfficesTicketsChart({super.key, this.repaintKey}); final GlobalKey? repaintKey; @override Widget build(BuildContext context, WidgetRef ref) { final asyncData = ref.watch(topOfficesTicketsReportProvider); return asyncData.when( loading: () => ReportCardWrapper( title: 'Top Offices by Tickets', isLoading: true, height: 320, repaintBoundaryKey: repaintKey, child: const SizedBox.shrink(), ), error: (e, _) => ReportCardWrapper( title: 'Top Offices by Tickets', error: e.toString(), repaintBoundaryKey: repaintKey, child: const SizedBox.shrink(), ), data: (data) => _HorizontalBarBody( data: data, title: 'Top Offices by Tickets', barColor: Theme.of(context).colorScheme.primary, repaintKey: repaintKey, ), ); } } /// Horizontal bar chart — top 10 offices by task count. class TopOfficesTasksChart extends ConsumerWidget { const TopOfficesTasksChart({super.key, this.repaintKey}); final GlobalKey? repaintKey; @override Widget build(BuildContext context, WidgetRef ref) { final asyncData = ref.watch(topOfficesTasksReportProvider); return asyncData.when( loading: () => ReportCardWrapper( title: 'Top Offices by Tasks', isLoading: true, height: 320, repaintBoundaryKey: repaintKey, child: const SizedBox.shrink(), ), error: (e, _) => ReportCardWrapper( title: 'Top Offices by Tasks', error: e.toString(), repaintBoundaryKey: repaintKey, child: const SizedBox.shrink(), ), data: (data) => _HorizontalBarBody( data: data, title: 'Top Offices by Tasks', barColor: Theme.of(context).colorScheme.secondary, repaintKey: repaintKey, ), ); } } // ─── Shared horizontal-bar body (pure Flutter widgets) ─── class _HorizontalBarBody extends StatelessWidget { const _HorizontalBarBody({ required this.data, required this.title, required this.barColor, this.repaintKey, }); final List data; final String title; final Color barColor; final GlobalKey? repaintKey; @override Widget build(BuildContext context) { if (data.isEmpty) { return ReportCardWrapper( title: title, repaintBoundaryKey: repaintKey, child: const SizedBox( height: 200, child: Center(child: Text('No data for selected period')), ), ); } final maxCount = data.fold(0, (m, e) => e.count > m ? e.count : m); final height = (data.length * 34.0).clamp(160.0, 420.0); final onBarColor = barColor.computeLuminance() > 0.5 ? Colors.black87 : Colors.white; return ReportCardWrapper( title: title, repaintBoundaryKey: repaintKey, height: height, child: LayoutBuilder( builder: (context, constraints) { final availableWidth = constraints.maxWidth; final labelStyle = Theme.of(context).textTheme.labelSmall?.copyWith( color: onBarColor, fontWeight: FontWeight.w600, ); return Column( mainAxisAlignment: MainAxisAlignment.center, children: data.map((item) { final fraction = maxCount > 0 ? item.count / maxCount : 0.0; final barWidth = (fraction * availableWidth).clamp( 120.0, availableWidth, ); return Padding( padding: const EdgeInsets.symmetric(vertical: 2), child: Tooltip( message: '${item.name}: ${item.count}', child: Align( alignment: Alignment.centerLeft, child: Container( width: barWidth, height: 28, decoration: BoxDecoration( color: barColor, borderRadius: const BorderRadius.horizontal( right: Radius.circular(6), ), ), padding: const EdgeInsets.symmetric(horizontal: 8), child: Row( children: [ Expanded( child: Text( item.name, style: labelStyle, maxLines: 1, overflow: TextOverflow.ellipsis, ), ), const SizedBox(width: 6), Text('${item.count}', style: labelStyle), ], ), ), ), ), ); }).toList(), ); }, ), ); } }