import 'package:flutter/material.dart';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:mobile_pos/Provider/transactions_provider.dart';
import 'package:mobile_pos/Screens/Loss_Profit/single_loss_profit_screen.dart';
import 'package:mobile_pos/const_commas.dart';
import 'package:mobile_pos/generated/l10n.dart' as lang;
import 'package:mobile_pos/model/print_transaction_model.dart';
import 'package:nb_utils/nb_utils.dart';

import '../../../Provider/profile_provider.dart';
import '../../../constant.dart';
import '../../currency.dart';
import '../../empty_screen_widget.dart';
import '../../model/personal_information_model.dart';
import '../../model/transition_model.dart';
import '../../thermal printing service/printing_provider/print_thermal_invoice_provider.dart';
import '../Home/home.dart';

final lossProfitScreenPaginationProvider =
    StateNotifierProvider<LossProfitScreenPaginationNotifier, LossProfitScreenPaginationState>(
        (ref) {
  return LossProfitScreenPaginationNotifier();
});

class LossProfitScreenPaginationState {
  final int currentPage;
  final int itemsPerPage;
  final bool isLoading;
  final bool hasMore;
  final List<SalesTransitionModel> displayedTransactions;
  final double totalProfit;
  final double totalLoss;

  LossProfitScreenPaginationState({
    this.currentPage = 1,
    this.itemsPerPage = 10,
    this.isLoading = false,
    this.hasMore = true,
    List<SalesTransitionModel>? displayedTransactions,
    this.totalProfit = 0,
    this.totalLoss = 0,
  }) : displayedTransactions = displayedTransactions ?? [];

  LossProfitScreenPaginationState copyWith({
    int? currentPage,
    int? itemsPerPage,
    bool? isLoading,
    bool? hasMore,
    List<SalesTransitionModel>? displayedTransactions,
    double? totalProfit,
    double? totalLoss,
  }) {
    return LossProfitScreenPaginationState(
      currentPage: currentPage ?? this.currentPage,
      itemsPerPage: itemsPerPage ?? this.itemsPerPage,
      isLoading: isLoading ?? this.isLoading,
      hasMore: hasMore ?? this.hasMore,
      displayedTransactions: displayedTransactions ?? this.displayedTransactions,
      totalProfit: totalProfit ?? this.totalProfit,
      totalLoss: totalLoss ?? this.totalLoss,
    );
  }
}

class LossProfitScreenPaginationNotifier extends StateNotifier<LossProfitScreenPaginationState> {
  LossProfitScreenPaginationNotifier() : super(LossProfitScreenPaginationState());

  void resetPagination() {
    state = state.copyWith(
      currentPage: 1,
      displayedTransactions: [],
      hasMore: true,
      totalProfit: 0,
      totalLoss: 0,
    );
  }

  void loadMoreTransactions(List<SalesTransitionModel> allTransactions,
      {DateTime? fromDate, DateTime? toDate, bool isPicked = false}) {
    if (state.isLoading || !state.hasMore) return;

    state = state.copyWith(isLoading: true);

    // Filter transactions based on date range
    final filteredTransactions = _filterTransactions(allTransactions,
        fromDate: fromDate, toDate: toDate, isPicked: isPicked);

    // Calculate totals for all filtered transactions
    final totals = _calculateTotals(filteredTransactions,
        fromDate: fromDate, toDate: toDate, isPicked: isPicked);

    final totalItems = filteredTransactions.length;
    final startIndex = (state.currentPage - 1) * state.itemsPerPage;
    final endIndex = startIndex + state.itemsPerPage;

    // Check if we have more items to load
    final hasMoreItems = endIndex < totalItems;

    // Get the next batch of transactions
    final nextBatch = endIndex <= totalItems
        ? filteredTransactions.sublist(startIndex, endIndex)
        : filteredTransactions.sublist(startIndex);

    // Update state
    final newDisplayedTransactions = [...state.displayedTransactions, ...nextBatch];

    state = state.copyWith(
      currentPage: state.currentPage + 1,
      isLoading: false,
      hasMore: hasMoreItems,
      displayedTransactions: newDisplayedTransactions,
      totalProfit: totals['profit'] ?? 0,
      totalLoss: totals['loss'] ?? 0,
    );
  }

