import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';

import 'package:tetrisdual/models/activity/activity.dart';
import 'package:tetrisdual/models/activity/player.dart';
import 'package:tetrisdual/models/settings/settings_activity.dart';
import 'package:tetrisdual/models/settings/settings_global.dart';

part 'activity_state.dart';

class ActivityCubit extends HydratedCubit<ActivityState> {
  ActivityCubit()
      : super(ActivityState(
          currentActivity: Activity.createEmpty(),
        ));

  void updateState(Activity activity) {
    emit(ActivityState(
      currentActivity: activity,
    ));
  }

  void refresh() {
    final Activity activity = Activity(
      // Settings
      activitySettings: state.currentActivity.activitySettings,
      globalSettings: state.currentActivity.globalSettings,
      // State
      isRunning: state.currentActivity.isRunning,
      isStarted: state.currentActivity.isStarted,
      isFinished: state.currentActivity.isFinished,
      animationInProgress: state.currentActivity.animationInProgress,
      // Base data
      players: state.currentActivity.players,
      // Game data
      currentPlayer: state.currentActivity.currentPlayer,
    );
    // game.dump();

    updateState(activity);
  }

  void startNewActivity({
    required ActivitySettings activitySettings,
    required GlobalSettings globalSettings,
  }) {
    final Activity newActivity = Activity.createNew(
      // Settings
      activitySettings: activitySettings,
      globalSettings: globalSettings,
    );

    newActivity.dump();

    updateState(newActivity);
    enableRandomPlayer();
    refresh();
  }

  void quitActivity() {
    state.currentActivity.isRunning = false;
    refresh();
  }

  void resumeSavedActivity() {
    state.currentActivity.isRunning = true;
    refresh();
  }

  void deleteSavedActivity() {
    state.currentActivity.isRunning = false;
    state.currentActivity.isFinished = true;
    refresh();
  }

  void toggleCurrentPlayer() {
    state.currentActivity.isStarted = true;

    // brand new game
    if (state.currentActivity.currentPlayer == 0) {
      state.currentActivity.currentPlayer = 1;
    } else {
      // Reset current player tetrimino
      getCurrentPlayer().resetTetrimino();

      // toggle: 1 -> 2 ; 2 -> 1
      state.currentActivity.currentPlayer = 3 - state.currentActivity.currentPlayer;
    }

    // Pick new tetrimino
    getCurrentPlayer().pickRandomTetrimino();

    refresh();
  }

  void enableRandomPlayer() {
    state.currentActivity.currentPlayer = Random().nextInt(2) + 1;
    toggleCurrentPlayer();
  }

  Player getPlayer(int playerId) {
    return state.currentActivity.players[playerId - 1];
  }

  Player getCurrentPlayer() {
    return getPlayer(state.currentActivity.currentPlayer);
  }

  @override
  ActivityState? fromJson(Map<String, dynamic> json) {
    final Activity currentActivity = json['currentActivity'] as Activity;

    return ActivityState(
      currentActivity: currentActivity,
    );
  }

  @override
  Map<String, dynamic>? toJson(ActivityState state) {
    return <String, dynamic>{
      'currentActivity': state.currentActivity.toJson(),
    };
  }
}