import 'dart:convert';

import 'package:easy_localization/easy_localization.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import '../repository/history_repository.dart';
import '../storage/sharedpreferences/shared_preferences_manager.dart';
import '../utils/U.dart';
import '../utils/cache_manager.dart';

enum HistoryTab {
  ongoing,
  done;

  List get filters {
    switch(this){
      case HistoryTab.ongoing:
        return [
          {'title': 'stateQueue'.tr(), 'value': 'queue', 'filter': '{"or":[{"f":["currentState","EQ","DIANTRIKAN"]},{"f":["currentState","EQ","DIPROSES"]}]}'},
          {'title': 'stateDone'.tr(), 'value': 'done', 'filter': '{"f":["currentState","EQ","DIMULAI"]}'},
          {'title': 'hold'.tr(), 'value': 'hold', 'filter': '{"f":["currentState","EQ","HOLD"]}'}
        ];
      case HistoryTab.done:
        return [
          {'title': 'stateFinish'.tr(), 'value': 'finish', 'filter': '{"or":[{"f":["currentState","EQ","DISELESAIKAN"]},{"f":["currentState","EQ","TUNTAS"]}]}'},
          {'title': 'stateCancel'.tr(), 'value': 'cancel', 'filter': '{"f":["currentState","EQ","DIBATALKAN"]}'}
        ];
    }
  }
}

class MenuHistoryState extends Equatable {
  final HistoryTab activeTab;
  final List<dynamic> pendingData;
  final List activeForum;
  final bool multiSelectMode;
  final List<int> selectedIndex;

  const MenuHistoryState({
    this.activeTab = HistoryTab.ongoing,
    this.pendingData = const [],
    this.activeForum = const [],
    this.multiSelectMode = false,
    this.selectedIndex = const [],
  });

  MenuHistoryState copyWith({
    HistoryTab? activeTab,
    List<dynamic>? pendingData,
    List? activeForum,
    bool? multiSelectMode,
    List<int>? selectedIndex,
  }){
    return MenuHistoryState(
      activeTab: activeTab ?? this.activeTab,
      pendingData: pendingData ?? this.pendingData,
      activeForum: activeForum ?? this.activeForum,
      multiSelectMode: multiSelectMode ?? this.multiSelectMode,
      selectedIndex: selectedIndex ?? this.selectedIndex,
    );
  }

  @override
  List<Object?> get props => [activeTab, pendingData, activeForum, multiSelectMode, selectedIndex];
}

class ReloadPage extends MenuHistoryState {}

class CreateNewRequest extends MenuHistoryState {
  final Map<String,dynamic> request;
  const CreateNewRequest(this.request);
}

class ShowError extends MenuHistoryState {
  final String error;
  const ShowError(this.error);
}

class MenuHistoryCubit extends Cubit<MenuHistoryState> {
  MenuHistoryCubit() : super(MenuHistoryState());
  final SharedPreferencesManager sharedPreferencesManager = SharedPreferencesManager();

  void init() {
    setActiveTab(HistoryTab.ongoing);
    getActiveForum();
    getPendingData();
  }

  void getPendingData() async {
    if(!U.getInternetStatus()){
      List pendingList = sharedPreferencesManager.isKeyExists(SharedPreferencesManager.keyPendingData)!?jsonDecode(sharedPreferencesManager.getString(SharedPreferencesManager.keyPendingData)!):[];
      setPendingData(pendingList);
    }
  }

  void setPendingData(List<dynamic> data){
    emit(state.copyWith(pendingData: data));
  }

  void setActiveTab(HistoryTab tab){
    emit(state.copyWith(activeTab: tab));
  }

  Future<void> getActiveForum() async {
    String url = '/api/notifications/search/forumNotification';
    var forum = [];

    // # check cache
    var cacheData = await CacheMan.readData(url);
    if(cacheData?['data'] != null){
      emit(state.copyWith(activeForum: cacheData['data']));
    }

    forum = await HistoryRepository().getActiveForum(url);
    emit(state.copyWith(activeForum: forum));
  }

  void setMultiSelectMode(bool val){
    emit(state.copyWith(multiSelectMode: val));
  }

  void selectIndex(int index){
    final updated = List<int>.from(state.selectedIndex);

    if(updated.contains(index)) {
      updated.remove(index);
    } else {
      updated.add(index);
    }

    if(updated.isEmpty){
      emit(state.copyWith(selectedIndex: [], multiSelectMode: false));
    } else {
      emit(state.copyWith(selectedIndex: updated, multiSelectMode: true));
    }
  }

  void deleteData(List<dynamic> data){
    List<String> params = [];

    for (var e in state.selectedIndex) {
      params.add(data[e]["ticketNo"]);
    }

    var res = HistoryRepository().deleteData(params);
    if (res != null) {
      emit(ReloadPage());
    }
  }

  Future<void> requestAgain(Map<String, dynamic> data) async {
    try {
      String tenant = '';
      String filter = '';

      if ((data['requestGroupCode']).split(" ").length != 1) {
        tenant = ',{"f":["tenantCode","EQ","${(data['requestGroupCode']).split(" ").first}"]}';
      }
      filter = '{"and":[{"f":["code","EQ","${data['requestCode']}"]}$tenant]}';

      var res = await HistoryRepository().checkRequest(filter);
      if (res.isNotEmpty) {
        if (res.containsKey('_embedded')) {
          emit(CreateNewRequest(res['_embedded']['requests'][0]));
        } else {
          emit(ShowError('reqCodeNotFound'.tr()));
        }
      }
    } catch (e) {
      emit(ShowError("Err: ${e.toString()}"));
    }
  }
}