import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
import 'package:marco/controller/dashboard/dashboard_controller.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/helpers/widgets/my_custom_skeleton.dart';

class AttendanceDashboardChart extends StatelessWidget {
  final DashboardController controller = Get.find<DashboardController>();

  AttendanceDashboardChart({super.key});

  List<Map<String, dynamic>> get filteredData {
    final now = DateTime.now();
    final daysBack = controller.rangeDays;
    return controller.roleWiseData.where((entry) {
      final date = DateTime.parse(entry['date']);
      return date.isAfter(now.subtract(Duration(days: daysBack))) &&
          !date.isAfter(now);
    }).toList();
  }

  List<DateTime> get filteredDateTimes {
    final uniqueDates = filteredData
        .map((e) => DateTime.parse(e['date'] as String))
        .toSet()
        .toList()
      ..sort();
    return uniqueDates;
  }

  List<String> get filteredDates =>
      filteredDateTimes.map((d) => DateFormat('d MMMM').format(d)).toList();

  List<String> get filteredRoles =>
      filteredData.map((e) => e['role'] as String).toSet().toList();

  List<String> get rolesWithData => filteredRoles.where((role) {
        return filteredData.any(
            (entry) => entry['role'] == role && (entry['present'] ?? 0) > 0);
      }).toList();

  final Map<String, Color> _roleColorMap = {};
  final List<Color> flatColors = [
    const Color(0xFFE57373),
    const Color(0xFF64B5F6),
    const Color(0xFF81C784),
    const Color(0xFFFFB74D),
    const Color(0xFFBA68C8),
    const Color(0xFFFF8A65),
    const Color(0xFF4DB6AC),
    const Color(0xFFA1887F),
    const Color(0xFFDCE775),
    const Color(0xFF9575CD),
  ];

  Color _getRoleColor(String role) {
    if (_roleColorMap.containsKey(role)) return _roleColorMap[role]!;
    final index = _roleColorMap.length % flatColors.length;
    final color = flatColors[index];
    _roleColorMap[role] = color;
    return color;
  }

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      final isChartView = controller.isChartView.value;
      final selectedRange = controller.selectedRange.value;
      final isLoading = controller.isLoading.value;

