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

import '../../../core/app_theme.dart';
import '../providers/monitoring_provider.dart';

class MonitoringChart extends ConsumerWidget {
  const MonitoringChart({super.key});

  String _getRangeLabel(ChartRange range, List<DailyAverage> dailyData) {
    if (dailyData.isEmpty) return '-';
    final first = dailyData.first.date;
    final months = ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Ags', 'Sep', 'Okt', 'Nov', 'Des'];
    
    if (range == ChartRange.daily) {
      return '${first.day} ${months[first.month - 1]} ${first.year}';
    } else {
      return '${months[first.month - 1]} ${first.year}';
    }
  }

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    ref.listen<int>(chartOffsetProvider, (previous, next) {
      if (next != previous) {
        final currentRange = ref.read(chartRangeProvider);
        ref.read(monitoringProvider.notifier).fetchHistoryForOffset(
          range: currentRange,
          offset: next,
        );
      }
    });

    ref.listen<ChartRange>(chartRangeProvider, (previous, next) {
      if (next != previous) {
        Future.microtask(() {
          ref.read(chartOffsetProvider.notifier).state = 0;
          if (ref.read(chartOffsetProvider) == 0) {
            ref.read(monitoringProvider.notifier).fetchHistoryForOffset(
              range: next,
              offset: 0,
            );
          }
        });
      }
    });

    final range     = ref.watch(chartRangeProvider);
    final type      = ref.watch(chartTypeProvider);
    final offset    = ref.watch(chartOffsetProvider);
    final dailyData = ref.watch(dailyAverageProvider);

    final values = dailyData
        .map((d) => type == ChartType.suhu ? d.suhu : d.kelembapan)
        .whereType<double>()
        .toList();

    final maxY = values.isEmpty
        ? 100.0
        : (values.reduce((a, b) => a > b ? a : b) + 15).ceilToDouble();

    final barColor =
        type == ChartType.suhu ? Colors.deepOrange : Colors.teal;

    Widget chart = BarChart(
      BarChartData(
        alignment: BarChartAlignment.spaceBetween,
        maxY: maxY,
        gridData: FlGridData(
          show: true,
          drawVerticalLine: false,
          horizontalInterval: (maxY / 4).ceilToDouble(),
          getDrawingHorizontalLine: (_) => FlLine(
            color: Colors.grey.withValues(alpha: 0.1),
            strokeWidth: 1,
          ),
        ),
        borderData: FlBorderData(show: false),
        barTouchData: BarTouchData(
          enabled: false, // Matikan interaksi sentuh karena angka sudah muncul di atas
          touchTooltipData: BarTouchTooltipData(
            tooltipBgColor: Colors.transparent,
            tooltipPadding: const EdgeInsets.only(bottom: 0),
            tooltipMargin: 2,
            getTooltipItem: (group, groupIndex, rod, rodIndex) {
              if (rod.toY == 0) return null; // Sembunyikan untuk batang kosong
              final val = rod.toY.round();
              return BarTooltipItem(
                '$val',
                TextStyle(
                  color: barColor,
                  fontWeight: FontWeight.bold,
                  fontSize: 11,
                ),
              );
            },
          ),
        ),
        titlesData: FlTitlesData(
          topTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
          rightTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
          leftTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
          bottomTitles: AxisTitles(
            sideTitles: SideTitles(
              showTitles: true,
              reservedSize: 36,
              getTitlesWidget: (value, _) {
                final i = value.toInt();
                if (i < 0 || i >= dailyData.length) {
                  return const SizedBox();
                }
                final date = dailyData[i].date;
                final label = range == ChartRange.daily
                    ? '${date.hour.toString().padLeft(2, '0')}:00'
                    : date.day.toString();
                return Padding(
                  padding: const EdgeInsets.only(top: 6),
                  child: Text(
                    label,
                    style: const TextStyle(
                        fontSize: 11, color: Colors.grey),
                  ),
                );
              },
            ),
          ),
        ),
        barGroups: List.generate(dailyData.length, (i) {
          final v = type == ChartType.suhu ? dailyData[i].suhu : dailyData[i].kelembapan;
          final val = v != null ? v.roundToDouble() : 0.0;
          return BarChartGroupData(
            x: i,
            showingTooltipIndicators: v != null ? [0] : [], // Selalu tampilkan angka jika ada data
            barRods: [
              BarChartRodData(
                toY: val,
                width: range == ChartRange.daily ? 16 : 12,
                borderRadius: BorderRadius.circular(6),
                color: v == null ? Colors.grey.shade200 : barColor,
                backDrawRodData: BackgroundBarChartRodData(
                  show: true,
                  toY: maxY,
                  color: Colors.grey.shade100, // Background bar semu
                ),
              ),
            ],
          );
        }),
      ),
    );

    if (range == ChartRange.monthly || range == ChartRange.daily) {
      chart = SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: SizedBox(
          width: dailyData.length * (range == ChartRange.daily ? 40.0 : 40.0),
          child: chart,
        ),
      );
    }

    return Container(
      padding: const EdgeInsets.all(20),
      decoration: AppTheme.cardDecoration(radius: 20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              const Text(
                'Monitoring Chart',
                style: TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.bold,
                  color: AppTheme.textPrimary,
                ),
              ),
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
                decoration: BoxDecoration(
                  color: barColor.withOpacity(0.1),
                  borderRadius: BorderRadius.circular(20),
                ),
                child: Text(
                  type == ChartType.suhu ? '°C (Suhu)' : '% (Kelembapan)',
                  style: TextStyle(
                      fontSize: 12, color: barColor, fontWeight: FontWeight.bold),
                ),
              ),
            ],
          ),
          const SizedBox(height: 16),
          // Navigasi Waktu (Kalender)
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              IconButton(
                onPressed: () => ref.read(chartOffsetProvider.notifier).state--,
                icon: const Icon(Icons.chevron_left, color: AppTheme.textSecondary),
                padding: EdgeInsets.zero,
                constraints: const BoxConstraints(),
              ),
              Text(
                _getRangeLabel(range, dailyData),
                style: const TextStyle(
                  fontSize: 14,
                  fontWeight: FontWeight.w600,
                  color: AppTheme.textPrimary,
                ),
              ),
              IconButton(
                onPressed: offset < 0 
                    ? () => ref.read(chartOffsetProvider.notifier).state++ 
                    : null, // Disable jika sudah di minggu/bulan ini
                icon: Icon(
                  Icons.chevron_right, 
                  color: offset < 0 ? AppTheme.textSecondary : Colors.grey.shade300
                ),
                padding: EdgeInsets.zero,
                constraints: const BoxConstraints(),
              ),
            ],
          ),
          const SizedBox(height: 30), // Beri jarak extra untuk angka di atas bar
          SizedBox(height: 220, child: chart),
        ],
      ),
    );
  }
}
