import 'package:calendar_date_picker2/calendar_date_picker2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';
import 'package:niogu_app/core/widgets/custom_error_screen.dart';
import 'package:niogu_app/core/providers/app_provider.dart';
import 'package:niogu_app/core/router/app_route.dart';
import 'package:niogu_app/core/utils/currency_format.dart';
import 'package:niogu_app/core/enums/report_type.dart';
import 'package:niogu_app/core/enums/transaction_reference_type.dart';
import 'package:niogu_app/core/enums/user_role.dart';
import 'package:niogu_app/core/widgets/custom_empty_screen.dart';
import 'package:niogu_app/features/outlets/presentation/providers/outlet_provider.dart';
import 'package:niogu_app/features/report/presentation/providers/report_provider.dart';
import 'package:niogu_app/features/report/presentation/widgets/filtered_date_range.dart';
import 'package:niogu_app/features/report/presentation/widgets/filtered_outlet.dart';
import 'package:niogu_app/features/report/presentation/widgets/filtered_type.dart';
import 'package:niogu_app/features/report/presentation/widgets/fixed_outlet.dart';
import 'package:niogu_app/features/report/presentation/widgets/report_header.dart';
import 'package:niogu_app/features/report/transaction/domain/entities/transaction_report.dart';
import 'package:niogu_app/features/report/transaction/presentation/providers/transaction_report_provider.dart';
import 'package:niogu_app/features/report/transaction/presentation/widgets/sliver_header_delegate.dart';
import 'package:niogu_app/features/report/transaction/presentation/widgets/transaction_item.dart';
import 'package:niogu_app/features/report/transaction/presentation/widgets/transaction_report_shimmer.dart';
import 'package:niogu_app/features/stock_in/domain/entities/stock_in_transfer.dart';
import 'package:sizer/sizer.dart';
import 'package:niogu_app/core/constants/app_color.dart';
import 'package:niogu_app/core/constants/app_font_size.dart';

class TransactionReportScreen extends ConsumerStatefulWidget {
  const TransactionReportScreen({super.key});

  @override
  ConsumerState<TransactionReportScreen> createState() =>
      _TransactionReportScreenState();
}

