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';

/// Donut chart  distribution of tasks by request type with hover animation.
class RequestTypeChart extends ConsumerStatefulWidget {
  const RequestTypeChart({super.key, this.repaintKey});
  final GlobalKey? repaintKey;

  static const _typeColors = <String, Color>{
    'Install': Color(0xFF4CAF50),
    'Repair': Color(0xFFFF9800),
    'Upgrade': Color(0xFF2196F3),
    'Replace': Color(0xFF9C27B0),
    'Other': Color(0xFF607D8B),
    'Unspecified': Color(0xFFBDBDBD),
  };

  @override
  ConsumerState<RequestTypeChart> createState() => _RequestTypeChartState();
}

class _RequestTypeChartState extends ConsumerState<RequestTypeChart> {
  int _touchedIndex = -1;

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

    return asyncData.when(
      loading: () => ReportCardWrapper(
        title: 'Request Type Distribution',
        isLoading: true,
        height: 220,
        repaintBoundaryKey: widget.repaintKey,
        child: const SizedBox.shrink(),
      ),
      error: (e, _) => ReportCardWrapper(
        title: 'Request Type Distribution',
        error: e.toString(),
        repaintBoundaryKey: widget.repaintKey,
        child: const SizedBox.shrink(),
      ),
      data: (data) => _build(context, data),
    );
  }

  Widget _build(BuildContext context, List<NamedCount> data) {
    if (data.isEmpty) {
      return ReportCardWrapper(
        title: 'Request Type Distribution',
        repaintBoundaryKey: widget.repaintKey,
        child: const SizedBox(
          height: 200,
          child: Center(child: Text('No data for selected period')),
        ),
      );
    }

    final total = data.fold<int>(0, (s, e) => s + e.count);
    final colorScheme = Theme.of(context).colorScheme;
    final fallbackColors = [
      colorScheme.primary,
      colorScheme.secondary,
      colorScheme.tertiary,
      colorScheme.error,
      colorScheme.outline,
    ];

    Color colorFor(int idx, String name) =>
        RequestTypeChart._typeColors[name] ??
        fallbackColors[idx % fallbackColors.length];

    return ReportCardWrapper(
      title: 'Request Type Distribution',
      repaintBoundaryKey: widget.repaintKey,
      height: 220,
      child: Row(
        children: [
          Expanded(
            child: PieChart(
              PieChartData(
                pieTouchData: PieTouchData(
                  touchCallback:
                      (FlTouchEvent event, pieTouchResponse) {
                    setState(() {
                      if (!event.isInterestedForInteractions ||
                          pieTouchResponse == null ||
                          pieTouchResponse.touchedSection == null) {
                        _touchedIndex = -1;
                        return;
                      }
                      _touchedIndex = pieTouchResponse
                          .touchedSection!
                          .touchedSectionIndex;
                    });
                  },
                ),
                sectionsSpace: 2,
                centerSpaceRadius: 40,
                sections: data.asMap().entries.map((entry) {
                  final i = entry.key;
                  final e = entry.value;
                  final isTouched = i == _touchedIndex;
                  return PieChartSectionData(
                    value: e.count.toDouble(),
                    title: '',
                    radius: isTouched ? 60 : 50,
                    color: colorFor(i, e.name),
                    borderSide: isTouched
                        ? const BorderSide(color: Colors.white, width: 2)
                        : BorderSide.none,
                  );
                }).toList(),
              ),
            ),
          ),
          const SizedBox(width: 12),
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: data.asMap().entries.map((entry) {
              final i = entry.key;
              final e = entry.value;
              final isTouched = i == _touchedIndex;
              return _HoverLegendItem(
                color: colorFor(i, e.name),
                label: e.name,
                value:
                    '${e.count} (${(e.count / total * 100).toStringAsFixed(0)}%)',
                isTouched: isTouched,
              );
            }).toList(),
          ),
        ],
      ),
    );
  }
}

/// Donut chart  distribution of tasks by request category with hover animation.
class RequestCategoryChart extends ConsumerStatefulWidget {
  const RequestCategoryChart({super.key, this.repaintKey});
  final GlobalKey? repaintKey;

  static const _catColors = <String, Color>{
    'Software': Color(0xFF42A5F5),
    'Hardware': Color(0xFFEF5350),
    'Network': Color(0xFF66BB6A),
    'Unspecified': Color(0xFFBDBDBD),
  };

  @override
  ConsumerState<RequestCategoryChart> createState() =>
      _RequestCategoryChartState();
}

