import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/message.dart';
import 'package:aman_kassa_flutter/core/models/auth_response.dart';
import 'package:aman_kassa_flutter/core/models/money.dart';
import 'package:aman_kassa_flutter/core/models/response.dart';
import 'package:aman_kassa_flutter/core/models/smena.dart';
import 'package:aman_kassa_flutter/core/models/user.dart';
import 'package:aman_kassa_flutter/core/route_names.dart';
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
import 'package:aman_kassa_flutter/redux/constants/auth_type_const.dart';
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
import 'package:aman_kassa_flutter/views/login/login_view.dart';
import 'package:redux/redux.dart';
import 'package:meta/meta.dart';
import 'package:redux_thunk/redux_thunk.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>();

Future<void> checkUserAction(Store<AppState> store) async {
  store.dispatch(SetUserStateAction(UserState(isLoading: true)));
  try {
    User? user = store.state.userState?.user;
    String? token = user?.token;
    bool isAuthenticated = false;
    if (token != null && user !=null) {
      if(user.email!=null && user.email!.toLowerCase().trim().startsWith('test')){
        _api.test = true;
      } else {
        _api.test = false;
      }
      Response<Message> session = await _api.isActive(token);
      isAuthenticated = "OK" == session.body?.message;

    } else {
      await Future.delayed(Duration(milliseconds: 2000));
    }
    store.dispatch(
      SetUserStateAction(
        UserState(
          isLoading: false,
          isAuthenticated: isAuthenticated,
        ),
      ),
    );

    if (!isAuthenticated) {
      _navigation.replace(LoginViewRoute, arguments: LoginModel());
    } else {
      _navigation.replace(HomeViewRoute);
    }
  } catch (error) {
    print(error);
    store.dispatch(SetUserStateAction(UserState(isLoading: false)));
  }
}

Future<void> logoutAction(Store<AppState> store) async {
  try {
    store.dispatch(
      SetUserStateAction(
        UserState(
          isLoading: false,
          isAuthenticated: false,
          user: User()
        ),
      ),
    );
    _navigation.replace(LoginViewRoute, arguments: LoginModel());
  } catch (error) {
    store.dispatch(SetUserStateAction(UserState(isLoading: false)));
  }
}

Future<Response<dynamic>?> checkMoney(Store<AppState> store) async {
  store.dispatch(SetUserStateAction(UserState(money: Money(loading: true))));
  try {
    Response<dynamic> result =
        await _api.money(store.state.userState!.user!.token!);
    if (result.operation) {
      store.dispatch(SetUserStateAction(UserState(
          money: Money(
              total: double.parse(result.body['money']), loading: false))));
    } else {
      store.dispatch(
          SetUserStateAction(UserState(money: Money(loading: false))));
    }
    return result;
  } catch (error) {
    store.dispatch(SetUserStateAction(UserState(money: Money(loading: false))));
    return null;
  }
}

ThunkAction<AppState> authenticateToken(String token) {
  return (Store<AppState> store) async {
    store.dispatch(SetUserStateAction(UserState(isLoading: true)));
    try {
      AuthBody result =
          await _api.authenticateToken(token, statusCheck: false);
      store.dispatch(SetUserStateAction(UserState(
        isLoading: false,
        loginFormMessage: LoginFormMessage(
            email: result.email?.join(","),
            password: result.password?.join(","),
            message: result.message),
        user: result.user,
        authenticateType: AuthenticateTypeQr,
        isAuthenticated: result.user != null,
      )));
      if (result.user == null && result.message != null) {
        _dialogService.showDialog(
            title: 'Внимание', buttonTitle: 'Ok', description: 'Ошибка авторизации');
      }
      if (result.user != null) {
        _navigation.replace(HomeViewRoute);
      }
    } catch (e) {
      print(e);
      store.dispatch(SetUserStateAction(UserState(isLoading: false)));
    }
  };
}

ThunkAction<AppState> authenticate(String email, String password) {
  return (Store<AppState> store) async {
    store.dispatch(SetUserStateAction(UserState(isLoading: true)));
    try {
      AuthBody result =
          await _api.authenticate(email, password, statusCheck: false);
      store.dispatch(SetUserStateAction(UserState(
        isLoading: false,
        loginFormMessage: LoginFormMessage(
            email: result.email?.join(","),
            password: result.password?.join(","),
            message: result.message),
        user: result.user,
        login: email,
        password: password,
        authenticateType: AuthenticateTypeLogin,
        isAuthenticated: result.user != null,
      )));
      if (result.user == null && result.message != null) {
        _dialogService.showDialog(
            title: 'Внимание', buttonTitle: 'Ok', description: 'Ошибка авторизации');
      }
      if (result.user != null) {
        _navigation.replace(HomeViewRoute);
      }
    } catch (e) {
      print(e);
      store.dispatch(SetUserStateAction(UserState(isLoading: false)));
    }
  };
}

Future<void> checkSmena(Store<AppState> store) async {
  String token = store.state.userState!.user!.token!;
  Response<Smena> result = await _api.smena(token);
  store.dispatch(SetUserStateAction(UserState(smena: result.body)));
}

Future<void> closeSmena(Store<AppState> store) async {
  String token = store.state.userState!.user!.token!;
  Response<Smena> result = await _api.closeSmena(token);
  store.dispatch(SetUserStateAction(UserState(smena: result.body)));
  store.dispatch(checkMoney);
}

Future<void> openSmena(Store<AppState> store) async {
  String token = store.state.userState!.user!.token!;
  Response<Smena> result = await _api.openSmena(token);
  store.dispatch(SetUserStateAction(UserState(smena: result.body)));
  if (result.operation) {
    store.dispatch(checkSmena);
    store.dispatch(checkMoney);
  }
}

Future<void> openSmenaPseudo(Store<AppState> store) async {
  store.dispatch(SetUserStateAction(UserState(smena: Smena(startedAt: DateTime.now() ))));
}
