import 'dart:async';
import 'dart:io';

import 'package:fcs/data/services/services.dart';
import 'package:fcs/domain/entities/package.dart';
import 'package:fcs/domain/entities/user.dart';
import 'package:fcs/helpers/shared_pref.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/localization/transalation.dart';
import 'package:fcs/pages/carton/carton_list.dart';
import 'package:fcs/pages/chat/message_detail.dart';
import 'package:fcs/pages/chat/model/message_model.dart';
import 'package:fcs/pages/customer/customer_list.dart';
import 'package:fcs/pages/customer/model/customer_model.dart';
import 'package:fcs/pages/delivery/delivery_list.dart';
import 'package:fcs/pages/discount/discount_list.dart';
import 'package:fcs/pages/faq/faq_list_page.dart';
import 'package:fcs/pages/fcs_shipment/fcs_shipment_list.dart';
import 'package:fcs/pages/invoice/invoice_list.dart';
import 'package:fcs/pages/main/model/language_model.dart';
import 'package:fcs/pages/main/model/main_model.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/package/model/package_model.dart';
import 'package:fcs/pages/package/package_info.dart';
import 'package:fcs/pages/package/package_list.dart';
import 'package:fcs/pages/processing/processing_list.dart';
import 'package:fcs/pages/receiving/receiving_list.dart';
import 'package:fcs/pages/shipment/shipment_list.dart';
import 'package:fcs/pages/staff/staff_list.dart';
import 'package:fcs/pages/widgets/badge.dart';
import 'package:fcs/pages/widgets/bottom_widgets.dart';
import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/progress.dart';
import 'package:fcs/pages/widgets/right_left_page_rout.dart';
import 'package:fcs/pages/widgets/task_button.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:logging/logging.dart';
import 'package:provider/provider.dart';

import '../profile/profile_page.dart';
import '../signin/signin_page.dart';
import '../widgets/banner.dart';
import '../widgets/offline_redirect.dart';

