import 'dart:async';

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hub/components/molecular_components/order_filter_modal/order_filter_modal_widget.dart';
import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart';
import 'package:hub/components/templates_components/details_component/details_component_widget.dart';
import 'package:hub/features/backend/index.dart';
import 'package:hub/features/storage/index.dart';
import 'package:hub/flutter_flow/flutter_flow_icon_button.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/shared/utils/dialog_util.dart';
import 'package:hub/shared/utils/limited_text_size.dart';
import 'package:hub/shared/utils/log_util.dart';
import 'package:hub/shared/utils/validator_util.dart';
import 'package:rxdart/rxdart.dart';

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

  @override
  State<PackageOrderPage> createState() => _PackageOrderPage();
}

class _PackageOrderPage extends State<PackageOrderPage> {
  late ScrollController _scrollController;
  int _pageNumber = 1;
  final int _pageSize = 10;
  bool _hasData = false;
  bool _loading = false;
  late final String cliUUID;

  late Future<void> _orderFuture;
  List<dynamic> _orderList = [];

  final Map<String, String> filter = {
    'adresseeType': 'PRO',
    'status': 'notPickedUp',
  };

  String _adresseeType = 'PRO';
  String _status = 'notPickedUp';

  late BehaviorSubject<Map<String, String>> _selectedTypeSubject;
  bool _isSubjectClosed = false;

  @override
  void initState() {
    super.initState();
    _selectedTypeSubject = BehaviorSubject.seeded(filter);
    _selectedTypeSubject.listen((value) {});

    _orderFuture = _fetchOrders();

    _scrollController = ScrollController()
      ..addListener(() {
        if (_scrollController.position.atEdge &&
            _scrollController.position.pixels != 0) {
          _loadMoreOrders();
        }
      });
    initDatabase();
  }

  Future<void> initDatabase() async {
    cliUUID =
        (await StorageHelper().get(ProfileStorageKey.clientUUID.key) ?? '');
  }

  @override
  void dispose() {
    super.dispose();
    _selectedTypeSubject.close();
    _isSubjectClosed = true;
    _scrollController.dispose();
  }