class _RequestCategoryChartState extends ConsumerState<RequestCategoryChart> {
  int _touchedIndex = -1;

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

    return asyncData.when(
      loading: () => ReportCardWrapper(
        title: 'Request Category Distribution',
        isLoading: true,
        height: 220,
        repaintBoundaryKey: widget.repaintKey,
        child: const SizedBox.shrink(),
      ),
      error: (e, _) => ReportCardWrapper(
        title: 'Request Category Distribution',
        error: e.toString(),
        repaintBoundaryKey: widget.repaintKey,
        child: const SizedBox.shrink(),
      ),
      data: (data) => _build(context, data),
    );
  }

  Widget _build(BuildContext context, List<NamedCount> data) {
    if (data.isEmpty) {
      return ReportCardWrapper(
        title: 'Request Category Distribution',
        repaintBoundaryKey: widget.repaintKey,
        child: const SizedBox(
          height: 200,
          child: Center(child: Text('No data for selected period')),
        ),
      );
    }

    final total = data.fold<int>(0, (s, e) => s + e.count);
    final colorScheme = Theme.of(context).colorScheme;
    final fallbackColors = [
      colorScheme.primary,
      colorScheme.secondary,
      colorScheme.tertiary,
    ];

    Color colorFor(int idx, String name) =>
        RequestCategoryChart._catColors[name] ??
        fallbackColors[idx % fallbackColors.length];

    return ReportCardWrapper(
      title: 'Request Category Distribution',
      repaintBoundaryKey: widget.repaintKey,
      height: 220,
      child: Row(
        children: [
          Expanded(
            child: PieChart(
              PieChartData(
                pieTouchData: PieTouchData(
                  touchCallback:
                      (FlTouchEvent event, pieTouchResponse) {
                    setState(() {
                      if (!event.isInterestedForInteractions ||
                          pieTouchResponse == null ||
                          pieTouchResponse.touchedSection == null) {
                        _touchedIndex = -1;
                        return;
                      }
                      _touchedIndex = pieTouchResponse
                          .touchedSection!
                          .touchedSectionIndex;
                    });
                  },
                ),
                sectionsSpace: 2,
                centerSpaceRadius: 40,
                sections: data.asMap().entries.map((entry) {
                  final i = entry.key;
                  final e = entry.value;
                  final isTouched = i == _touchedIndex;
                  return PieChartSectionData(
                    value: e.count.toDouble(),
                    title: '',
                    radius: isTouched ? 60 : 50,
                    color: colorFor(i, e.name),
                    borderSide: isTouched
                        ? const BorderSide(color: Colors.white, width: 2)
                        : BorderSide.none,
                  );
                }).toList(),
              ),
            ),
          ),
          const SizedBox(width: 12),
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: data.asMap().entries.map((entry) {
              final i = entry.key;
              final e = entry.value;
              final isTouched = i == _touchedIndex;
              return _HoverLegendItem(
                color: colorFor(i, e.name),
                label: e.name,
                value:
                    '${e.count} (${(e.count / total * 100).toStringAsFixed(0)}%)',
                isTouched: isTouched,
              );
            }).toList(),
          ),
        ],
      ),
    );
  }
}

//  Shared helpers 

class _HoverLegendItem extends StatelessWidget {
  const _HoverLegendItem({
    required this.color,
    required this.label,
    required this.value,
    this.isTouched = false,
  });
  final Color color;
  final String label;
  final String value;
  final bool isTouched;

  @override
  Widget build(BuildContext context) {
    final text = Theme.of(context).textTheme;
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 2),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          AnimatedContainer(
            duration: const Duration(milliseconds: 200),
            width: isTouched ? 14 : 10,
            height: isTouched ? 14 : 10,
            decoration: BoxDecoration(color: color, shape: BoxShape.circle),
          ),
          const SizedBox(width: 6),
          AnimatedDefaultTextStyle(
            duration: const Duration(milliseconds: 200),
            style: (text.bodySmall ?? const TextStyle()).copyWith(
              fontWeight: isTouched ? FontWeight.bold : FontWeight.normal,
            ),
            child: Text(label),
          ),
          const SizedBox(width: 4),
          AnimatedDefaultTextStyle(
            duration: const Duration(milliseconds: 200),
            style: (text.labelSmall ?? const TextStyle()).copyWith(
              fontWeight: isTouched ? FontWeight.bold : FontWeight.normal,
            ),
            child: Text(value),
          ),
        ],
      ),
    );
  }
}