final msgLog = Logger('backgroundMessageHandler');

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final log = Logger('_HomePageState');
  bool login = false;
  bool _isLoading = false;
  List<bool> isSelected = [true, false];
  static FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();
  TextEditingController _searchCtl = TextEditingController();
  List<bool> isFcs = [false];

  @override
  void initState() {
    super.initState();
    MainModel mainModel = Provider.of<MainModel>(context, listen: false);

    Services.instance.messagingService.init(
        (message) {
          print("Message from FCM:$message");
          _showNotification(message);
        },
        onLaunch: (m) => _showNotiContent(m),
        onResume: (m) => _showNotiContent(m),
        onSetupComplete: (token) {
          mainModel.setMessaginToken = token;
        });
    _initLocalNotifications();
    _loadStaffMode(mainModel.isCustomer());
  }

  _loadStaffMode(bool isCustomer) async {
    bool staffMode = await SharedPref.getStaffMode();
    setState(() {
      if (isCustomer) {
        isFcs[0] = false;
      } else {
        isFcs[0] = staffMode ?? false;
      }
    });
  }

  String notiUserID, notiUserName;
  _showNotiContent(Map<String, dynamic> message) {
    try {
      Map<String, dynamic> map = Map<String, dynamic>.from(message["data"]);
      notiUserID = map['user_id'];
      notiUserName = map['user_name'];
      _startNotiTimer();
      print("Notification:$map");
    } catch (e) {
      print("Error:$e");
    }
  }

  _startNotiTimer() async {
    var _duration = new Duration(milliseconds: 500);
    new Timer.periodic(_duration, (t) => displayNoti(t));
  }

  void displayNoti(Timer timer) async {
    MainModel mainModel = Provider.of<MainModel>(context, listen: false);
    if (mainModel.isLogin()) {
      timer.cancel();
      bool isCustomer = mainModel.isCustomer();
      String receiverID = isCustomer ? mainModel.user.id : notiUserID;
      String receiverName = isCustomer ? mainModel.user.name : notiUserName;
      MessageModel messageModel =
          Provider.of<MessageModel>(context, listen: false);
      messageModel.initQuery(receiverID);
      User user = mainModel.user;
      if (!isCustomer) {
        CustomerModel customerModel =
            Provider.of<CustomerModel>(context, listen: false);
        user = await customerModel.getUser(receiverID);
      }
      Navigator.push(
          context,
          MaterialPageRoute(
              builder: (context) => MessageDetail(
                    messageModel: messageModel,
                    receiverID: receiverID,
                    receiverName: receiverName,
                  ))).then((value) {
        if (user.userUnseenCount > 0) {
          messageModel.seenMessages(user.id, true);
        }
      });
      if (user.userUnseenCount > 0) {
        messageModel.seenMessages(user.id, true);
      }
    }
  }

  _initLocalNotifications() {
    var initializationSettingsAndroid =
        new AndroidInitializationSettings('@mipmap/ic_launcher');
    var initializationSettingsIOS = new IOSInitializationSettings();
    var initializationSettings = new InitializationSettings(
        initializationSettingsAndroid, initializationSettingsIOS);
    _flutterLocalNotificationsPlugin.initialize(initializationSettings);
  }

  static Future _showNotification(Map<String, dynamic> message) async {
    var pushTitle;
    var pushText;
    var action;

    if (Platform.isAndroid) {
      var nodeData = message['notification'];
      pushTitle = nodeData['title'];
      pushText = nodeData['body'];
      action = nodeData['action'];
    } else {
      pushTitle = message['title'];
      pushText = message['body'];
      action = message['action'];
    }
    print("AppPushs params pushTitle : $pushTitle");
    print("AppPushs params pushText : $pushText");
    print("AppPushs params pushAction : $action");

    // @formatter:off
    var platformChannelSpecificsAndroid = new AndroidNotificationDetails(
        'your channel id', 'your channel name', 'your channel description',
        playSound: true,
        enableVibration: true,
        importance: Importance.Max,
        priority: Priority.High);
    // @formatter:on
    var platformChannelSpecificsIos =
        new IOSNotificationDetails(presentSound: true);
    var platformChannelSpecifics = new NotificationDetails(
        platformChannelSpecificsAndroid, platformChannelSpecificsIos);

    new Future.delayed(Duration.zero, () {
      _flutterLocalNotificationsPlugin.show(
        0,
        pushTitle,
        pushText,
        platformChannelSpecifics,
        payload: 'No_Sound',
      );
    });
  }

  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    User user = Provider.of<MainModel>(context).user;

    if (user == null) {
      Future.microtask(
          () => Navigator.pushNamedAndRemoveUntil(context, "/", (r) => false));
      return Container();
    }

    login = Provider.of<MainModel>(context).isLogin();
    LanguageModel languageModel = Provider.of<LanguageModel>(context);

    final faqBtn = TaskButton("faq.btn",
        icon: MaterialCommunityIcons.frequently_asked_questions,
        btnCallback: () => Navigator.of(context).push(CupertinoPageRoute(
              builder: (context) => FAQListPage(),
            )));

    final packagesBtn = TaskButton("package.btn.name",
        icon: Octicons.package,
        btnCallback: () => Navigator.of(context).push<void>(
            CupertinoPageRoute(builder: (context) => PackageList())));
    final packagesBtnFcs = TaskButton("package.btn.name",
        icon: Octicons.package,
        btnCallback: () => Navigator.of(context).push<void>(CupertinoPageRoute(
            builder: (context) => PackageList(
                  forCustomer: false,
                ))));

    final receivingBtn = TaskButton("receiving.title",
        icon: MaterialCommunityIcons.inbox_arrow_down,
        btnCallback: () => Navigator.of(context).push<void>(
            CupertinoPageRoute(builder: (context) => ReceivingList())));

    final processingBtn = TaskButton("processing.title",
        icon: FontAwesome.dropbox,
        btnCallback: () => Navigator.of(context).push<void>(
            CupertinoPageRoute(builder: (context) => ProcessingList())));
    final cartonBtn = TaskButton("boxes.name",
        icon: MaterialCommunityIcons.package,
        btnCallback: () => Navigator.of(context).push<void>(
            CupertinoPageRoute(builder: (context) => CartonList())));

    final shipmentBtn = TaskButton("shipment",
        icon: SimpleLineIcons.direction,
        btnCallback: () => Navigator.of(context)
            .push(CupertinoPageRoute(builder: (context) => ShipmentList())));

    final shipmentBtnFcs = TaskButton("shipment",
        icon: SimpleLineIcons.direction,
        btnCallback: () => Navigator.of(context).push(CupertinoPageRoute(
            builder: (context) => ShipmentList(
                  forCustomer: false,
                ))));

    final fcsShipmentBtn = TaskButton("FCSshipment.title",
        icon: Ionicons.ios_airplane,
        btnCallback: () => Navigator.of(context).push(CupertinoPageRoute(
              builder: (context) => FcsShipmentList(),
            )));
    final notiBtnOrg =
        TaskButton("message.btn", icon: Icons.message, btnCallback: () {
      MessageModel messageModel =
          Provider.of<MessageModel>(context, listen: false);
      messageModel.initQuery(user.id);
      Navigator.of(context)
          .push(CupertinoPageRoute(
        builder: (context) => MessageDetail(messageModel: messageModel),
      ))
          .then((value) {
        if (user.userUnseenCount > 0) {
          messageModel.seenMessages(user.id, true);
        }
      });
      if (user.userUnseenCount > 0) {
        messageModel.seenMessages(user.id, true);
      }
    });
    final notiBtn = badgeCounter(notiBtnOrg, user.userUnseenCount);

    final staffBtn = TaskButton(
      "staff.title",
      icon: MaterialCommunityIcons.worker,
      btnCallback: () => Navigator.of(context).push<void>(CupertinoPageRoute(
        builder: (context) => StaffList(),
      )),
    );

    final customersBtn = TaskButton("customers.btn",
        icon: Feather.users,
        btnCallback: () => Navigator.of(context).push<void>(CupertinoPageRoute(
              builder: (context) => CustomerList(),
            )));

    final invoicesBtn = TaskButton("invoices.btn",
        icon: FontAwesomeIcons.fileInvoice,
        btnCallback: () => Navigator.of(context).push<void>(CupertinoPageRoute(
            builder: (context) => InvoiceList(forCustomer: true))));
    final invoicesBtnFcs = TaskButton("invoices.btn",
        icon: FontAwesomeIcons.fileInvoice,
        btnCallback: () => Navigator.of(context).push<void>(CupertinoPageRoute(
            builder: (context) => InvoiceList(forCustomer: false))));

    final discountBtn = TaskButton("discount.btn",
        icon: Entypo.price_ribbon,
        btnCallback: () => Navigator.of(context).push<void>(
            CupertinoPageRoute(builder: (context) => DiscountList())));

    final deliveryBtn = TaskButton("delivery.title",
        icon: MaterialCommunityIcons.truck_fast,
        btnCallback: () => Navigator.of(context).push<void>(
            CupertinoPageRoute(builder: (context) => DeliverList())));

    List<Widget> widgets = [];
    List<Widget> widgetsFcs = [];
    widgets.add(notiBtn);
    if (user.joined) {
      widgets.add(packagesBtn);
      widgets.add(shipmentBtn);
      widgets.add(invoicesBtn);

      if (user.hasPackages()) widgetsFcs.add(packagesBtnFcs);
      if (user.hasShipment()) widgetsFcs.add(shipmentBtnFcs);
      if (user.hasInvoices()) widgetsFcs.add(invoicesBtnFcs);

      if (user.hasFcsShipments()) widgetsFcs.add(fcsShipmentBtn);
      if (user.hasReceiving()) widgetsFcs.add(receivingBtn);
      if (user.hasProcessing()) widgetsFcs.add(processingBtn);
      if (user.hasCarton()) widgetsFcs.add(cartonBtn);
      if (user.hasDeliveries()) widgetsFcs.add(deliveryBtn);
      if (user.hasCustomers()) widgetsFcs.add(customersBtn);
      if (user.hasAdmin()) widgetsFcs.add(discountBtn);
      if (user.hasStaffs()) widgetsFcs.add(staffBtn);
    }
    widgets.add(faqBtn);

    final fcsToggle = ToggleButtons(
      selectedColor: Colors.white,
      color: Colors.blue,
      children: <Widget>[
        Icon(MaterialCommunityIcons.worker),
      ],
      onPressed: (i) => this.setState(() {
        isFcs[0] = !isFcs[0];
        SharedPref.saveStaffMode(isFcs[0]);
      }),
      isSelected: isFcs,
      selectedBorderColor: Colors.white24,
    );
    final langToggle = ToggleButtons(
      children: <Widget>[
        Image.asset(
          'icons/flags/png/us.png',
          package: 'country_icons',
          fit: BoxFit.fitWidth,
          width: 25,
        ),
        Image.asset(
          'icons/flags/png/mm.png',
          package: 'country_icons',
          fit: BoxFit.fitWidth,
          width: 25,
        )
      ],
      onPressed: _langChange,
      isSelected: languageModel.currentState,
      selectedBorderColor: Colors.white24,
    );
    final signinBtn = FlatButton(
      onPressed: () {
        Navigator.of(context)
            .push(CupertinoPageRoute(builder: (context) => SigninPage()));
      },
      child: Text(
        "Sign In",
        style: siginButtonStyle,
      ),
    );
    final profileBtn = IconButton(
      onPressed: () {
        Navigator.of(context).push(RightLeftPageRoute(Profile()));
      },
      iconSize: 30,
      icon: Icon(Icons.account_circle),
    );

    var searchInput = Row(children: [
      Expanded(
        child: Padding(
          padding: const EdgeInsets.only(bottom: 3, left: 5, right: 5, top: 3),
          child: Theme(
            data: new ThemeData(
              primaryColor: primaryColor,
              primaryColorDark: primaryColor,
            ),
            child: TextField(
              style: TextStyle(color: Colors.white),
              controller: _searchCtl,
              scrollPadding: EdgeInsets.all(0),
              decoration: new InputDecoration(
                  enabledBorder: const OutlineInputBorder(
                    borderRadius: BorderRadius.all(Radius.circular(30)),
                    borderSide:
                        const BorderSide(color: Colors.white, width: 1.5),
                  ),
                  focusedBorder: const OutlineInputBorder(
                    borderRadius: BorderRadius.all(Radius.circular(30)),
                    borderSide:
                        const BorderSide(color: Colors.white, width: 1.5),
                  ),
                  contentPadding: EdgeInsets.only(top: 1, bottom: 1),
                  isDense: true,
                  hintText: getLocalString(context, "home.search"),
                  hintStyle: languageModel.isEng
                      ? newLabelStyle(color: Colors.white60)
                      : newLabelStyleMM(color: Colors.white60),
                  prefixIcon: const Icon(
                    Icons.search,
                    color: Colors.grey,
                  ),
                  suffixIcon: InkWell(
                    onTap: () => {_searchCtl.clear()},
                    child: const Icon(
                      Icons.close,
                      color: Colors.grey,
                    ),
                  ),
                  suffixStyle: const TextStyle(color: primaryColor)),
            ),
          ),
        ),
      ),
      InkWell(
        child: Padding(
          padding: const EdgeInsets.all(10.0),
          child: LocalText(
            context,
            "home.search.btn",
            color: Colors.white,
          ),
        ),
        onTap: _lookup,
      )
    ]);
    widgets.insert(0, searchInput);

    return LocalProgress(
      inAsyncCall: _isLoading,
      child: OfflineRedirect(
        child: FlavorBanner(
          child: Scaffold(
              appBar: AppBar(
                  elevation: 0,
                  backgroundColor: primaryColor,
                  title: ClipRRect(
                    child: Image.asset("assets/logo.jpg", height: 40),
                    borderRadius: new BorderRadius.circular(30.0),
                  ),
                  actions: login
                      ? user.isCustomer()
                          ? <Widget>[
                              langToggle,
                              profileBtn,
                            ]
                          : <Widget>[
                              fcsToggle,
                              langToggle,
                              profileBtn,
                            ]
                      : <Widget>[
                          langToggle,
                          signinBtn,
                        ]),
              body: Container(
                  decoration: BoxDecoration(
                    gradient: LinearGradient(
                      begin: Alignment.topCenter,
                      end: Alignment.bottomCenter,
                      colors: [
                        Color(0xd0272262),
                        Color(0xfa272262),
                      ],
                    ),
                  ),
                  child: ListView(
                    children: <Widget>[
                      Column(children: [
                        Wrap(
                          alignment: WrapAlignment.center,
                          children: isFcs[0] ? widgetsFcs : widgets,
                        ),
                      ]),
                      SizedBox(height: 50),
                      BottomWidgets(),
                    ],
                  ))),
        ),
      ),
    );
  }

  _langChange(index) {
    var languageModel = Provider.of<LanguageModel>(context, listen: false);
    languageModel.saveLanguage(Translation().supportedLanguages[index]);
    setState(() {
      isSelected.asMap().forEach((i, e) {
        isSelected[i] = false;
      });
      isSelected[index] = !isSelected[index];
    });
  }

  _lookup() async {
    setState(() {
      _isLoading = true;
    });

    try {
      String term = _searchCtl.text;
      if (term == null || term.trim() == "") return;
      var packageModel = Provider.of<PackageModel>(context, listen: false);
      Package package = await packageModel.lookupPackage(term);
      if (package == null) {
        showMsgDialog(context, "Not found", "Tracking ID - '$term' not found!");
        return;
      }
      Navigator.push(
        context,
        CupertinoPageRoute(
            builder: (context) => PackageInfo(
                  package: package,
                  isSearchResult: true,
                )),
      );
    } catch (e) {
      showMsgDialog(context, "Error", e.toString());
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }
}
