import 'package:redux/redux.dart';
import 'package:meta/meta.dart';
import 'package:redux_thunk/redux_thunk.dart';
import 'package:satu/core/models/auth/auth_response.dart';
import 'package:satu/core/redux/state/user_state.dart';
import 'package:satu/core/services/api_service.dart';
import 'package:satu/core/services/dialog_service.dart';
import 'package:satu/core/services/dictionary_service.dart';
import 'package:satu/core/services/navigator_service.dart';
import 'package:satu/core/utils/locator.dart';
import 'package:satu/routes/route_names.dart';
import '../store.dart';

@immutable
class SetUserStateAction {
  final UserState userState;
  SetUserStateAction(this.userState);
}

final ApiService _api = locator<ApiService>();
final NavigatorService _navigation = locator<NavigatorService>();
final DialogService _dialogService = locator<DialogService>();

final DictionaryService _dictionaryService = locator<DictionaryService>();


ThunkAction<AppState> authenticate(String email, String password) {
  return (Store<AppState> store) async {
    store.dispatch(SetUserStateAction(UserState(isLoading: true)));
    try {
      AuthResponse result = await _api.login(email, password);
      if ( result.operation!) {
        _api.token = result.token!;
        store.dispatch(SetUserStateAction(UserState(isLoading: false, auth: result)));
        _navigation.replace(mainViewRoute);
        _afterAuth(store);
      } else {
        _dialogService.showDialog(title: 'Внимание', buttonTitle: 'Ok', description: result.message!);
      }
    } catch (e) {
      print(e);
    } finally {
      store.dispatch(SetUserStateAction(UserState(isLoading: false)));
    }
  };
}

ThunkAction<AppState> authenticateByToken(String token) {
  return (Store<AppState> store) async {
    store.dispatch(SetUserStateAction(UserState(isLoading: true)));
    try {
      AuthResponse result = await _api.authorization(token);
      if ( result.operation!) {
        _api.token = result.token!;
        store.dispatch(SetUserStateAction(UserState(isLoading: false, auth: result)));
        _navigation.replace(mainViewRoute);
        _afterAuth(store);
      } else {
        _dialogService.showDialog(title: 'Внимание', buttonTitle: 'Ok', description: result.message!);
      }
    } catch (e) {
      print(e);
    } finally {
      store.dispatch(SetUserStateAction(UserState(isLoading: false)));
    }
  };
}

Future<void> auth(Store<AppState> store) async {
  store.dispatch(SetUserStateAction(UserState(isLoading: true)));
  try {
    UserState? state  =  store.state.userState;
    if(state != null) {
      if (state.auth?.operation == false) {
        _navigation.replace(loginViewRoute);
      } else {
        AuthResponse response = await _api.auth(state.auth?.token ?? '');
        if (response.operation!) {
          _api.token = response.token!;
          _navigation.replace(mainViewRoute);
          _afterAuth(store);
        } else {
          _navigation.replace(loginViewRoute);
        }
      }
    } else {
      _navigation.replace(loginViewRoute);
    }
  } catch (e) {
    print(e);
  } finally {
    store.dispatch(SetUserStateAction(UserState(isLoading: false)));
  }
}

Future<void> logout(Store<AppState> store) async {
  store.dispatch(SetUserStateAction(UserState(isLoading: true)));
  try {
    AuthResponse result = await _api.logout();
    if (result.operation!) {
      _api.token = null;
      store.dispatch(SetUserStateAction(UserState(isLoading: false, auth: AuthResponse())));
      _navigation.replace(loginViewRoute);
    } else {
      _dialogService.showDialog(title: 'Внимание', buttonTitle: 'Ok', description: result.message!);
    }
  } catch (e) {
    print(e);
  } finally {
    store.dispatch(SetUserStateAction(UserState(isLoading: false)));
  }
}

Future<void> _afterAuth(Store<AppState> store) async {
  await _dictionaryService.refreshFull();
}

