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

import '../../../providers/reports_provider.dart';
import 'report_card_wrapper.dart';

/// Converts 24h hour int to AM/PM string.
String _hourAmPm(int h) {
  if (h == 0) return '12AM';
  if (h < 12) return '${h}AM';
  if (h == 12) return '12PM';
  return '${h - 12}PM';
}

/// Vertical bar chart showing tasks created per hour of day (0–23).
class TasksByHourChart extends ConsumerWidget {
  const TasksByHourChart({super.key, this.repaintKey});
  final GlobalKey? repaintKey;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final asyncData = ref.watch(tasksByHourReportProvider);

    return asyncData.when(
      loading: () => ReportCardWrapper(
        title: 'Tasks Created by Hour',
        isLoading: true,
        height: 260,
        repaintBoundaryKey: repaintKey,
        child: const SizedBox.shrink(),
      ),
      error: (e, _) => ReportCardWrapper(
        title: 'Tasks Created by Hour',
        error: e.toString(),
        repaintBoundaryKey: repaintKey,
        child: const SizedBox.shrink(),
      ),
      data: (data) => _build(context, data),
    );
  }

  Widget _build(BuildContext context, List<HourCount> data) {
    if (data.isEmpty) {
      return ReportCardWrapper(
        title: 'Tasks Created by Hour',
        repaintBoundaryKey: repaintKey,
        child: const SizedBox(
          height: 200,
          child: Center(child: Text('No data for selected period')),
        ),
      );
    }

    // Fill all 24 hours
    final hourMap = {for (final h in data) h.hour: h.count};
    final maxCount = data
        .fold<int>(0, (m, e) => e.count > m ? e.count : m)
        .toDouble();

    final colors = Theme.of(context).colorScheme;

    return ReportCardWrapper(
      title: 'Tasks Created by Hour',
      repaintBoundaryKey: repaintKey,
      height: 260,
      child: BarChart(
        BarChartData(
          maxY: maxCount * 1.15,
          barTouchData: BarTouchData(
            touchTooltipData: BarTouchTooltipData(
              getTooltipItem: (group, groupIdx, rod, rodIdx) {
                return BarTooltipItem(
                  '${_hourAmPm(group.x)} — ${rod.toY.toInt()}',
                  Theme.of(context).textTheme.bodySmall!.copyWith(
                    color: colors.onInverseSurface,
                  ),
                );
              },
            ),
          ),
          titlesData: FlTitlesData(
            leftTitles: AxisTitles(
              sideTitles: SideTitles(
                showTitles: true,
                reservedSize: 36,
                getTitlesWidget: (value, meta) => Text(
                  value.toInt().toString(),
                  style: Theme.of(context).textTheme.labelSmall,
                ),
              ),
            ),
            bottomTitles: AxisTitles(
              sideTitles: SideTitles(
                showTitles: true,
                getTitlesWidget: (value, meta) {
                  final h = value.toInt();
                  // Show every 3rd hour label to avoid crowding
                  if (h % 3 != 0) return const SizedBox.shrink();
                  return Padding(
                    padding: const EdgeInsets.only(top: 4),
                    child: Text(
                      _hourAmPm(h),
                      style: Theme.of(context).textTheme.labelSmall,
                    ),
                  );
                },
              ),
            ),
            topTitles: const AxisTitles(
              sideTitles: SideTitles(showTitles: false),
            ),
            rightTitles: const AxisTitles(
              sideTitles: SideTitles(showTitles: false),
            ),
          ),
          gridData: FlGridData(
            drawVerticalLine: false,
            horizontalInterval: maxCount > 0
                ? (maxCount / 4).ceilToDouble()
                : 1,
          ),
          borderData: FlBorderData(show: false),
          barGroups: List.generate(24, (i) {
            final count = (hourMap[i] ?? 0).toDouble();
            return BarChartGroupData(
              x: i,
              barRods: [
                BarChartRodData(
                  toY: count,
                  width: 10,
                  borderRadius: const BorderRadius.vertical(
                    top: Radius.circular(4),
                  ),
                  color: colors.primary,
                ),
              ],
            );
          }),
        ),
      ),
    );
  }
}

