import 'package:farm_tpf/custom_model/NotificationDTO.dart';
import 'package:farm_tpf/data/repository/repository.dart';
import 'package:farm_tpf/presentation/custom_widgets/bottom_loader.dart';
import 'package:farm_tpf/presentation/custom_widgets/dash_line_widget.dart';
import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart';
import 'package:farm_tpf/presentation/screens/notification/update_count_noti_bloc.dart';
import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart';
import 'package:farm_tpf/utils/NotificationsBloc.dart';
import 'package:farm_tpf/utils/const_icons.dart';
import 'package:farm_tpf/utils/pref.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:farm_tpf/utils/formatter.dart';
import 'package:flutter_svg/svg.dart';

import 'bloc/noti_bloc.dart';

class NotificationScreen extends StatefulWidget {
  @override
  _NotificationScreenState createState() => _NotificationScreenState();
}

class _NotificationScreenState extends State<NotificationScreen> {
  var notiBloc = NotiBloc(repository: Repository());

  final _scrollController = ScrollController();
  final _scrollThreshold = 250.0;
  List<NotificationDTO> currentItems = <NotificationDTO>[];
  int latestId = 0;
  int currentPage = 0;
  bool currentHasReachedMax = true;
  bool isUpdatingFromApi = true;
  Stream<LocalNotification>? _notificationsStream;

  var pref = LocalPref();
  var token;
  Future<Null> getSharedPrefs() async {
    _scrollController.addListener(() {
      final maxScroll = _scrollController.position.maxScrollExtent;
      final currentScroll = _scrollController.position.pixels;
      if (maxScroll - currentScroll < _scrollThreshold) {
        notiBloc.add(DataFetched());
      }
    });
    token = await pref.getString(DATA_CONST.TOKEN_KEY);
  }

  @override
  void initState() {
    getSharedPrefs();
    notiBloc.add(DataFetched());
    _notificationsStream = NotificationsBloc.instance.notificationsStream;
    _notificationsStream?.listen((notification) {
      updateCountNotiBloc.getNotifications((data) {}, (err) {});
      print('Notification: $notification');
      notiBloc.add(OnRefresh());
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<NotiBloc, NotiState>(
      bloc: notiBloc,
      builder: (context, state) {
        if (state is NotiFailure) {
          return Center(child: Text(state.errorString));
        } else if (state is NotiSuccess) {
          updateCountNotiBloc.getNotifications((data) {}, (err) {});
          if (state.items.isEmpty) {
            return SafeArea(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const SizedBox(
                    height: 8,
                  ),
                  const Padding(
                    padding: EdgeInsets.all(8.0),
                    child: Text('Thông báo', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22)),
                  ),
                  const Expanded(
                    child: Center(child: Text("Không có thông báo")),
                  ),
                ],
              ),
            );
          }
          currentItems = List<NotificationDTO>.from(state.items);
          currentPage = state.page;
          currentHasReachedMax = state.hasReachedMax;

          return SafeArea(
            child: Column(
              children: <Widget>[
                Container(
                    padding: const EdgeInsets.all(8),
                    color: Colors.white,
                    child: Row(
                      children: [
                        const SizedBox(
                          height: 8,
                        ),
                        const Expanded(
                            child: Text(
                          'Thông báo',
                          style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
                        )),
                        FlatButton(
                            onPressed: () {
                              notiBloc.add(MarkAllNotificationUpdate(status: "1"));
                            },
                            child: const Text('Đánh dấu đã đọc tất cả',
                                style: TextStyle(fontWeight: FontWeight.normal, fontSize: 14, color: Colors.blue)))
                      ],
                    )),
                Expanded(
                    child: RefreshIndicator(
                        child: ListView.builder(
                          physics: const AlwaysScrollableScrollPhysics(),
                          itemBuilder: (BuildContext context, int index) {
                            return index >= state.items.length
                                ? BottomLoader()
                                : ItemInfinityWidget(
                                    notiBloc: notiBloc,
                                    unread: state.unread ?? 0,
                                    read: state.read ?? 0,
                                    currentItems: currentItems,
                                    item: state.items[index],
                                    currentPage: state.page,
                                    currentReachedMax: state.hasReachedMax,
                                  );
                          },
                          itemCount: state.hasReachedMax ? state.items.length : state.items.length + 1,
                          controller: _scrollController,
                        ),
                        onRefresh: () async {
                          notiBloc.add(OnRefresh());
                        }))
              ],
            ),
          );
        } else if (state is NotiLoadding) {
          return Center(
            child: LoadingListPage(),
          );
        }
        return Container();
      },
    );
  }

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

