
import 'package:meta/meta.dart';
import 'package:redux/redux.dart';
import 'package:redux_persist_flutter/redux_persist_flutter.dart';
import 'package:redux_thunk/redux_thunk.dart';
import 'package:redux_persist/redux_persist.dart';
import 'package:satu/core/redux/actions/nav_actions.dart';
import 'package:satu/core/redux/actions/sell_actions.dart';
import 'package:satu/core/redux/reducers/nav_reducer.dart';
import 'package:satu/core/redux/reducers/sell_reducer.dart';
import 'package:satu/core/redux/reducers/user_reducer.dart';
import 'package:satu/core/redux/state/nav_state.dart';
import 'package:satu/core/redux/state/sell_state.dart';
import 'package:satu/core/redux/state/user_state.dart';

import 'actions/user_actions.dart';


//reducer context
AppState appReducer(AppState state, dynamic action) {
  if (action is SetUserStateAction) {
    /** UserAction **/
    final UserState nextState = userReducer(state.userState!, action);
    return state.copyWith(userState: nextState);
  } else if (action is SetNavStateAction) {
    /** NavAction **/
    final NavState nextState = navReducer(state.navState!, action);
    return state.copyWith(navState: nextState);
  }  else if (action is SetSellStateAction) {
    /** NavAction **/
    final SellState nextState = sellReducer(state.sellState!, action);
    return state.copyWith(sellState: nextState);
  }
  return state;
}

//Main  State
@immutable
class AppState {
  final UserState? userState;
  final NavState? navState;
  final SellState? sellState;


  const AppState({
    this.userState,
    this.navState,
    this.sellState
  });

  //stable work
  AppState copyWith({
    @required UserState? userState,
    @required NavState? navState,
    @required SellState? sellState,
  }) {
    return AppState(
      userState: userState ?? this.userState,
      navState: navState ?? this.navState,
      sellState: sellState ?? this.sellState
    );
  }

  static AppState? fromJson(dynamic json){
    return json !=null
        ? AppState(
          userState: UserState.fromJson(json['userState']),
        )
        : null;
  }

  dynamic toJson() {
    return {
      "userState" : userState!.toJson(),
    };
  }
}

class Redux {
  static Store<AppState>? _store;

  static Store<AppState>? get store {
    if (_store == null) {
      throw Exception("store is not initialized");
    } else {
      return _store;
    }
  }

  //initial context
  static Future<void> init() async {
    // Create Persistor
    final persist = Persistor<AppState>(
      storage: FlutterStorage(), // Or use other engines
      serializer: JsonSerializer<AppState>(AppState.fromJson), // Or use other serializers
    );

    final AppState? initialState = await persist.load();
    final userStateInitial = UserState.initial(initialState?.userState);
    final navStateInitial = NavState.initial();
    final sellStateInitial = SellState.initial();

    _store = Store<AppState>(
      appReducer,
      middleware: [thunkMiddleware, persist.createMiddleware() ],
      initialState: AppState(
          userState: userStateInitial,
          navState: navStateInitial,
          sellState: sellStateInitial,
      )
    );
  }
}
