import 'dart:convert';

import 'package:e_commerce_training/src/model/preference/app_preference.dart';
import 'package:e_commerce_training/src/model/repository/app_repository.dart';
import 'package:e_commerce_training/src/model/response/home_config_response.dart';
import 'package:e_commerce_training/src/model/response/notification_response.dart';
import 'package:e_commerce_training/src/model/service/api_result.dart';
import 'package:e_commerce_training/src/model/service/network_exceptions.dart';
import 'package:e_commerce_training/src/page/main/main_state.dart';
import 'package:e_commerce_training/src/util/const.dart';
import 'package:e_commerce_training/src/util/logger.dart';
import 'package:e_commerce_training/src/util/util.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class MainCubit extends Cubit<MainState> {
  final AppRepository repository;
  late FirebaseMessaging _firebaseMessaging;
  int prePosition = 0;
  int countProduct = 0;
  int countUnRead = 0;
  String searchKeyword = "";
  List<SliderData> slider = [];

  String? get token => appPreference.getData(Const.TOKEN);

  String? get deviceToken => appPreference.getData(Const.DEVICE_TOKEN);

  String? get phoneNumber => appPreference.getData(Const.COMPANY_PHONE_NUMBER);

  bool get isLoggedIn => !Util.isEmpty(token);

  MainCubit(this.repository) : super(MainInitial()) {
    Future.delayed(Duration(seconds: 1), () {
      _firebaseMessaging = FirebaseMessaging.instance;
      _registerNotification();
      _firebaseMessaging.getToken().then((token) {
        logger.d(token);
        repository.registerDeviceToken(token!);
        appPreference.setData(Const.DEVICE_TOKEN, token);
      });
      _firebaseMessaging.getInitialMessage().then((RemoteMessage? message) {
        logger.d('on terminal', message?.data);
        handleClickNotification(_handleParseNotification(message));
      });
    });
  }

  void getHomeConfig() async {
    // TODO call api home config
    emit(MainLoading());
    ApiResult<HomeConfigResponse> homeConfigData = await repository.getHomeConfig();
    homeConfigData.when(success: (HomeConfigResponse response) async {
      HomeConfigData? data = response.data;
      if (data != null) {
        appPreference.setData(Const.PHONE_NUMBER_SUPPORT, data.phoneNumber);
        searchKeyword = data.searchKeyword ?? "";
        slider = data.sliders ?? [];
      }
      emit(MainInitial());
    }, failure: (NetworkExceptions error) async {
      emit(MainFailure(NetworkExceptions.getErrorMessage(error)));
      try {
        HomeConfigResponse response = HomeConfigResponse.fromJson(await Util.parseJson("home_config.json"));
        HomeConfigData? data = response.data;
        if (data != null) {
          appPreference.setData(Const.PHONE_NUMBER_SUPPORT, data.phoneNumber);
          searchKeyword = data.searchKeyword ?? "";
          slider = data.sliders ?? [];
        }
      } catch (e) {
        logger.e(e.toString());
      }
    });
  }

  void getCountNotification() async {
    emit(MainLoading());
    if (isLoggedIn) {
      ApiResult<NotificationResponse> notificationData =
          await repository.getListNotification(deviceToken: deviceToken, userToken: token, isReaded: false);
      notificationData.when(success: (NotificationResponse response) async {
        countUnRead = response.totalRecord ?? 0;
        await Util.updateBadge(countUnRead);
        emit(MainInitial());
      }, failure: (NetworkExceptions error) async {
        emit(MainFailure(NetworkExceptions.getErrorMessage(error)));
        try {
          NotificationResponse response = NotificationResponse.fromJson(await Util.parseJson("notification.json"));
          countUnRead = response.totalRecord ?? 0;
          await Util.updateBadge(countUnRead);
        } catch (e) {
          logger.e(e.toString());
        }
      });
    }
  }

  void selectTab(int position) {
    if (prePosition == position) return;
    prePosition = position;
    emit(MainLoading());
    emit(MainPageState(position));
  }

  void showForegroundNotificationEvent(String title, String body, NotificationData data) {
    emit(MainLoading());
    emit(ShowForegroundNotificationSuccess(title, body, data));
  }

  void refreshMainEvent() {
    emit(MainLoading());
    emit(RefreshMainState());
  }

  void refreshAfterAuthenticateEvent() {
    emit(MainLoading());
    emit(RefreshAfterAuthenticateState());
  }

  void showNewNotification(NotificationData data) {
    emit(MainLoading());
    emit(NavigateToNotificationState(data));
  }

  void _registerNotification() {
    getIosPermission();
    try {
      FirebaseMessaging.onMessage.listen((RemoteMessage message) {
        logger.d('on message', message.data);
        NotificationData? data = _handleParseNotification(message);
        if (data != null) {
          showForegroundNotificationEvent(message.notification?.title ?? "", message.notification?.body ?? "", data);
        }
      });

      FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
        logger.d('on background', message.data);
        handleClickNotification(_handleParseNotification(message));
      });
    } catch (e) {
      logger.e(e);
    }
  }

  void getIosPermission() {
    _firebaseMessaging
        .requestPermission(
          alert: true,
          announcement: false,
          badge: true,
          carPlay: false,
          criticalAlert: false,
          provisional: false,
          sound: true,
        )
        .then((value) => logger.d('User granted permission: ${value.authorizationStatus}'));
  }

  NotificationData? _handleParseNotification(RemoteMessage? message) {
    dynamic data = message?.data;
    if (data == null) return null;
    try {
      NotificationData data = NotificationData.fromJson(json.decode(message!.data['payload']));
      return data;
    } catch (e) {
      logger.e(e.toString());
    }
    return null;
  }

  void handleClickNotification(NotificationData? data) {
    if (data == null) return;
  }
}