class ItemInfinityWidget extends StatelessWidget {
  final int unread;
  final int read;
  final NotificationDTO item;
  final List<NotificationDTO> currentItems;
  final int currentPage;
  final bool currentReachedMax;
  final NotiBloc notiBloc;

  const ItemInfinityWidget(
      {Key? key,
      required this.unread,
      required this.read,
      required this.currentItems,
      required this.item,
      required this.currentPage,
      required this.currentReachedMax,
      required this.notiBloc})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    var type;
    try {
      type = int.parse(item.type ?? '0');
    } catch (_) {
      type = -1;
    }
    return Column(
      children: [
        GestureDetector(
            child: Container(
                margin: const EdgeInsets.all(4.0),
                child: Column(
                  children: [
                    ListTile(
                        title: Text(item.subject ?? ''),
                        subtitle: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            Text(item.message ?? ''),
                            Row(children: [
                              Icon(Icons.access_time, color: item.isRead == 1 ? Colors.grey : Colors.blue, size: 18),
                              const SizedBox(
                                width: 4,
                              ),
                              Text(item.sendDate?.format_DDMMYY_HHmm() ?? '', style: TextStyle(color: item.isRead == 1 ? Colors.grey : Colors.blue))
                            ]),
                          ],
                        ),
                        leading: SvgPicture.asset(AppIcons.icNotificationItem)),
                  ],
                )),
            onTap: () {
              if (item.contents == "ENV_UPDATE") {
                Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (BuildContext context) => PlotDetailScreen(
                              cropType: type,
                              cropId: item.tbCropId,
                              initialIndex: 0,
                            ))).then((value) {
                  if (item.isRead == 0) {
                    _updateReadNotification(
                        context: context,
                        unread: unread,
                        read: read,
                        item: item,
                        currentItems: currentItems,
                        currentPage: currentPage,
                        currentReachedMax: currentReachedMax);
                  }
                });
              } else if (item.contents == "PIC_UPDATE") {
                Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (BuildContext context) => PlotDetailScreen(
                              cropType: type,
                              cropId: item.tbCropId,
                              initialIndex: 1,
                            ))).then((value) {
                  if (item.isRead == 0) {
                    _updateReadNotification(
                        context: context,
                        unread: unread,
                        read: read,
                        item: item,
                        currentItems: currentItems,
                        currentPage: currentPage,
                        currentReachedMax: currentReachedMax);
                  }
                });
              } else {}
            }),
        Container(padding: const EdgeInsets.only(left: 16, right: 16), child: const DashLineWidget())
      ],
    );
  }

  _updateReadNotification(
      {required BuildContext context,
      required int unread,
      required int read,
      required NotificationDTO item,
      required List<NotificationDTO> currentItems,
      required int currentPage,
      required bool currentReachedMax}) {
    var updatedItems = <NotificationDTO>[];
    currentItems.forEach((e) {
      if (e.id == item.id) {
        e.isRead = 1;
      } else {}
      updatedItems.add(NotificationDTO.clone(e));
    });

    notiBloc.add(OnUpdate<NotificationDTO>(
        unread: unread - 1,
        read: read + 1,
        currentItemId: item.id,
        currentItems: updatedItems,
        currentPage: currentPage,
        hasReachedMax: currentReachedMax));
  }
}