/// Vertical bar chart showing tickets created per hour of day (0–23).
class TicketsByHourChart extends ConsumerWidget {
  const TicketsByHourChart({super.key, this.repaintKey});
  final GlobalKey? repaintKey;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final asyncData = ref.watch(ticketsByHourReportProvider);

    return asyncData.when(
      loading: () => ReportCardWrapper(
        title: 'Tickets Created by Hour',
        isLoading: true,
        height: 260,
        repaintBoundaryKey: repaintKey,
        child: const SizedBox.shrink(),
      ),
      error: (e, _) => ReportCardWrapper(
        title: 'Tickets Created by Hour',
        error: e.toString(),
        repaintBoundaryKey: repaintKey,
        child: const SizedBox.shrink(),
      ),
      data: (data) => _build(context, data),
    );
  }

  Widget _build(BuildContext context, List<HourCount> data) {
    if (data.isEmpty) {
      return ReportCardWrapper(
        title: 'Tickets Created by Hour',
        repaintBoundaryKey: repaintKey,
        child: const SizedBox(
          height: 200,
          child: Center(child: Text('No data for selected period')),
        ),
      );
    }

    final hourMap = {for (final h in data) h.hour: h.count};
    final maxCount = data
        .fold<int>(0, (m, e) => e.count > m ? e.count : m)
        .toDouble();
    final colors = Theme.of(context).colorScheme;

    return ReportCardWrapper(
      title: 'Tickets Created by Hour',
      repaintBoundaryKey: repaintKey,
      height: 260,
      child: BarChart(
        BarChartData(
          maxY: maxCount * 1.15,
          barTouchData: BarTouchData(
            touchTooltipData: BarTouchTooltipData(
              getTooltipItem: (group, groupIdx, rod, rodIdx) {
                return BarTooltipItem(
                  '${_hourAmPm(group.x)} — ${rod.toY.toInt()}',
                  Theme.of(context).textTheme.bodySmall!.copyWith(
                    color: colors.onInverseSurface,
                  ),
                );
              },
            ),
          ),
          titlesData: FlTitlesData(
            leftTitles: AxisTitles(
              sideTitles: SideTitles(
                showTitles: true,
                reservedSize: 36,
                getTitlesWidget: (value, meta) => Text(
                  value.toInt().toString(),
                  style: Theme.of(context).textTheme.labelSmall,
                ),
              ),
            ),
            bottomTitles: AxisTitles(
              sideTitles: SideTitles(
                showTitles: true,
                getTitlesWidget: (value, meta) {
                  final h = value.toInt();
                  if (h % 3 != 0) return const SizedBox.shrink();
                  return Padding(
                    padding: const EdgeInsets.only(top: 4),
                    child: Text(
                      _hourAmPm(h),
                      style: Theme.of(context).textTheme.labelSmall,
                    ),
                  );
                },
              ),
            ),
            topTitles: const AxisTitles(
              sideTitles: SideTitles(showTitles: false),
            ),
            rightTitles: const AxisTitles(
              sideTitles: SideTitles(showTitles: false),
            ),
          ),
          gridData: FlGridData(
            drawVerticalLine: false,
            horizontalInterval: maxCount > 0
                ? (maxCount / 4).ceilToDouble()
                : 1,
          ),
          borderData: FlBorderData(show: false),
          barGroups: List.generate(24, (i) {
            final count = (hourMap[i] ?? 0).toDouble();
            return BarChartGroupData(
              x: i,
              barRods: [
                BarChartRodData(
                  toY: count,
                  width: 10,
                  borderRadius: const BorderRadius.vertical(
                    top: Radius.circular(4),
                  ),
                  color: colors.tertiary,
                ),
              ],
            );
          }),
        ),
      ),
    );
  }
}
