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

import '../../../../common/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/analytic/analytic.dart';

class FinanceCashFlow extends StatelessWidget {
  final List<ProfitLossDailyData> dailyData;

  const FinanceCashFlow({super.key, required this.dailyData});

  @override
  Widget build(BuildContext context) {
    // Calculate totals from daily data
    final totalCashIn = _calculateTotalCashIn();
    final totalCashOut = _calculateTotalCashOut();
    final netFlow = totalCashIn - totalCashOut;

    return Container(
      margin: const EdgeInsets.all(16),
      padding: const EdgeInsets.all(20),
      decoration: BoxDecoration(
        color: AppColor.white,
        borderRadius: BorderRadius.circular(16),
        boxShadow: [
          BoxShadow(
            color: AppColor.textLight.withOpacity(0.1),
            spreadRadius: 1,
            blurRadius: 8,
            offset: const Offset(0, 2),
          ),
        ],
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Row(
                children: [
                  Container(
                    padding: const EdgeInsets.all(8),
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        colors: AppColor.primaryGradient,
                      ),
                      borderRadius: BorderRadius.circular(8),
                    ),
                    child: const Icon(
                      LineIcons.areaChart,
                      color: AppColor.white,
                      size: 20,
                    ),
                  ),
                  const SizedBox(width: 12),
                  Text(
                    context.lang.cash_flow_analysis,
                    style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold),
                  ),
                ],
              ),
              IconButton(
                onPressed: () {},
                icon: const Icon(
                  LineIcons.alternateExternalLink,
                  color: AppColor.primary,
                ),
              ),
            ],
          ),
          const SizedBox(height: 20),

          // Cash Flow Indicators
          Row(
            children: [
              Expanded(
                child: _buildCashFlowIndicator(
                  context.lang.cash_in,
                  _formatCurrency(totalCashIn),
                  LineIcons.arrowUp,
                  AppColor.success,
                ),
              ),
              const SizedBox(width: 16),
              Expanded(
                child: _buildCashFlowIndicator(
                  context.lang.cash_out,
                  _formatCurrency(totalCashOut),
                  LineIcons.arrowDown,
                  AppColor.error,
                ),
              ),
              const SizedBox(width: 16),
              Expanded(
                child: _buildCashFlowIndicator(
                  context.lang.net_flow,
                  _formatCurrency(netFlow),
                  LineIcons.equals,
                  AppColor.info,
                ),
              ),
            ],
          ),
          const SizedBox(height: 20),

          // FL Chart Implementation
          Container(
            height: 200,
            padding: const EdgeInsets.all(16),
            decoration: BoxDecoration(
              color: AppColor.background,
              borderRadius: BorderRadius.circular(12),
              border: Border.all(color: AppColor.borderLight),
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  context.lang.cash_flow_chart(dailyData.length),
                  style: AppStyle.sm.copyWith(
                    color: AppColor.textSecondary,
                    fontWeight: FontWeight.w600,
                  ),
                ),
                const SizedBox(height: 16),
                Expanded(
                  child: dailyData.isEmpty
                      ? _buildEmptyChart()
                      : LineChart(_buildLineChartData()),
                ),
                const SizedBox(height: 12),
                // Legend
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    _buildChartLegend(context.lang.cash_in, AppColor.success),
                    const SizedBox(width: 20),
                    _buildChartLegend(context.lang.cash_out, AppColor.error),
                    const SizedBox(width: 20),
                    _buildChartLegend(context.lang.net_flow, AppColor.info),
                  ],
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  LineChartData _buildLineChartData() {
    final maxValue = _getMaxChartValue();
    final minValue = _getMinChartValue();

    return LineChartData(
      gridData: FlGridData(
        show: true,
        drawVerticalLine: false,
        horizontalInterval: (maxValue / 5).roundToDouble(),
        getDrawingHorizontalLine: (value) {
          return FlLine(color: AppColor.borderLight, strokeWidth: 1);
        },
      ),
      titlesData: FlTitlesData(
        show: true,
        rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
        topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
        bottomTitles: AxisTitles(
          sideTitles: SideTitles(
            showTitles: true,
            reservedSize: 30,
            interval: 1,
            getTitlesWidget: (double value, TitleMeta meta) {
              final index = value.toInt();
              if (index >= 0 && index < dailyData.length) {
                final date = DateTime.parse(dailyData[index].date);
                final dayName = _getDayName(date.weekday);
                return SideTitleWidget(
                  meta: meta,
                  child: Text(
                    dayName,
                    style: const TextStyle(
                      color: AppColor.textSecondary,
                      fontWeight: FontWeight.w500,
                      fontSize: 10,
                    ),
                  ),
                );
              }
              return SideTitleWidget(meta: meta, child: Text(''));
            },
          ),
        ),
        leftTitles: AxisTitles(
          sideTitles: SideTitles(
            showTitles: true,
            interval: (maxValue / 3).roundToDouble(),
            reservedSize: 42,
            getTitlesWidget: (double value, TitleMeta meta) {
              return Text(
                _formatChartValue(value),
                style: const TextStyle(
                  color: AppColor.textSecondary,
                  fontWeight: FontWeight.w500,
                  fontSize: 10,
                ),
                textAlign: TextAlign.left,
              );
            },
          ),
        ),
      ),
      borderData: FlBorderData(
        show: true,
        border: Border.all(color: AppColor.borderLight),
      ),
      minX: 0,
      maxX: (dailyData.length - 1).toDouble(),
      minY: minValue,
      maxY: maxValue,
      lineBarsData: [
        // Cash In Line (Revenue)
        LineChartBarData(
          spots: _buildCashInSpots(),
          isCurved: true,
          gradient: LinearGradient(
            colors: [AppColor.success.withOpacity(0.8), AppColor.success],
          ),
          barWidth: 3,
          isStrokeCapRound: true,
          dotData: FlDotData(
            show: true,
            getDotPainter: (spot, percent, barData, index) {
              return FlDotCirclePainter(
                radius: 4,
                color: AppColor.success,
                strokeWidth: 2,
                strokeColor: AppColor.white,
              );
            },
          ),
          belowBarData: BarAreaData(
            show: true,
            gradient: LinearGradient(
              colors: [
                AppColor.success.withOpacity(0.1),
                AppColor.success.withOpacity(0.0),
              ],
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
            ),
          ),
        ),
        // Cash Out Line (Total Cost)
        LineChartBarData(
          spots: _buildCashOutSpots(),
          isCurved: true,
          gradient: LinearGradient(
            colors: [AppColor.error.withOpacity(0.8), AppColor.error],
          ),
          barWidth: 3,
          isStrokeCapRound: true,
          dotData: FlDotData(
            show: true,
            getDotPainter: (spot, percent, barData, index) {
              return FlDotCirclePainter(
                radius: 4,
                color: AppColor.error,
                strokeWidth: 2,
                strokeColor: AppColor.white,
              );
            },
          ),
        ),
        // Net Flow Line (Net Profit)
        LineChartBarData(
          spots: _buildNetFlowSpots(),
          isCurved: true,
          gradient: LinearGradient(
            colors: [AppColor.info.withOpacity(0.8), AppColor.info],
          ),
          barWidth: 3,
          isStrokeCapRound: true,
          dotData: FlDotData(
            show: true,
            getDotPainter: (spot, percent, barData, index) {
              return FlDotCirclePainter(
                radius: 4,
                color: AppColor.info,
                strokeWidth: 2,
                strokeColor: AppColor.white,
              );
            },
          ),
        ),
      ],
    );
  }

  Widget _buildEmptyChart() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(
            LineIcons.lineChart,
            size: 48,
            color: AppColor.textSecondary.withOpacity(0.3),
          ),
          const SizedBox(height: 12),
          Text(
            'Tidak ada data untuk ditampilkan',
            style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
          ),
        ],
      ),
    );
  }

  // Helper methods for calculating data
  int _calculateTotalCashIn() {
    return dailyData.fold(0, (sum, data) => sum + data.revenue);
  }

  int _calculateTotalCashOut() {
    return dailyData.fold(
      0,
      (sum, data) => sum + data.cost + data.tax + data.discount,
    );
  }

  double _getMaxChartValue() {
    if (dailyData.isEmpty) return 30000000;

    final maxRevenue = dailyData
        .map((e) => e.revenue)
        .reduce((a, b) => a > b ? a : b);
    final maxCost = dailyData
        .map((e) => e.cost + e.tax + e.discount)
        .reduce((a, b) => a > b ? a : b);
    final maxValue = maxRevenue > maxCost ? maxRevenue : maxCost;

    return (maxValue * 1.2).toDouble(); // Add 20% padding
  }

  double _getMinChartValue() {
    if (dailyData.isEmpty) return -5000000;

    final minNetProfit = dailyData
        .map((e) => e.netProfit)
        .reduce((a, b) => a < b ? a : b);
    return minNetProfit < 0 ? (minNetProfit * 1.2).toDouble() : 0;
  }

  List<FlSpot> _buildCashInSpots() {
    return dailyData.asMap().entries.map((entry) {
      return FlSpot(entry.key.toDouble(), entry.value.revenue.toDouble());
    }).toList();
  }

  List<FlSpot> _buildCashOutSpots() {
    return dailyData.asMap().entries.map((entry) {
      final totalCost =
          entry.value.cost + entry.value.tax + entry.value.discount;
      return FlSpot(entry.key.toDouble(), totalCost.toDouble());
    }).toList();
  }

  List<FlSpot> _buildNetFlowSpots() {
    return dailyData.asMap().entries.map((entry) {
      return FlSpot(entry.key.toDouble(), entry.value.netProfit.toDouble());
    }).toList();
  }

  String _getDayName(int weekday) {
    switch (weekday) {
      case 1:
        return 'Sen';
      case 2:
        return 'Sel';
      case 3:
        return 'Rab';
      case 4:
        return 'Kam';
      case 5:
        return 'Jum';
      case 6:
        return 'Sab';
      case 7:
        return 'Min';
      default:
        return '';
    }
  }

  String _formatChartValue(double value) {
    if (value.abs() >= 1000000) {
      return '${(value / 1000000).toStringAsFixed(0)}M';
    } else if (value.abs() >= 1000) {
      return '${(value / 1000).toStringAsFixed(0)}K';
    } else {
      return value.toStringAsFixed(0);
    }
  }

  String _formatCurrency(int amount) {
    if (amount.abs() >= 1000000000) {
      return 'Rp ${(amount / 1000000000).toStringAsFixed(1)}B';
    } else if (amount.abs() >= 1000000) {
      return 'Rp ${(amount / 1000000).toStringAsFixed(1)}M';
    } else if (amount.abs() >= 1000) {
      return 'Rp ${(amount / 1000).toStringAsFixed(1)}K';
    } else {
      return 'Rp ${NumberFormat('#,###', 'id_ID').format(amount)}';
    }
  }

  Widget _buildChartLegend(String label, Color color) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          width: 12,
          height: 12,
          decoration: BoxDecoration(color: color, shape: BoxShape.circle),
        ),
        const SizedBox(width: 6),
        Text(
          label,
          style: AppStyle.xs.copyWith(
            color: AppColor.textSecondary,
            fontWeight: FontWeight.w500,
          ),
        ),
      ],
    );
  }

  Widget _buildCashFlowIndicator(
    String label,
    String amount,
    IconData icon,
    Color color,
  ) {
    return Container(
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: color.withOpacity(0.05),
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: color.withOpacity(0.2)),
      ),
      child: Column(
        children: [
          Icon(icon, color: color, size: 20),
          const SizedBox(height: 8),
          Text(
            label,
            style: AppStyle.xs.copyWith(color: AppColor.textSecondary),
          ),
          const SizedBox(height: 4),
          Text(
            amount,
            style: AppStyle.md.copyWith(
              fontWeight: FontWeight.bold,
              color: color,
            ),
          ),
        ],
      ),
    );
  }
}