      return Container(
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            colors: [Color(0xfff0f4f8), Color(0xffe2ebf0)],
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
          ),
        ),
        child: Card(
          color: Colors.white,
          elevation: 6,
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
          shadowColor: Colors.black12,
          child: Padding(
            padding: const EdgeInsets.all(10),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                _buildHeader(selectedRange, isChartView),
                const SizedBox(height: 12),
                AnimatedSwitcher(
                  duration: const Duration(milliseconds: 300),
                  child: isLoading
                      ? SkeletonLoaders.buildLoadingSkeleton()
                      : filteredData.isEmpty
                          ? _buildNoDataMessage()
                          : isChartView
                              ? _buildChart()
                              : _buildTable(),
                ),
              ],
            ),
          ),
        ),
      );
    });
  }

  Widget _buildHeader(String selectedRange, bool isChartView) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
      child: Row(
        children: [
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                MyText.bodyMedium('Attendance Overview', fontWeight: 600),
                MyText.bodySmall('Role-wise present count', color: Colors.grey),
              ],
            ),
          ),
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4),
            decoration: BoxDecoration(
              color: Colors.grey.shade100,
              borderRadius: BorderRadius.circular(8),
              border: Border.all(color: Colors.grey.shade300),
            ),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                PopupMenuButton<String>(
                  padding: EdgeInsets.zero,
                  tooltip: 'Select Range',
                  onSelected: (value) => controller.selectedRange.value = value,
                  itemBuilder: (context) => const [
                    PopupMenuItem(value: '7D', child: Text('Last 7 Days')),
                    PopupMenuItem(value: '15D', child: Text('Last 15 Days')),
                    PopupMenuItem(value: '30D', child: Text('Last 30 Days')),
                  ],
                  child: Row(
                    children: [
                      const Icon(Icons.calendar_today_outlined, size: 18),
                      const SizedBox(width: 4),
                      MyText.labelSmall(selectedRange),
                    ],
                  ),
                ),
                const SizedBox(width: 8),
                IconButton(
                  icon: Icon(
                    Icons.bar_chart_rounded,
                    size: 20,
                    color: isChartView ? Colors.blueAccent : Colors.grey,
                  ),
                  visualDensity: VisualDensity(horizontal: -4, vertical: -4),
                  constraints: const BoxConstraints(),
                  padding: EdgeInsets.zero,
                  onPressed: () => controller.isChartView.value = true,
                  tooltip: 'Chart View',
                ),
                IconButton(
                  icon: Icon(
                    Icons.table_chart,
                    size: 20,
                    color: !isChartView ? Colors.blueAccent : Colors.grey,
                  ),
                  visualDensity: VisualDensity(horizontal: -4, vertical: -4),
                  constraints: const BoxConstraints(),
                  padding: EdgeInsets.zero,
                  onPressed: () => controller.isChartView.value = false,
                  tooltip: 'Table View',
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildChart() {
    final formattedDateMap = {
      for (var e in filteredData)
        '${e['role']}_${DateFormat('d MMMM').format(DateTime.parse(e['date']))}':
            e['present']
    };

    return SizedBox(
      height: 360,
      child: SfCartesianChart(
        tooltipBehavior: TooltipBehavior(
          enable: true,
          shared: true,
          activationMode: ActivationMode.singleTap,
          tooltipPosition: TooltipPosition.pointer,
        ),
        legend: const Legend(
          isVisible: true,
          position: LegendPosition.bottom,
          overflowMode: LegendItemOverflowMode.wrap,
        ),
        primaryXAxis: CategoryAxis(
          labelRotation: 45,
          majorGridLines: const MajorGridLines(width: 0),
        ),
        primaryYAxis: NumericAxis(
          minimum: 0,
          interval: 1,
          majorGridLines: const MajorGridLines(width: 0),
        ),
        series: rolesWithData.map((role) {
          final data = filteredDates.map((formattedDate) {
            final key = '${role}_$formattedDate';
            return {
              'date': formattedDate,
              'present': formattedDateMap[key] ?? 0
            };
          }).toList();

          return StackedColumnSeries<Map<String, dynamic>, String>(
            dataSource: data,
            xValueMapper: (d, _) => d['date'],
            yValueMapper: (d, _) => d['present'],
            name: role,
            legendIconType: LegendIconType.circle,
            dataLabelSettings: const DataLabelSettings(isVisible: true),
            dataLabelMapper: (d, _) =>
                d['present'] == 0 ? '' : d['present'].toString(),
            color: _getRoleColor(role),
          );
        }).toList(),
      ),
    );
  }

  Widget _buildNoDataMessage() {
    return SizedBox(
      height: 200,
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(Icons.info_outline, color: Colors.grey.shade500, size: 48),
            const SizedBox(height: 12),
            MyText.bodyMedium(
              'No attendance data available for the selected range or project.',
              textAlign: TextAlign.center,
              color: Colors.grey.shade600,
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildTable() {
    final formattedDateMap = {
      for (var e in filteredData)
        '${e['role']}_${DateFormat('d MMMM').format(DateTime.parse(e['date']))}':
            e['present']
    };

    return Container(
      decoration: BoxDecoration(
        border: Border.all(color: Colors.grey.shade300),
        borderRadius: BorderRadius.circular(12),
      ),
      child: SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: DataTable(
          columnSpacing: 28,
          headingRowHeight: 42,
          headingRowColor:
              WidgetStateProperty.all(Colors.blueAccent.withOpacity(0.1)),
          headingTextStyle: const TextStyle(
              fontWeight: FontWeight.bold, color: Colors.black87),
          columns: [
            DataColumn(label: MyText.labelSmall('Role', fontWeight: 600)),
            ...filteredDates.map((date) => DataColumn(
                  label: MyText.labelSmall(date, fontWeight: 600),
                )),
          ],
          rows: filteredRoles.map((role) {
            return DataRow(
              cells: [
                DataCell(Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 4),
                  child: _rolePill(role),
                )),
                ...filteredDates.map((date) {
                  final key = '${role}_$date';
                  return DataCell(Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 4),
                    child: MyText.labelSmall('${formattedDateMap[key] ?? 0}'),
                  ));
                }),
              ],
            );
          }).toList(),
        ),
      ),
    );
  }

  Widget _rolePill(String role) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
      decoration: BoxDecoration(
        color: _getRoleColor(role).withOpacity(0.15),
        borderRadius: BorderRadius.circular(8),
      ),
      child: MyText.labelSmall(role, fontWeight: 500),
    );
  }
}