  List<SalesTransitionModel> _filterTransactions(List<SalesTransitionModel> transactions,
      {DateTime? fromDate, DateTime? toDate, bool isPicked = false}) {
    return transactions.where((transaction) {
      try {
        final purchaseDate = DateTime.parse(transaction.purchaseDate);

        if (!isPicked) {
          // Default to current month if no date range is picked
          return purchaseDate.month == DateTime.now().month &&
              purchaseDate.year == DateTime.now().year;
        } else {
          // Use selected date range
          if (fromDate != null && toDate != null) {
            return (fromDate.isBefore(purchaseDate) || purchaseDate.isAtSameMomentAs(fromDate)) &&
                (toDate.isAfter(purchaseDate) || purchaseDate.isAtSameMomentAs(toDate));
          }
          return true;
        }
      } catch (e) {
        return false;
      }
    }).toList();
  }

  Map<String, double> _calculateTotals(List<SalesTransitionModel> transactions,
      {DateTime? fromDate, DateTime? toDate, bool isPicked = false}) {
    double profit = 0;
    double loss = 0;

    for (var element in transactions) {
      try {
        final purchaseDate = DateTime.parse(element.purchaseDate);

        if (!isPicked) {
          if (purchaseDate.month == DateTime.now().month &&
              purchaseDate.year == DateTime.now().year) {
            element.lossProfit!.isNegative
                ? loss += element.lossProfit!.abs()
                : profit += element.lossProfit!;
          }
        } else {
          if (fromDate != null && toDate != null) {
            if ((fromDate.isBefore(purchaseDate) || purchaseDate.isAtSameMomentAs(fromDate)) &&
                (toDate.isAfter(purchaseDate) || purchaseDate.isAtSameMomentAs(toDate))) {
              element.lossProfit!.isNegative
                  ? loss += element.lossProfit!.abs()
                  : profit += element.lossProfit!;
            }
          }
        }
      } catch (e) {
        continue;
      }
    }

    return {'profit': profit, 'loss': loss};
  }
}

class LossProfitScreen extends StatefulWidget {
  const LossProfitScreen({super.key});

  @override
  _LossProfitScreenState createState() => _LossProfitScreenState();
}

class _LossProfitScreenState extends State<LossProfitScreen> {
  late TextEditingController fromDateTextEditingController;
  late TextEditingController toDateTextEditingController;
  late DateTime fromDate;
  late DateTime toDate;
  bool isPicked = false;
  final ScrollController _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    // Initialize dates with safe defaults
    fromDate = DateTime(DateTime.now().year, 1, 1); // Start of current year
    toDate = DateTime.now();
    fromDateTextEditingController = TextEditingController(text: _formatDate(fromDate));
    toDateTextEditingController = TextEditingController(text: _formatDate(toDate));