class _TransactionReportScreenState
    extends ConsumerState<TransactionReportScreen>
    with AutomaticKeepAliveClientMixin {
  String? _selectedOutlet;

  String _selectedType = "Semua Transaksi";

  DateTimeRange? _selectedDateRange;

  List<DateTime?> _initialValue = [
    DateTime.now().subtract(const Duration(days: 7)),
    DateTime.now(),
  ];

  @override
  // TODO: implement wantKeepAlive
  bool get wantKeepAlive => true;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((_) {
      final currentUserRole = ref.read(currentUserRoleProvider);

      if (currentUserRole == UserRole.admin) {
        final currentOutletId = ref.read(currentOutletIdProvider);
        ref
                .read(filteredByOutletProvider(ReportType.transaction).notifier)
                .state =
            currentOutletId;
      }
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  bool _isSameDay(DateTime d1, DateTime d2) {
    return d1.year == d2.year && d1.month == d2.month && d1.day == d2.day;
  }

  String _formatGroupDate(DateTime date) {
    return DateFormat('dd MMMM yyyy').format(date);
  }

  Future<void> _showDateRangePicker() async {
    final bool isTablet = 100.w >= 600;

    List<DateTime?> tempSelectedDates = List.from(_initialValue);

    showModalBottomSheet(
      context: context,
      useRootNavigator: true,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      constraints: BoxConstraints(maxWidth: double.infinity),
      builder: (context) {
        return StatefulBuilder(
          builder: (context, setModalState) {
            return Container(
              height: 80.h,
              width: double.infinity,
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.vertical(
                  top: Radius.circular(4.5.w),
                ),
              ),
              constraints: BoxConstraints(
                maxHeight: 80.h,
                maxWidth: double.infinity,
              ),
              child: Column(
                children: [
                  SizedBox(height: 1.5.h),
                  Container(
                    width: 12.w,
                    height: 0.6.h,
                    decoration: BoxDecoration(
                      color: Colors.grey[300],
                      borderRadius: BorderRadius.circular(2.5.w),
                    ),
                  ),
                  Padding(
                    padding: EdgeInsets.symmetric(vertical: 2.h),
                    child: Text(
                      "Pilih Rentang Tanggal",
                      style: TextStyle(
                        fontSize: isTablet
                            ? AppFontSize.medium.sp
                            : AppFontSize.small.sp,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                  Divider(height: 1, color: Colors.grey[200]),

                  Expanded(
                    child: CalendarDatePicker2(
                      config: CalendarDatePicker2Config(
                        calendarType: CalendarDatePicker2Type.range,
                        selectedDayHighlightColor: AppColor.primaryColor,
                        weekdayLabels: [
                          'Min',
                          'Sen',
                          'Sel',
                          'Rab',
                          'Kam',
                          'Jum',
                          'Sab',
                        ],
                        weekdayLabelTextStyle: TextStyle(
                          color: Colors.grey[600],
                          fontWeight: FontWeight.bold,
                          fontSize: isTablet
                              ? AppFontSize.medium.sp
                              : AppFontSize.small.sp,
                        ),
                        controlsTextStyle: TextStyle(
                          color: Colors.black,
                          fontWeight: FontWeight.bold,
                          fontSize: isTablet
                              ? AppFontSize.medium.sp
                              : AppFontSize.small.sp,
                        ),
                        centerAlignModePicker: true,
                        firstDayOfWeek: 1,
                      ),
                      value: tempSelectedDates,
                      onValueChanged: (dates) {
                        setModalState(() {
                          tempSelectedDates = dates;
                        });
                      },
                    ),
                  ),

                  Container(
                    padding: EdgeInsets.all(5.w),
                    decoration: BoxDecoration(
                      color: Colors.white,
                      boxShadow: [
                        BoxShadow(
                          color: Colors.black.withOpacity(0.05),
                          blurRadius: 10,
                          offset: const Offset(0, -5),
                        ),
                      ],
                    ),
                    child: Row(
                      children: [
                        Expanded(
                          child: OutlinedButton(
                            onPressed: () {
                              _selectedDateRange = null;
                              ref
                                      .read(
                                        filteredByDateTimeProvider(
                                          ReportType.transaction,
                                        ).notifier,
                                      )
                                      .state =
                                  null;
                              context.pop();
                            },
                            style: OutlinedButton.styleFrom(
                              padding: EdgeInsets.symmetric(vertical: 1.5.h),
                              side: BorderSide(color: Colors.grey),
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(2.5.w),
                              ),
                            ),
                            child: Text(
                              "Atur Ulang",
                              style: TextStyle(
                                color: Colors.black,
                                fontWeight: FontWeight.bold,
                                fontSize: AppFontSize.medium.sp,
                              ),
                            ),
                          ),
                        ),
                        SizedBox(width: 3.w),
                        Expanded(
                          child: OutlinedButton(
                            onPressed: () => context.pop(),
                            style: OutlinedButton.styleFrom(
                              padding: EdgeInsets.symmetric(vertical: 1.5.h),
                              side: BorderSide(color: AppColor.primaryColor),
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(2.5.w),
                              ),
                            ),
                            child: Text(
                              "Batal",
                              style: TextStyle(
                                color: AppColor.primaryColor,
                                fontWeight: FontWeight.bold,
                                fontSize: AppFontSize.medium.sp,
                              ),
                            ),
                          ),
                        ),
                        SizedBox(width: 3.w),
                        Expanded(
                          child: ElevatedButton(
                            onPressed: tempSelectedDates.length < 2
                                ? null
                                : () {
                                    _initialValue = tempSelectedDates;
                                    final startDate = tempSelectedDates[0]!;

                                    final endDate = tempSelectedDates[1]!;

                                    final dateRange = DateTimeRange(
                                      start: startDate,
                                      end: endDate,
                                    );

                                    _selectedDateRange = dateRange;

                                    ref
                                            .read(
                                              filteredByDateTimeProvider(
                                                ReportType.transaction,
                                              ).notifier,
                                            )
                                            .state =
                                        dateRange;

                                    context.pop();
                                  },
                            style: ElevatedButton.styleFrom(
                              padding: EdgeInsets.symmetric(vertical: 1.5.h),
                              backgroundColor: AppColor.primaryColor,
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(2.5.w),
                              ),
                              disabledBackgroundColor: Colors.grey.shade300,
                            ),
                            child: Text(
                              "Pilih",
                              style: TextStyle(
                                color: Colors.white,
                                fontWeight: FontWeight.bold,
                                fontSize: AppFontSize.medium.sp,
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            );
          },
        );
      },
    );
  }

  void _onSelectedOutletChange(String? value) {
    _selectedOutlet = value != '0' ? value : null;
    ref.read(filteredByOutletProvider(ReportType.transaction).notifier).state =
        _selectedOutlet;
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);

    final bool isTablet = 100.w >= 600;

    final isLoggedIn = ref.watch(currentStatusLoginProvider);

    double totalIncome = 0.0;

    double totalExpense = 0.0;

    double netProfit = 0.0;

    final filteredTransactionState = ref.watch(
      filteredTransactionReportProvider,
    );

    filteredTransactionState.whenData((transactions) {
      for (final transaction in transactions) {
        if (transaction.isIncome) {
          totalIncome += transaction.amount;
        } else {
          totalExpense += transaction.amount;
        }
      }

      netProfit = totalIncome - totalExpense;
    });

    final transactionEmptyState = isLoggedIn
        ? ref.watch(transactionReportEmptyProvider)
        : TransactionReportItemEmpty.empty_database;

    final List<SourceOutlet> sourceOutlets = [
      SourceOutlet(id: "0", name: "Semua Outlet"),
    ];

    final currentUserRole = ref.watch(currentUserRoleProvider);

    final sourceOutletState = ref.watch(sourceOutletStreamProvider(true));

    final currentOutletName = ref.watch(currentOutletNameProvider);

    if (currentUserRole == UserRole.owner) {
      sourceOutletState.whenData((outlets) {
        sourceOutlets.addAll(outlets);
      });
    }

    return CustomScrollView(
      physics: const BouncingScrollPhysics(),
      slivers: [
        SliverAppBar(
          pinned: false,
          floating: true,
          snap: true,
          stretch: true,
          expandedHeight: 100.w > 800
              ? 48.h
              : isTablet
              ? 44.5.h
              : 42.h,
          backgroundColor: Colors.white,
          elevation: 0,
          flexibleSpace: FlexibleSpaceBar(
            collapseMode: CollapseMode.parallax,
            stretchModes: const [StretchMode.zoomBackground],
            background: Material(
              color: Colors.white,
              elevation: 0,
              child: Column(
                children: [
                  Padding(
                    padding: EdgeInsets.fromLTRB(5.w, 2.h, 5.w, 1.h),
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Row(
                          children: [
                            Expanded(
                              flex: 3,
                              child: currentUserRole == UserRole.owner
                                  ? FilteredOutlet(
                                      value: sourceOutletState.isLoading
                                          ? '0'
                                          : (_selectedOutlet ?? '0'),
                                      sourceOutlets: sourceOutlets,
                                      onChanged: _onSelectedOutletChange,
                                    )
                                  : FixedOutlet(
                                      value:
                                          currentOutletName ??
                                          'Tidak ada outlet',
                                    ),
                            ),

                            SizedBox(width: 3.w),

                            Expanded(
                              flex: 3,
                              child: FilteredType(
                                value: _selectedType,
                                items: [
                                  "Semua Transaksi",
                                  "Pendapatan",
                                  "Pengeluaran",
                                ],
                                onChanged: (value) {
                                  _selectedType = value!;
                                  final type = value == 'Semua Transaksi'
                                      ? null
                                      : value == 'Pendapatan'
                                      ? TransactionType.income
                                      : TransactionType.expense;
                                  ref
                                          .read(
                                            filteredByTransactionTypeProvider
                                                .notifier,
                                          )
                                          .state =
                                      type;
                                },
                              ),
                            ),
                          ],
                        ),

                        SizedBox(height: 1.5.h),

                        FilteredDateRange(
                          value: _selectedDateRange != null
                              ? "${_formatGroupDate(_selectedDateRange!.start)} - ${_formatGroupDate(_selectedDateRange!.end)}"
                              : "Filter Tanggal",
                          onTap: _showDateRangePicker,
                        ),
                      ],
                    ),
                  ),

                  Container(
                    margin: EdgeInsets.symmetric(
                      horizontal: 5.w,
                      vertical: 1.h,
                    ),
                    padding: EdgeInsets.all(5.w),
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        colors: [
                          AppColor.primaryColor,
                          AppColor.primaryColor.withOpacity(0.8),
                        ],
                        begin: Alignment.topLeft,
                        end: Alignment.bottomRight,
                      ),
                      borderRadius: BorderRadius.circular(4.w),
                      boxShadow: [
                        BoxShadow(
                          color: AppColor.primaryColor.withOpacity(0.3),
                          blurRadius: 10,
                          offset: const Offset(0, 5),
                        ),
                      ],
                    ),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          "Laba / Rugi",
                          style: TextStyle(
                            color: Colors.white70,
                            fontSize: AppFontSize.medium.sp,
                          ),
                        ),
                        SizedBox(height: 0.5.h),
                        Text(
                          CurrencyFormat.formatToIdr(netProfit, 0),
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: AppFontSize.large.sp,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                        SizedBox(height: 2.5.h),

                        Container(
                          padding: EdgeInsets.all(3.w),
                          decoration: BoxDecoration(
                            color: Colors.white.withOpacity(0.15),
                            borderRadius: BorderRadius.circular(2.5.w),
                          ),
                          child: Row(
                            children: [
                              Expanded(
                                child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    Row(
                                      children: [
                                        Icon(
                                          Icons.arrow_downward_rounded,
                                          color: Colors.greenAccent,
                                          size: 5.w,
                                        ),
                                        SizedBox(width: 1.w),
                                        Text(
                                          "Pendapatan",
                                          style: TextStyle(
                                            color: Colors.white70,
                                            fontSize: isTablet
                                                ? AppFontSize.medium.sp
                                                : AppFontSize.small.sp,
                                          ),
                                        ),
                                      ],
                                    ),
                                    SizedBox(height: 0.5.h),
                                    Text(
                                      CurrencyFormat.formatToIdr(
                                        totalIncome,
                                        0,
                                      ),
                                      style: TextStyle(
                                        color: Colors.white,
                                        fontSize: isTablet
                                            ? AppFontSize.medium.sp
                                            : AppFontSize.small.sp,
                                        fontWeight: FontWeight.w600,
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                              Container(
                                width: 1,
                                height: 4.h,
                                color: Colors.white24,
                              ), // Separator
                              SizedBox(width: 3.w),
                              // Expense
                              Expanded(
                                child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    Row(
                                      children: [
                                        Icon(
                                          Icons.arrow_upward_rounded,
                                          color: Colors.redAccent,
                                          size: 5.w,
                                        ),
                                        SizedBox(width: 1.w),
                                        Text(
                                          "Pengeluaran",
                                          style: TextStyle(
                                            color: Colors.white70,
                                            fontSize: isTablet
                                                ? AppFontSize.medium.sp
                                                : AppFontSize.small.sp,
                                          ),
                                        ),
                                      ],
                                    ),
                                    SizedBox(height: 0.5.h),
                                    Text(
                                      CurrencyFormat.formatToIdr(
                                        totalExpense,
                                        0,
                                      ),
                                      style: TextStyle(
                                        color: Colors.white,
                                        fontSize: isTablet
                                            ? AppFontSize.medium.sp
                                            : AppFontSize.small.sp,
                                        fontWeight: FontWeight.w600,
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),

        filteredTransactionState.when(
          data: (transactions) {
            switch (transactionEmptyState) {
              case TransactionReportItemEmpty.loading:
                return const SliverToBoxAdapter(child: const SizedBox());
              case TransactionReportItemEmpty.empty_database:
                return const SliverToBoxAdapter(
                  child: CustomEmptyScreen(
                    title: "Tidak Ada Transaksi",
                    body: "Kamu belum melakukan transaksi",
                  ),
                );
              case TransactionReportItemEmpty.empty_search_result:
                return SliverMainAxisGroup(
                  slivers: [
                    SliverPersistentHeader(
                      pinned: true,
                      delegate: SliverHeaderDelegate(
                        child: ReportHeader(
                          rightTitle: "Riwayat Transaksi",
                          leftTitle: "Unduh Laporan",
                        ),
                      ),
                    ),
                    const SliverToBoxAdapter(
                      child: CustomEmptyScreen(
                        body: "Transaksi Tidak Ditemukan",
                      ),
                    ),
                  ],
                );
              case TransactionReportItemEmpty.has_data:
                return SliverMainAxisGroup(
                  slivers: [
                    SliverPersistentHeader(
                      pinned: true,
                      delegate: SliverHeaderDelegate(
                        child: ReportHeader(
                          rightTitle: "Riwayat Transaksi",
                          leftTitle: "Unduh Laporan",
                        ),
                      ),
                    ),
                    SliverList(
                      delegate: SliverChildBuilderDelegate((context, index) {
                        final item = transactions[index];
                        bool showHeader = true;

                        if (index > 0) {
                          final prevItem = transactions[index - 1];
                          if (_isSameDay(prevItem.date, item.date))
                            showHeader = false;
                        }
                        return Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            if (showHeader)
                              Padding(
                                padding: EdgeInsets.symmetric(
                                  horizontal: 5.w,
                                  vertical: 2.h,
                                ),
                                child: Text(
                                  _formatGroupDate(item.date),
                                  style: TextStyle(
                                    color: Colors.grey[500],
                                    fontSize: isTablet
                                        ? AppFontSize.medium.sp
                                        : AppFontSize.small.sp,
                                    fontWeight: FontWeight.bold,
                                  ),
                                ),
                              ),

                            TransactionItem(
                              item: item,
                              onTap: () async {
                                if (item.isIncome) {
                                  final orderDetail = await ref
                                      .read(transactionReportRepositoryProvider)
                                      .getOrderDetail(item.id);

                                  FocusScope.of(context).unfocus();

                                  await Future.delayed(
                                    const Duration(milliseconds: 400),
                                  );

                                  context.pushNamed(
                                    AppRoute.transactionReportOrderDetailScreen,
                                    extra: orderDetail,
                                  );
                                } else {
                                  final purchaseDetail = await ref
                                      .read(transactionReportRepositoryProvider)
                                      .getPurchaseDetail(item.id);

                                  FocusScope.of(context).unfocus();

                                  await Future.delayed(
                                    const Duration(milliseconds: 400),
                                  );

                                  context.pushNamed(
                                    AppRoute
                                        .transactionReportPurchaseDetailScreen,
                                    extra: purchaseDetail,
                                  );
                                }
                              },
                            ),
                          ],
                        );
                      }, childCount: transactions.length),
                    ),
                  ],
                );
            }
          },
          error: (error, stackTrace) {
            return SliverToBoxAdapter(
              child: CustomErrorScreen(
                message: "Ups,terjadi kesalahan",
                onRefresh: () {},
              ),
            );
          },
          loading: () =>
              const SliverToBoxAdapter(child: const TransactionReportShimmer()),
        ),
        SliverToBoxAdapter(child: SizedBox(height: 10.h)),
      ],
    );
  }
}
