import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';

/// A single labelled bar in [StatBarChart].
class StatBarDatum {
  const StatBarDatum({required this.label, required this.value});

  /// Short label rendered along the X axis (kept terse so it fits).
  final String label;
  final int value;
}

/// Lightweight wrapper around [BarChart] for the top-6 leaderboards. Renders
/// vertical bars with a numeric Y axis and the supplied [data] labels on X.
class StatBarChart extends StatelessWidget {
  const StatBarChart({
    super.key,
    required this.data,
    required this.valueLabel,
    this.height = 280,
  });

  /// Sorted list of bars to render (highest first); only the first 6 are used.
  final List<StatBarDatum> data;

  /// Used for the Y axis title, e.g. "Goals".
  final String valueLabel;

  final double height;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final scheme = theme.colorScheme;

    final visible = data.take(6).toList(growable: false);

    if (visible.isEmpty) {
      return SizedBox(
        height: height,
        child: Center(
          child: Text(
            'No data yet',
            style: theme.textTheme.bodyMedium?.copyWith(
              color: scheme.onSurfaceVariant,
            ),
          ),
        ),
      );
    }

    final maxValue = visible
        .map((d) => d.value)
        .fold<int>(0, (a, b) => a > b ? a : b);
    // Round the y-axis ceiling up to the nearest sensible interval so the
    // grid lines land on whole numbers.
    final yMax = maxValue <= 4 ? 4.0 : (maxValue + 2).toDouble();
    final interval = yMax <= 6 ? 1.0 : (yMax / 5).ceilToDouble();

    return Padding(
      padding: const EdgeInsets.fromLTRB(12, 4, 16, 8),
      child: SizedBox(
        height: height,
        child: BarChart(
          BarChartData(
            alignment: BarChartAlignment.spaceAround,
            maxY: yMax,
            minY: 0,
            barTouchData: BarTouchData(
              enabled: true,
              touchTooltipData: BarTouchTooltipData(
                getTooltipColor: (_) => scheme.surfaceContainerHigh,
                tooltipBorder: BorderSide(color: scheme.outlineVariant),
                getTooltipItem: (group, _, rod, _) {
                  final datum = visible[group.x];
                  return BarTooltipItem(
                    '${datum.label}\n',
                    theme.textTheme.bodySmall!.copyWith(
                      color: scheme.onSurface,
                      fontWeight: FontWeight.w700,
                    ),
                    children: [
                      TextSpan(
                        text: '${rod.toY.toInt()} $valueLabel',
                        style: theme.textTheme.bodySmall?.copyWith(
                          color: scheme.primary,
                          fontWeight: FontWeight.w700,
                        ),
                      ),
                    ],
                  );
                },
              ),
            ),
            gridData: FlGridData(
              show: true,
              drawVerticalLine: false,
              horizontalInterval: interval,
              getDrawingHorizontalLine: (_) => FlLine(
                color: scheme.outlineVariant.withValues(alpha: 0.4),
                strokeWidth: 1,
              ),
            ),
            borderData: FlBorderData(show: false),
            titlesData: FlTitlesData(
              show: true,
              topTitles: const AxisTitles(
                sideTitles: SideTitles(showTitles: false),
              ),
              rightTitles: const AxisTitles(
                sideTitles: SideTitles(showTitles: false),
              ),
              leftTitles: AxisTitles(
                axisNameWidget: Padding(
                  padding: const EdgeInsets.only(bottom: 6),
                  child: Text(
                    valueLabel,
                    style: theme.textTheme.labelSmall?.copyWith(
                      color: scheme.onSurfaceVariant,
                      letterSpacing: 0.5,
                    ),
                  ),
                ),
                axisNameSize: 18,
                sideTitles: SideTitles(
                  showTitles: true,
                  interval: interval,
                  reservedSize: 32,
                  getTitlesWidget: (value, meta) {
                    if (value == 0 || value > yMax) {
                      return const SizedBox.shrink();
                    }
                    return Padding(
                      padding: const EdgeInsets.only(right: 4),
                      child: Text(
                        value.toInt().toString(),
                        style: theme.textTheme.labelSmall?.copyWith(
                          color: scheme.onSurfaceVariant,
                        ),
                      ),
                    );
                  },
                ),
              ),
              bottomTitles: AxisTitles(
                sideTitles: SideTitles(
                  showTitles: true,
                  reservedSize: 36,
                  interval: 1,
                  getTitlesWidget: (value, meta) {
                    final index = value.toInt();
                    if (index < 0 || index >= visible.length) {
                      return const SizedBox.shrink();
                    }
                    return Padding(
                      padding: const EdgeInsets.only(top: 6),
                      child: Text(
                        _shortLabel(visible[index].label),
                        textAlign: TextAlign.center,
                        style: theme.textTheme.labelSmall?.copyWith(
                          color: scheme.onSurfaceVariant,
                          fontWeight: FontWeight.w600,
                        ),
                      ),
                    );
                  },
                ),
              ),
            ),
            barGroups: [
              for (var i = 0; i < visible.length; i++)
                BarChartGroupData(
                  x: i,
                  barRods: [
                    BarChartRodData(
                      toY: visible[i].value.toDouble(),
                      color: scheme.primary,
                      width: 22,
                      borderRadius: const BorderRadius.vertical(
                        top: Radius.circular(6),
                      ),
                      backDrawRodData: BackgroundBarChartRodData(
                        show: true,
                        toY: yMax,
                        color: scheme.surfaceContainerHighest
                            .withValues(alpha: 0.5),
                      ),
                    ),
                  ],
                ),
            ],
          ),
        ),
      ),
    );
  }

  /// Compresses long names like "Marcus Reed" → "M. Reed" so X-axis labels
  /// don't overflow on phone widths.
  static String _shortLabel(String full) {
    final parts = full.trim().split(RegExp(r'\s+'));
    if (parts.length < 2) {
      return parts.first.length > 10
          ? '${parts.first.substring(0, 9)}…'
          : parts.first;
    }
    final last = parts.last;
    final first = parts.first;
    final initial = first.isEmpty ? '' : '${first[0]}. ';
    final candidate = '$initial$last';
    if (candidate.length <= 12) return candidate;
    return '${candidate.substring(0, 11)}…';
  }
}