  void _showNoMoreDataSnackbar(BuildContext context) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(
          FFLocalizations.of(context).getVariableText(
              ptText: "Não há mais dados.", enText: "No more data."),
          style: TextStyle(
            color: Colors.white,
            fontSize: LimitedFontSizeUtil.getBodyFontSize(context),
          ),
        ),
        duration: const Duration(seconds: 3),
        backgroundColor: FlutterFlowTheme.of(context).primary,
      ),
    );
  }

  Future<ApiCallResponse?> _fetchOrders() async {
    try {
      setState(() => _loading = true);

      var response = await PhpGroup.buscaEnconcomendas.call(
          pageSize: _pageSize.toString(),
          page: _pageNumber.toString(),
          adresseeType: _adresseeType == '.*' ? 'TOD' : _adresseeType,
          status: _status == '.*' ? 'all' : _status);

      final List<dynamic> orders = response.jsonBody['value']['list'] ?? [];

      if (orders.isNotEmpty) {
        setState(() {
          _orderList.addAll(orders);
          _hasData = true;
          _loading = false;
        });

        return response;
      }

      _showNoMoreDataSnackbar(context);

      setState(() {
        _hasData = false;
        _loading = false;
      });

      return null;
    } catch (e, s) {
      await DialogUtil.errorDefault(context);
      LogUtil.requestAPIFailed('processRequest', "", "Busca Encomendas", e, s);
      setState(() {
        _hasData = false;
        _loading = false;
      });
    }
    return null;
  }

  void _loadMoreOrders() {
    if (_hasData == true) {
      _pageNumber++;
      _orderFuture = _fetchOrders();
    }
  }

  Widget _backButton(BuildContext context, FlutterFlowTheme theme) {
    return FlutterFlowIconButton(
      key: ValueKey<String>('BackNavigationAppBar'),
      borderColor: Colors.transparent,
      borderRadius: 30.0,
      borderWidth: 1.0,
      buttonSize: 60.0,
      icon: Icon(
        Icons.keyboard_arrow_left,
        color: theme.primaryText,
        size: 30.0,
      ),
      onPressed: () => Navigator.of(context).pop(),
    );
  }

  Widget _filterButton(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.end,
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(0, 0, 10, 0),
          child: IconButton(
            icon: const Icon(Icons.filter_list),
            onPressed: () async {
              final Map<String, String>? selectedFilter =
                  await showModalBottomSheet<Map<String, String>>(
                      isScrollControlled: true,
                      backgroundColor: Colors.transparent,
                      context: context,
                      builder: (context) {
                        return GestureDetector(
                          onTap: () => Navigator.of(context).pop(),
                          child: Container(
                            color: Colors.transparent,
                            child: GestureDetector(
                              onTap: () {},
                              child: OrderFilterModalWidget(
                                defaultAdresseeType: _selectedTypeSubject
                                        .value['adresseeType'] ??
                                    '.*',
                                defaultStatus:
                                    _selectedTypeSubject.value['status'] ??
                                        '.*',
                              ),
                            ),
                          ),
                        );
                      });

              if (selectedFilter != null) {
                _updateFilterAction(selectedFilter);
              }
            },
          ),
        ),
      ],
    );
  }

  void _updateFilterAction(Map<String, String> newType) {
    if (!_isSubjectClosed) {
      final currentType = _selectedTypeSubject.value;
      final updatedType = Map<String, String>.from(currentType);
      bool needsUpdate = false;
      newType.forEach((key, newValue) {
        if (currentType[key] != newValue) {
          updatedType[key] = newValue;
          needsUpdate = true;
        }
      });
      if (needsUpdate) {
        _selectedTypeSubject.add(updatedType);
        _fetchFilterOrder(updatedType);
        safeSetState(() {});
      }
    }
  }

  void _fetchFilterOrder(Map<String, String> select) {
    _adresseeType = select['adresseeType']!;
    _status = select['status']!;
    _orderList = [];
    _pageNumber = 1;
    _orderFuture = _fetchOrders();
  }

  PreferredSizeWidget _appBar(BuildContext context) {
    return AppBar(
      backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
      automaticallyImplyLeading: false,
      title: Text(
        FFLocalizations.of(context)
            .getVariableText(enText: 'Orders', ptText: 'Encomendas'),
        style: FlutterFlowTheme.of(context).headlineMedium.override(
              fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily,
              color: FlutterFlowTheme.of(context).primaryText,
              fontSize: 16.0,
              fontWeight: FontWeight.bold,
              letterSpacing: 0.0,
              useGoogleFonts: GoogleFonts.asMap().containsKey(
                  FlutterFlowTheme.of(context).headlineMediumFamily),
            ),
      ),
      leading: _backButton(context, FlutterFlowTheme.of(context)),
      centerTitle: true,
      elevation: 0.0,
      actions: [_filterButton(context)],
    );
  }

  Widget _appBody(BuildContext context) {
    return SafeArea(
      top: true,
      child: Column(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
          if (_hasData == false && _pageNumber <= 1 && _loading == false)
            Expanded(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.max,
                children: [
                  Center(
                      child: Text(
                    FFLocalizations.of(context).getVariableText(
                        ptText: "Nenhuma encomenda encontrada!",
                        enText: "No orders found!"),
                    style: TextStyle(
                      color: FlutterFlowTheme.of(context).primaryText,
                      fontSize: LimitedFontSizeUtil.getHeaderFontSize(context),
                    ),
                  )),
                ],
              ),
            )
          else if (_hasData || _pageNumber >= 1)
            Expanded(child: _itemList()),
          if (_hasData == true && _loading == true)
            Container(
              padding: const EdgeInsets.only(top: 15, bottom: 15),
              child: Center(
                child: CircularProgressIndicator(
                  valueColor: AlwaysStoppedAnimation<Color>(
                    FlutterFlowTheme.of(context).primary,
                  ),
                ),
              ),
            )
        ],
      ),
    );
  }

  Widget _itemList() {
    return FutureBuilder<void>(
        future: _orderFuture,
        builder: (context, snapshot) {
          return ListView.builder(
            shrinkWrap: true,
            physics: const BouncingScrollPhysics(),
            controller: _scrollController,
            itemCount: _orderList.length,
            itemBuilder: (context, index) {
              final order = _orderList[index];
              return _item(context, order);
            },
          );
        });
  }

  String _imagePath(dynamic order) {
    return '${PhpGroup.getBaseUrl()}/getImage.php?cliID=$cliUUID&atividade=getFotoEncomenda&orderId=${order['id'] ?? ''}';
  }

  Map<String, String> _labelsHashMap(dynamic order) {
    return Map<String, String>.from({
      if (order['isPending'] == true)
        '${FFLocalizations.of(context).getVariableText(ptText: 'Cód. Retirada', enText: 'Pickup Code')}:':
            order['id'].toString(),
      '${FFLocalizations.of(context).getVariableText(ptText: 'Categoria', enText: 'Category')}:':
          order['customCategory'],
      '${FFLocalizations.of(context).getVariableText(ptText: 'Recebido em', enText: 'Received on')}:':
          ValidatorUtil.toLocalDateTime(
              'yyyy-MM-dd HH:mm:ss', order['dtReceive']),
      if (order['isPending'] == false)
        '${FFLocalizations.of(context).getVariableText(ptText: 'Retirado em', enText: 'Picked up on')}:':
            ValidatorUtil.toLocalDateTime(
                'yyyy-MM-dd HH:mm:ss', order['dtPickUp']),
    });
  }

  Map<String, String> _labelsHashMapDialog(dynamic order) {
    return Map<String, String>.from({
      if (order['isPending'] == true)
        '${FFLocalizations.of(context).getVariableText(ptText: 'Cód. Retirada', enText: 'Pickup Code')}:':
            order['id'].toString(),
      '${FFLocalizations.of(context).getVariableText(ptText: 'Categoria', enText: 'Category')}:':
          order['customCategory'],
      if (order['code'] != null)
        '${FFLocalizations.of(context).getVariableText(ptText: 'Cód. Objeto', enText: 'Object Code')}:':
            order['code'],
      '${FFLocalizations.of(context).getVariableText(ptText: 'Entregue por', enText: 'Delivered by')}:':
          order['sendedBy'],
      '${FFLocalizations.of(context).getVariableText(ptText: 'Recebido por', enText: 'Received by')}:':
          order['receivedBy'],
      '${FFLocalizations.of(context).getVariableText(ptText: 'Recebido em', enText: 'Received on')}:':
          ValidatorUtil.toLocalDateTime(
              'yyyy-MM-dd HH:mm:ss', order['dtReceive']),
      if (order['isPending'] == false)
        '${FFLocalizations.of(context).getVariableText(ptText: 'Retirado por', enText: 'Picked up by')}:':
            order['pickedUpBy'],
      if (order['isPending'] == false)
        '${FFLocalizations.of(context).getVariableText(ptText: 'Retirado em', enText: 'Picked up on')}:':
            ValidatorUtil.toLocalDateTime(
                'yyyy-MM-dd HH:mm:ss', order['dtPickUp']),
      if (order['message'] != null)
        '${FFLocalizations.of(context).getVariableText(ptText: 'Mensagem', enText: 'Message')}:':
            order['message']
    });
  }

  List<Map<String, Color>> _statusHashMap(dynamic order) {
    return [
      if (order['isPending'] == true)
        Map<String, Color>.from({
          FFLocalizations.of(context).getVariableText(
              ptText: 'Aguardando Retirada',
              enText: 'Waiting Pick up'): FlutterFlowTheme.of(context).warning,
        })
      else
        Map<String, Color>.from({
          FFLocalizations.of(context).getVariableText(
              ptText: 'Retirado',
              enText: 'Picked up'): FlutterFlowTheme.of(context).primary,
        }),
      if (order['adresseeType'] == 'PRO')
        Map<String, Color>.from({
          FFLocalizations.of(context).getVariableText(
            ptText: 'Propriedade',
            enText: 'Property',
          ): FlutterFlowTheme.of(context).alternate2,
        })
      else if (order['adresseeType'] == 'MOR')
        Map<String, Color>.from({
          FFLocalizations.of(context).getVariableText(
            ptText: 'Morador',
            enText: 'Resident',
          ): FlutterFlowTheme.of(context).alternate2,
        })
    ];
  }

  Widget _item(BuildContext context, dynamic order) {
    return CardItemTemplateComponentWidget(
      imagePath: _imagePath(order),
      labelsHashMap: _labelsHashMap(order),
      statusHashMap: _statusHashMap(order),
      onTapCardItemAction: () async {
        showDialog(
            useSafeArea: true,
            context: context,
            builder: (context) {
              return Dialog(
                child: DetailsComponentWidget(
                  imagePath: _imagePath(order),
                  labelsHashMap: _labelsHashMapDialog(order),
                  statusHashMap: [
                    if (order['isPending'] == true)
                      Map<String, Color>.from({
                        FFLocalizations.of(context).getVariableText(
                                ptText: 'Aguardando Retirada',
                                enText: 'Waiting Pick up'):
                            FlutterFlowTheme.of(context).warning,
                      })
                    else
                      Map<String, Color>.from({
                        FFLocalizations.of(context).getVariableText(
                                ptText: 'Retirado', enText: 'Picked up'):
                            FlutterFlowTheme.of(context).primary,
                      }),
                  ],
                  buttons: const [],
                ),
              );
            });
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
      appBar: _appBar(context),
      body: _appBody(context),
    );
  }
}
