import 'package:reversi/models/game/game_board.dart';
import 'package:reversi/models/game/game_model.dart';
import 'package:reversi/models/settings/settings_game.dart';
import 'package:reversi/models/settings/settings_global.dart';
import 'package:reversi/utils/tools.dart';

class Game {
  Game({
    // Settings
    required this.gameSettings,
    required this.globalSettings,

    // State
    this.isRunning = false,
    this.isStarted = false,
    this.isFinished = false,
    this.animationInProgress = false,

    // Base data
    required this.gameModel,

    // Game data
    this.score = 0,
  });

  // Settings
  final GameSettings gameSettings;
  final GlobalSettings globalSettings;

  // State
  bool isRunning;
  bool isStarted;
  bool isFinished;
  bool animationInProgress;

  // Base data
  final GameModel gameModel;

  // Game data
  int score;

  factory Game.createNull() {
    return Game(
      // Settings
      gameSettings: GameSettings.createDefault(),
      globalSettings: GlobalSettings.createDefault(),
      // Base data
      gameModel: GameModel(board: GameBoard()),
      // Game data
      score: 0,
    );
  }

  factory Game.createNew({
    GameSettings? gameSettings,
    GlobalSettings? globalSettings,
  }) {
    final GameSettings newGameSettings = gameSettings ?? GameSettings.createDefault();
    final GlobalSettings newGlobalSettings = globalSettings ?? GlobalSettings.createDefault();

    return Game(
      // Settings
      gameSettings: newGameSettings,
      globalSettings: newGlobalSettings,
      // State
      isRunning: true,
      // Base data
      gameModel: GameModel(board: GameBoard()),
      // Game data
      score: 0,
    );
  }

  bool get canBeResumed => isStarted && !isFinished;

  void dump() {
    printlog('');
    printlog('## Current game dump:');
    printlog('');
    printlog('$Game:');
    printlog('  Settings');
    gameSettings.dump();
    globalSettings.dump();
    printlog('  State');
    printlog('    isRunning: $isRunning');
    printlog('    isStarted: $isStarted');
    printlog('    isFinished: $isFinished');
    printlog('    animationInProgress: $animationInProgress');
    printlog('  Base data');
    printlog('    gameModel: $gameModel');
    printlog('  Game data');
    printlog('    score: $score');
    printlog('');
  }

  @override
  String toString() {
    return '$Game(${toJson()})';
  }

  Map<String, dynamic>? toJson() {
    return <String, dynamic>{
      // Settings
      'gameSettings': gameSettings.toJson(),
      'globalSettings': globalSettings.toJson(),
      // State
      'isRunning': isRunning,
      'isStarted': isStarted,
      'isFinished': isFinished,
      'animationInProgress': animationInProgress,
      // Base data
      //   'gameModel': gameModel,
      // Game data
      'score': score,
    };
  }
}