package edu.caltech.cs2.project02.choosers;

import edu.caltech.cs2.project02.interfaces.IHangmanChooser;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

public class RandomHangmanChooser implements IHangmanChooser {
  private static final Random RANDOM = new Random();
  private static SortedSet<String> acceptableWords;
  private static int numOfGuess;
  private static String secretWord;
  private static boolean found;
  private static ArrayList<String> allWords;
  private static Set<Character> lettersGuessed;




  public RandomHangmanChooser(int wordLength, int maxGuesses) throws FileNotFoundException {
    lettersGuessed = new TreeSet<>();
    numOfGuess = maxGuesses;

    File text = new File("data/scrabble.txt");
    allWords = new ArrayList<>();
    Scanner scan = new Scanner(text);
    while (scan.hasNextLine()) {
      allWords.addAll(List.of(scan.nextLine().split(" ")));
    }
      acceptableWords = new TreeSet<>();
      if (wordLength < 1 || maxGuesses < 1) {
        throw new IllegalArgumentException("Word length or max guesses should be a positive integer");
      }
      for (String word : allWords){
        if (word.length() == wordLength){
          found = true;
          acceptableWords.add(word);
        }
      }
      if (!found) {
        throw new IllegalStateException("No words found for word length specified");
      }

      int index = RANDOM.nextInt(acceptableWords.size());
      List<String> wordsList = new ArrayList<>(acceptableWords);
      secretWord = wordsList.get(index);

  }

  @Override
  public int makeGuess(char letter) {
    if (numOfGuess < 1){
      throw new IllegalStateException("You ran out of guesses.");
    }
    if (lettersGuessed.contains(letter)){
      throw new IllegalArgumentException("Letter is already guessed.");
    }
    if (letter < 'a' || letter > 'z'){
      throw new IllegalArgumentException("Guess must be lowercase alphabet letter.");
    }
    if (!secretWord.contains(String.valueOf(letter))){
      numOfGuess--;
    }

    lettersGuessed.add(letter);
    return (int) secretWord.chars().filter(ch -> ch == letter).count();

  }

  @Override
  public boolean isGameOver() {
    if (numOfGuess == 0 || getPattern().equals(secretWord)) {
      return true;
    }
    else {
      return false;
    }
  }

  @Override
  public String getPattern() {
    char result[] = new char[secretWord.length()];
    for (int i = 0; i < secretWord.length(); i++){
      if (lettersGuessed.contains(secretWord.charAt(i))){
        result[i] = secretWord.charAt(i);
      }
      else{
        result[i] = '-';
      }
    }


    String res = "";
    for (char letter : result){
      res += letter;
    }

    return res;
  }

  @Override
  public SortedSet<Character> getGuesses() {
    return (SortedSet<Character>) lettersGuessed;
  }

  @Override
  public int getGuessesRemaining() {
    return numOfGuess;
  }

  @Override
  public String getWord() {
    numOfGuess = 0;
    return secretWord;
  }
}