import 'dart:async';

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/components/top_back_bar_app.dart';
import 'package:niogu_app/core/constants/app_color.dart';
import 'package:niogu_app/core/constants/app_font_size.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/enums/approval_process.dart';
import 'package:niogu_app/core/enums/order_status.dart';
import 'package:niogu_app/core/enums/report_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/core/widgets/pop_up_notification.dart';
import 'package:niogu_app/features/online_store/domain/entities/online_store.dart';
import 'package:niogu_app/features/online_store/presentation/providers/online_store_provider.dart';
import 'package:niogu_app/features/online_store/presentation/widgets/online_store_order_shimmer.dart';
import 'package:niogu_app/features/online_store/presentation/widgets/order_card.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/fixed_outlet.dart';
import 'package:niogu_app/features/report/transaction/presentation/widgets/online_order_header.dart';
import 'package:niogu_app/features/report/transaction/presentation/widgets/sliver_header_delegate.dart';
import 'package:niogu_app/features/stock_in/domain/entities/stock_in_transfer.dart';
import 'package:sizer/sizer.dart';

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

  @override
  ConsumerState<OnlineStoreOrdersScreen> createState() =>
      _OnlineStoreOrdersScreenState();
}

class _OnlineStoreOrdersScreenState
    extends ConsumerState<OnlineStoreOrdersScreen> {
  final FocusNode _searchFocusNode = FocusNode();

  Color _searchIconColor = Colors.grey;

  String _selectedStatus = "Semua";

  final List<String> _statuses = [
    "Semua",
    "Verifikasi Pembayaran",
    "Tertunda",
    "Dikonfirmasi",
    "Pengiriman",
    "Selesai",
    "Pembatalan",
    "Dibatalkan",
  ];

  Timer? _debounce;

  String? _selectedOutlet;

  DateTimeRange? _selectedDateRange;

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

  @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.online_order).notifier,
                )
                .state =
            currentOutletId;
      }
    });
  }

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

  void _onSearchChanged(String value) {
    if (_debounce?.isActive ?? false) _debounce?.cancel();
    _debounce = Timer(const Duration(milliseconds: 800), () {
      ref.read(onlineOrderSearchProvider.notifier).state = value;
    });
  }

  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.online_order,
                                        ).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.online_order,
                                              ).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.online_order).notifier).state =
        _selectedOutlet;
  }

  String _parseOrderStatus(OrderStatus? orderStatus) {
    switch (orderStatus) {
      case null:
        return "Semua";
      case OrderStatus.pending_payment:
        return "Verifikasi Pembayaran";
      case OrderStatus.pending_confirmation:
        return "Tertunda";
      case OrderStatus.confirmed:
        return "Dikonfirmasi";
      case OrderStatus.in_progress:
        return "Pengiriman";
      case OrderStatus.completed:
        return "Selesai";
      case OrderStatus.canceled:
        return "Dibatalkan";
    }
  }

  List<OnlineOrder> _filteredOrders(List<OnlineOrder> orders) {
    return orders.where((order) {
      if (_selectedStatus == 'Semua') {
        return true;
      }

      if (_selectedStatus == 'Pembatalan') {
        if ((order.orderStatus == OrderStatus.confirmed ||
                order.orderStatus == OrderStatus.in_progress) &&
            order.isCancellation &&
            !order.cancellationAccepted &&
            order.process == ApprovalProcess.waiting) {
          return true;
        }
      }

      return _selectedStatus == _parseOrderStatus(order.orderStatus);
    }).toList();
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        final bool isTablet = 100.w >= 600;

        const greyColor = Color(0xFFF5F5F5);

        final messageActivity = ref.watch(messageActivityProvider);

        final currentUserRole = ref.watch(currentUserRoleProvider);

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

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

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

        final currentOutletName = ref.watch(currentOutletNameProvider);

        final filteredOnlineOrderState = ref.watch(filteredOnlineOrderProvider);

        final orderOnlineEmptyState = ref.watch(onlineOrderEmptyProvider);

        final List<OnlineOrder> onlineOrders = [];

        filteredOnlineOrderState.whenData(
          (orders) => onlineOrders.addAll(orders),
        );

        final Map<String, int> orderCounts = {
          "Semua": onlineOrders.length,
          "Verifikasi Pembayaran": onlineOrders
              .where(
                (order) => order.orderStatus == OrderStatus.pending_payment,
              )
              .length,
          "Tertunda": onlineOrders
              .where(
                (order) =>
                    order.orderStatus == OrderStatus.pending_confirmation,
              )
              .length,
          "Dikonfirmasi": onlineOrders
              .where((order) => order.orderStatus == OrderStatus.confirmed)
              .length,
          "Pengiriman": onlineOrders
              .where((order) => order.orderStatus == OrderStatus.in_progress)
              .length,
          "Selesai": onlineOrders
              .where((order) => order.orderStatus == OrderStatus.completed)
              .length,
          "Pembatalan": onlineOrders
              .where(
                (order) =>
                    (order.orderStatus == OrderStatus.confirmed ||
                        order.orderStatus == OrderStatus.in_progress) &&
                    order.isCancellation &&
                    !order.cancellationAccepted &&
                    order.process == ApprovalProcess.waiting,
              )
              .length,
          "Dibatalkan": onlineOrders
              .where((order) => order.orderStatus == OrderStatus.canceled)
              .length,
        };

        return SafeArea(
          top: false,
          bottom: true,
          right: false,
          left: false,
          child: Stack(
            children: [
              Scaffold(
                backgroundColor: const Color(0xFFF9FAFB),
                appBar: TopBackBarApp(
                  title: "Pesanan Dari Toko Online",
                  onTap: () => context.pop(),
                ),
                body: CustomScrollView(
                  physics: const ClampingScrollPhysics(),
                  slivers: [
                    SliverAppBar(
                      pinned: false,
                      floating: true,
                      snap: true,
                      expandedHeight: 26.h,
                      backgroundColor: Colors.white,
                      elevation: 0,
                      automaticallyImplyLeading: false,
                      flexibleSpace: FlexibleSpaceBar(
                        background: Material(
                          type: MaterialType.canvas,
                          color: Colors.white,
                          elevation: 0,
                          child: Padding(
                            padding: EdgeInsets.fromLTRB(5.w, 2.h, 5.w, 1.h),
                            child: Column(
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                Container(
                                  height: 6.h,
                                  decoration: BoxDecoration(
                                    color: greyColor,
                                    borderRadius: BorderRadius.circular(2.5.w),
                                  ),
                                  child: TextField(
                                    focusNode: _searchFocusNode,
                                    onChanged: (value) =>
                                        _onSearchChanged(value),
                                    textAlignVertical: TextAlignVertical.center,
                                    style: TextStyle(
                                      color: Colors.black87,
                                      fontSize: isTablet
                                          ? AppFontSize.medium.sp
                                          : AppFontSize.small.sp,
                                    ),
                                    decoration: InputDecoration(
                                      hintText:
                                          "Cari berdasarkan nomor pesanan",
                                      hintStyle: TextStyle(
                                        color: _searchIconColor,
                                        fontSize: isTablet
                                            ? AppFontSize.medium.sp
                                            : AppFontSize.small.sp,
                                      ),
                                      prefixIcon: Icon(
                                        Icons.search,
                                        color: _searchIconColor,
                                        size: 5.w,
                                      ),
                                      border: InputBorder.none,
                                      contentPadding: EdgeInsets.zero,
                                      isDense: true,
                                    ),
                                  ),
                                ),

                                SizedBox(height: 1.5.h),

                                if (currentUserRole == UserRole.owner)
                                  FilteredOutlet(
                                    value: sourceOutletState.isLoading
                                        ? '0'
                                        : (_selectedOutlet ?? '0'),
                                    sourceOutlets: sourceOutlets,
                                    onChanged: _onSelectedOutletChange,
                                  )
                                else
                                  FixedOutlet(value: currentOutletName!),

                                SizedBox(height: 1.5.h),

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

                    SliverPersistentHeader(
                      pinned: true,
                      delegate: SliverHeaderDelegate(
                        child: OrderOnlineHeader(
                          statuses: _statuses,
                          selectedStatus: _selectedStatus,
                          orderCounts: orderCounts,
                          onTap: (value) {
                            setState(() {
                              _selectedStatus = value;
                            });
                          },
                        ),
                        value: _selectedStatus,
                      ),
                    ),

                    filteredOnlineOrderState.when(
                      data: (onlineOrders) {
                        switch (orderOnlineEmptyState) {
                          case OnlineOrderEmpty.loading:
                            return const SliverToBoxAdapter(
                              child: const SizedBox(),
                            );
                          case OnlineOrderEmpty.empty_database:
                            return const SliverToBoxAdapter(
                              child: CustomEmptyScreen(
                                title: "Tidak Ada Pesanan",
                                body: "Kamu belum memiliki pesanan",
                              ),
                            );
                          case OnlineOrderEmpty.empty_search_result:
                            return const SliverToBoxAdapter(
                              child: CustomEmptyScreen(
                                body: "Pesanan Tidak Ditemukan",
                              ),
                            );
                          case OnlineOrderEmpty.has_data:
                            final orders = _filteredOrders(onlineOrders);

                            if (orders.isEmpty) {
                              return const SliverToBoxAdapter(
                                child: CustomEmptyScreen(
                                  body: "Pesanan Tidak Ditemukan",
                                ),
                              );
                            }

                            return SliverPadding(
                              padding: EdgeInsets.symmetric(
                                horizontal: 5.w,
                                vertical: 2.h,
                              ),
                              sliver: SliverList(
                                delegate: SliverChildBuilderDelegate((
                                  context,
                                  index,
                                ) {
                                  final order = orders[index];

                                  bool showHeader = true;
                                  if (index > 0) {
                                    final prevOrder = orders[index - 1];
                                    if (_isSameDay(
                                      prevOrder.orderDate,
                                      order.orderDate,
                                    )) {
                                      showHeader = false;
                                    }
                                  }
                                  return Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: [
                                      if (showHeader)
                                        Padding(
                                          padding: EdgeInsets.symmetric(
                                            horizontal: 5.w,
                                            vertical: index > 0 ? 1.5.h : 0,
                                          ),
                                          child: Text(
                                            _formatGroupDate(order.orderDate),
                                            style: TextStyle(
                                              color: Colors.grey[500],
                                              fontSize: isTablet
                                                  ? AppFontSize.medium.sp
                                                  : AppFontSize.small.sp,
                                              fontWeight: FontWeight.bold,
                                            ),
                                          ),
                                        ),
                                      OrderCard(
                                        order: order,
                                        onTap: () async {
                                          final onlineOrderDetail = await ref
                                              .read(
                                                onlineStoreRepositoryProvider,
                                              )
                                              .fetchOnlineOrderDetailById(
                                                order.id,
                                              );

                                          await Future.delayed(
                                            const Duration(milliseconds: 800),
                                            () {
                                              context.pushNamed(
                                                AppRoute
                                                    .onlineStoreOrderDetilScreen,
                                                extra: onlineOrderDetail,
                                              );
                                            },
                                          );
                                        },
                                      ),
                                    ],
                                  );
                                }, childCount: orders.length),
                              ),
                            );
                        }
                      },
                      error: (error, stackTrace) {
                        return SliverToBoxAdapter(
                          child: CustomErrorScreen(
                            message: "Ups,terjadi kesalahan",
                            onRefresh: () {},
                          ),
                        );
                      },
                      loading: () => const SliverToBoxAdapter(
                        child: const OnlineStoreOrderShimmer(),
                      ),
                    ),
                  ],
                ),
              ),

              if (messageActivity != null)
                PopupNotification(
                  isOwner: currentUserRole == UserRole.owner,
                  messages: messageActivity.messages,
                  type: messageActivity.type,
                ),
            ],
          ),
        );
      },
    );
  }
}
