import '../provider/data.dart';
import '../utils/game_utils.dart';
import '../utils/random_pick_word.dart';

class GameUtils {

  static Future<void> resetGame(Data myProvider) async {
    myProvider.updateGameIsRunning(false);
  }

  static Future<void> startGame(Data myProvider) async {
    print('Starting game');
    print('- lang: ' + myProvider.lang);
    print('- length: ' + myProvider.length);

    myProvider.resetGame();

    await pickWord(myProvider);

    myProvider.updateGameIsRunning(true);
  }

  static Future<void> pickWord(Data myProvider) async {
    RandomPickWord randomPickWord;
    String word = '';

    int attempts = 0;
    do {
      randomPickWord = RandomPickWord();
      int wordLength = int.parse(myProvider.length);
      await randomPickWord.init(myProvider.lang, wordLength, myProvider.level);

      if (randomPickWord.word != '') {
        word = randomPickWord.word;
      }
      attempts++;

      if ((word != '') && !myProvider.isRecentlyPicked(word)) {
        myProvider.updateWord(word);
      }
    } while (myProvider.word != word && attempts < 10);

    print('Picked word: ' + word);
  }

  static bool addLetter(Data myProvider, String letter) {
    print('addLetter: ' + letter);
    myProvider.currentGuessAddLetter(letter);
    return true;
  }

  static bool removeLetter(Data myProvider) {
    print('removeLetter');
    myProvider.currentGuessRemoveLetter();
    return true;
  }

  static List<String> getTips(Data myProvider, String candidate) {
    String word = myProvider.word;
    int wordLength = int.parse(myProvider.length);

    List<String> tips = List<String>.filled(wordLength, '', growable: false);

    if (
      (word.length != wordLength)
      || (candidate.length != wordLength)
      || (!RandomPickWord.checkWordExists(candidate))
    ) {
        return List<String>.filled(wordLength, 'wrong', growable: false);
    }

    String replaceCharAt(String oldString, int index, String newChar) {
      return oldString.substring(0, index) + newChar + oldString.substring(index + 1);
    }

    print('getTips: candidate "'+candidate+'" / word "'+word+'"');

    // Check correctly placed letters
    print('Check correctly placed letters');
    for (int i = 0; i < wordLength; i++) {
      if ((tips[i] == '') && (word[i] == candidate[i])) {
        print('Found "'+word[i]+'" on the right place: '+(i+1).toString());
        word = replaceCharAt(word, i, ' ');
        candidate = replaceCharAt(candidate, i, ' ');
        tips[i] = 'good';
      }
    }

    // Check misplaced letters
    print('Check misplaced letters');
    for (int i = 0; i < wordLength; i++) {
      for (int j = 0; j < wordLength; j++) {
        if ((candidate[j] != ' ') && (candidate[j] == word[i])) {
          print('Found "'+candidate[j]+'" on the wrong place: '+(j+1).toString()+' instead of '+(i+1).toString());
          word = replaceCharAt(word, i, ' ');
          candidate = replaceCharAt(candidate, j, ' ');
          tips[j] = 'misplaced';
        }
      }
    }

    print('Finished check letters: '+tips.toString());

    return tips;
  }

  static bool submitWord(Data myProvider) {
    print('submitWord');

    if (GameUtils.checkCurrentlyGuessedWordExists(myProvider)) {
      print('Ok word allowed');
      myProvider.currentGuessSubmitWord();
    } else {
      print('Unknown word');
      myProvider.currentGuessSubmitWrongWord();
    }

    return true;
  }

  static bool checkCurrentlyGuessedWordExists(Data myProvider) {
    String guessedWord = myProvider.currentGuess;
    print('Checking word "' + guessedWord + '"...');

    return RandomPickWord.checkWordExists(guessedWord);
  }

  static bool isGameFinished(Data myProvider) {
    print('isGameFinished');

    if (myProvider.guesses.length > 0) {
      if (myProvider.guesses[myProvider.guesses.length - 1] == myProvider.word) {
        return true;
      }
    }
    return false;
  }

}