    // Add scroll listener for pagination
    _scrollController.addListener(_scrollListener);
  }

  @override
  void dispose() {
    fromDateTextEditingController.dispose();
    toDateTextEditingController.dispose();
    _scrollController.dispose();
    super.dispose();
  }

  void _scrollListener() {
    if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
      _loadMoreData();
    }
  }

  void _loadMoreData() {
    final ref = ProviderScope.containerOf(context);
    final providerData = ref.read(transitionProvider);

    providerData.whenData((transactions) {
      ref.read(lossProfitScreenPaginationProvider.notifier).loadMoreTransactions(
            transactions.reversed.toList(),
            fromDate: fromDate,
            toDate: toDate,
            isPicked: isPicked,
          );
    });
  }

  void _resetAndLoadData() {
    final ref = ProviderScope.containerOf(context);
    ref.read(lossProfitScreenPaginationProvider.notifier).resetPagination();
    _loadMoreData();
  }

  String _formatDate(DateTime date) {
    return DateFormat.yMMMd().format(date);
  }

  Widget _buildTransactionListItem(SalesTransitionModel transaction, WidgetRef ref,
      AsyncValue<PersonalInformationModel> personalData) {
    return GestureDetector(
      onTap: () {
        SingleLossProfitScreen(
          transactionModel: transaction,
        ).launch(context);
      },
      child: Column(
        children: [
          Container(
            padding: const EdgeInsets.all(20),
            width: context.width(),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Flexible(
                      child: Text(
                        transaction.customerName.isNotEmpty
                            ? transaction.customerName
                            : transaction.customerPhone,
                        style: const TextStyle(fontSize: 16),
                        maxLines: 2,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ),
                    Text(
                      '#${transaction.invoiceNumber}',
                      style: const TextStyle(color: Colors.black),
                    ),
                  ],
                ),
                const SizedBox(height: 10),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Container(
                      padding: const EdgeInsets.all(8),
                      decoration: BoxDecoration(
                          color: transaction.dueAmount! <= 0
                              ? const Color(0xff0dbf7d).withValues(alpha: 0.1)
                              : const Color(0xFFED1A3B).withValues(alpha: 0.1),
                          borderRadius: const BorderRadius.all(Radius.circular(10))),
                      child: Text(
                        transaction.dueAmount! <= 0
                            ? lang.S.of(context).paid
                            : lang.S.of(context).unpaid,
                        style: TextStyle(
                            color: transaction.dueAmount! <= 0
                                ? const Color(0xff0dbf7d)
                                : const Color(0xFFED1A3B)),
                      ),
                    ),
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.end,
                      children: [
                        Text(
                          DateFormat.yMMMd().format(DateTime.parse(transaction.purchaseDate)),
                          style: const TextStyle(color: Colors.grey),
                        ),
                        const SizedBox(height: 5),
                        Text(
                          DateFormat.jm().format(DateTime.parse(transaction.purchaseDate)),
                          style: const TextStyle(color: Colors.grey),
                        ),
                      ],
                    ),
                  ],
                ),
                const SizedBox(height: 5),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          '${lang.S.of(context).total} : $currency ${myFormat.format(transaction.totalAmount)}',
                          style: const TextStyle(color: Colors.grey),
                        ),
                        const SizedBox(height: 5),
                        Text(
                          '${lang.S.of(context).profit} : $currency ${myFormat.format(transaction.lossProfit)}',
                          style: const TextStyle(color: Colors.green, fontWeight: FontWeight.bold),
                        ).visible(!transaction.lossProfit!.isNegative),
                        Text(
                          '${lang.S.of(context).loss}: $currency ${myFormat.format(transaction.lossProfit!.abs())}',
                          style: const TextStyle(
                              color: Colors.redAccent, fontWeight: FontWeight.bold),
                        ).visible(transaction.lossProfit!.isNegative),
                      ],
                    ),
                    personalData.when(data: (data) {
                      return Row(
                        children: [
                          IconButton(
                            onPressed: () async {
                              PrintTransactionModel model = PrintTransactionModel(
                                  transitionModel: transaction, personalInformationModel: data);
                              ref.watch(thermalPrinterProvider).printSalesThermalInvoiceNow(
                                  transaction: model,
                                  productList: model.transitionModel?.productList,
                                  context: context);
                            },
                            icon: const Icon(
                              FeatherIcons.printer,
                              color: Colors.grey,
                            ),
                          ),
                          IconButton(
                            onPressed: () => toast('Coming Soon'),
                            icon: const Icon(
                              FeatherIcons.share,
                              color: Colors.grey,
                            ),
                          ).visible(false),
                        ],
                      );
                    }, error: (e, stack) {
                      return Text(e.toString());
                    }, loading: () {
                      return Text(lang.S.of(context).loading);
                    }),
                  ],
                ),
              ],
            ),
          ),
          Container(
            height: 0.5,
            width: context.width(),
            color: Colors.grey,
          )
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        return await const Home().launch(context, isNewTask: true);
      },
      child: Scaffold(
        backgroundColor: kMainColor,
        appBar: AppBar(
          iconTheme: const IconThemeData(color: kWhite),
          title: Text(
            lang.S.of(context).lossOrProfit,
            style: GoogleFonts.poppins(
              color: Colors.white,
              fontSize: 20.0,
            ),
          ),
          centerTitle: true,
          backgroundColor: kMainColor,
          elevation: 0.0,
        ),
        body: Container(
          alignment: Alignment.topCenter,
          decoration: const BoxDecoration(
              color: Colors.white,
              borderRadius:
                  BorderRadius.only(topRight: Radius.circular(30), topLeft: Radius.circular(30))),
          child: Consumer(builder: (context, ref, __) {
            final providerData = ref.watch(transitionProvider);
            final personalData = ref.watch(profileDetailsProvider);
            final paginationState = ref.watch(lossProfitScreenPaginationProvider);

            return providerData.when(
              data: (allTransactions) {
                // Initial load of data
                if (paginationState.displayedTransactions.isEmpty && !paginationState.isLoading) {
                  WidgetsBinding.instance.addPostFrameCallback((_) {
                    _resetAndLoadData();
                  });
                }

                final filteredTransactions = allTransactions.where((transaction) {
                  try {
                    final purchaseDate = DateTime.parse(transaction.purchaseDate);

                    if (!isPicked) {
                      return purchaseDate.month == DateTime.now().month &&
                          purchaseDate.year == DateTime.now().year;
                    } else {
                      return (fromDate.isBefore(purchaseDate) ||
                              purchaseDate.isAtSameMomentAs(fromDate)) &&
                          (toDate.isAfter(purchaseDate) || purchaseDate.isAtSameMomentAs(toDate));
                    }
                  } catch (e) {
                    return false;
                  }
                }).toList();

                return Column(
                  children: [
                    // Date Selection
                    Padding(
                      padding: const EdgeInsets.only(right: 20.0, left: 20.0, top: 20, bottom: 10),
                      child: Row(
                        children: [
                          Expanded(
                            child: AppTextField(
                              textFieldType: TextFieldType.NAME,
                              readOnly: true,
                              controller: fromDateTextEditingController,
                              decoration: InputDecoration(
                                floatingLabelBehavior: FloatingLabelBehavior.always,
                                labelText: lang.S.of(context).formDate,
                                border: const OutlineInputBorder(),
                                suffixIcon: IconButton(
                                  onPressed: () async {
                                    try {
                                      final DateTime? picked = await showDatePicker(
                                        initialDate: fromDate,
                                        firstDate: DateTime(2015, 8),
                                        lastDate: DateTime(2101),
                                        context: context,
                                      );
                                      if (picked != null) {
                                        setState(() {
                                          fromDateTextEditingController.text = _formatDate(picked);
                                          fromDate = picked;
                                          isPicked = true;
                                          _resetAndLoadData();
                                        });
                                      }
                                    } catch (e) {
                                      debugPrint('Error selecting from date: $e');
                                    }
                                  },
                                  icon: const Icon(FeatherIcons.calendar),
                                ),
                              ),
                            ),
                          ),
                          const SizedBox(width: 10),
                          Expanded(
                            child: AppTextField(
                              textFieldType: TextFieldType.NAME,
                              readOnly: true,
                              controller: toDateTextEditingController,
                              decoration: InputDecoration(
                                floatingLabelBehavior: FloatingLabelBehavior.always,
                                labelText: lang.S.of(context).toDate,
                                border: const OutlineInputBorder(),
                                suffixIcon: IconButton(
                                  onPressed: () async {
                                    try {
                                      final DateTime? picked = await showDatePicker(
                                        initialDate: toDate.isAfter(fromDate) ? toDate : fromDate,
                                        firstDate: fromDate,
                                        lastDate: DateTime(2101),
                                        context: context,
                                      );
                                      if (picked != null) {
                                        setState(() {
                                          toDateTextEditingController.text = _formatDate(picked);
                                          toDate = picked;
                                          isPicked = true;
                                          _resetAndLoadData();
                                        });
                                      }
                                    } catch (e) {
                                      debugPrint('Error selecting to date: $e');
                                    }
                                  },
                                  icon: const Icon(FeatherIcons.calendar),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),

                    // Totals Display and Transactions List
                    Expanded(
                      child: paginationState.displayedTransactions.isNotEmpty ||
                              paginationState.isLoading
                          ? SingleChildScrollView(
                              controller: _scrollController,
                              child: Column(
                                children: [
                                  // Totals Summary
                                  Padding(
                                    padding: const EdgeInsets.all(20.0),
                                    child: Container(
                                      height: 120,
                                      width: double.infinity,
                                      decoration: BoxDecoration(
                                          color: kMainColor.withValues(alpha: 0.1),
                                          border: Border.all(width: 1, color: kMainColor),
                                          borderRadius:
                                              const BorderRadius.all(Radius.circular(15))),
                                      child: Column(
                                        mainAxisAlignment: MainAxisAlignment.spaceAround,
                                        crossAxisAlignment: CrossAxisAlignment.center,
                                        children: [
                                          Row(
                                            mainAxisAlignment: MainAxisAlignment.spaceAround,
                                            children: [
                                              SizedBox(
                                                width: MediaQuery.of(context).size.width / 2 - 30,
                                                child: Column(
                                                  mainAxisAlignment: MainAxisAlignment.center,
                                                  crossAxisAlignment: CrossAxisAlignment.center,
                                                  children: [
                                                    Text(
                                                      currency +
                                                          myFormat
                                                              .format(paginationState.totalProfit),
                                                      style: const TextStyle(
                                                        color: Colors.green,
                                                        fontSize: 20,
                                                      ),
                                                    ),
                                                    const SizedBox(height: 10),
                                                    Text(
                                                      lang.S.of(context).profit,
                                                      style: const TextStyle(
                                                        color: Colors.black,
                                                        fontSize: 16,
                                                      ),
                                                    ),
                                                  ],
                                                ),
                                              ),
                                              Container(
                                                width: 1,
                                                height: 60,
                                                color: kMainColor,
                                              ),
                                              SizedBox(
                                                width: MediaQuery.of(context).size.width / 2 - 30,
                                                child: Column(
                                                  mainAxisAlignment: MainAxisAlignment.center,
                                                  crossAxisAlignment: CrossAxisAlignment.center,
                                                  children: [
                                                    Text(
                                                      currency +
                                                          myFormat
                                                              .format(paginationState.totalLoss),
                                                      style: const TextStyle(
                                                        color: Colors.orange,
                                                        fontSize: 20,
                                                      ),
                                                    ),
                                                    const SizedBox(height: 10),
                                                    Text(
                                                      lang.S.of(context).loss,
                                                      style: const TextStyle(
                                                        color: Colors.black,
                                                        fontSize: 16,
                                                      ),
                                                    ),
                                                  ],
                                                ),
                                              ),
                                            ],
                                          ),
                                        ],
                                      ),
                                    ),
                                  ),

                                  // Transactions List
                                  ListView.builder(
                                    shrinkWrap: true,
                                    physics: const NeverScrollableScrollPhysics(),
                                    itemCount: paginationState.displayedTransactions.length +
                                        (paginationState.hasMore ? 1 : 0),
                                    itemBuilder: (context, index) {
                                      // Loading indicator at the end
                                      if (index == paginationState.displayedTransactions.length) {
                                        return paginationState.hasMore
                                            ? const Padding(
                                                padding: EdgeInsets.all(16.0),
                                                child: Center(
                                                  child: CircularProgressIndicator(),
                                                ),
                                              )
                                            : filteredTransactions.isNotEmpty
                                                ? Padding(
                                                    padding: const EdgeInsets.all(16.0),
                                                    child: Center(
                                                      child: Text(
                                                        lang.S.of(context).noDataFound,
                                                        style: const TextStyle(color: Colors.grey),
                                                      ),
                                                    ),
                                                  )
                                                : const SizedBox.shrink();
                                      }

                                      final transaction =
                                          paginationState.displayedTransactions[index];
                                      return _buildTransactionListItem(
                                          transaction, ref, personalData);
                                    },
                                  ),
                                ],
                              ),
                            )
                          : filteredTransactions.isEmpty
                              ? const Padding(
                                  padding: EdgeInsets.only(top: 60),
                                  child: EmptyScreenWidget(),
                                )
                              : const Center(
                                  child: CircularProgressIndicator(),
                                ),
                    ),
                  ],
                );
              },
              error: (e, stack) {
                return Center(
                  child: Padding(
                    padding: const EdgeInsets.all(20.0),
                    child: Text(
                      'Error loading transactions: $e',
                      style: const TextStyle(color: Colors.red),
                      textAlign: TextAlign.center,
                    ),
                  ),
                );
              },
              loading: () {
                return const Center(child: CircularProgressIndicator());
              },
            );
          }),
        ),
      ),
    );
  }
}
