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 EvilHangmanChooser implements IHangmanChooser {

  private int maxGuesses;
  private SortedSet<Character> guessed;
  private SortedSet<String> words;
  private String pattern;

    
  public EvilHangmanChooser(int wordLength, int maxGuesses) throws FileNotFoundException {
    this.maxGuesses = maxGuesses;
    this.guessed = new TreeSet<Character>();
    this.words = new TreeSet<>();
    this.pattern = "";
    if(wordLength < 1 || maxGuesses < 1) {
      throw new IllegalArgumentException();
    }
    File scrabble = new File("data/scrabble.txt");
    Scanner reader = new Scanner(scrabble);
    while(reader.hasNextLine()) {
      String word = reader.nextLine();
      if(word.length() == wordLength) {
        words.add(word);
      }
    }
    if(words.isEmpty()) {
      throw new IllegalStateException();
    }
  }

  @Override
  public int makeGuess(char letter) {
    if(this.maxGuesses < 1) {
      throw new IllegalStateException();
    }
    if(this.guessed.contains(letter)) {
      throw new IllegalArgumentException();
    }
    if(letter < 'a' || letter > 'z') {
      throw new IllegalArgumentException();
    }
    this.guessed.add(letter);
    SortedSet<String> biggest = new TreeSet<>();
    Map<String, SortedSet<String>> family = new TreeMap<>();
    for(String word : this.words) {
      String pattern = "";
      for(int i = 0; i < word.length(); i++) {
        if(word.charAt(i) == letter) {
          pattern += letter;
        }
        else {
          pattern += "-";
        }
      }
      if(!family.containsKey(pattern)) {
        SortedSet<String> words = new TreeSet<>();
        words.add(word);
        family.put(pattern, words);
      }
      else {
        SortedSet<String> words = family.get(pattern);
        words.add(word);
        family.put(pattern, words);
      }
    }
    for(String pattern : family.keySet()) {
      SortedSet<String> words = family.get(pattern);
      if(words.size() > biggest.size()) {
        biggest = words;
        this.pattern = pattern;
      }
    }
    this.words = biggest;
    int count = 0;
    for(int j = 0; j < this.pattern.length(); j++) {
      if (this.pattern.charAt(j) == letter) {
        count += 1;
      }
    }
    if(count == 0) {
      maxGuesses--;
    }
    return count;
  }

  @Override
  public boolean isGameOver() {
    if(maxGuesses < 1) {
      return true;
    }
    for(int i = 0; i < pattern.length(); i++) {
      if(pattern.charAt(i) == '-') {
        return false;
      }
    }
    return true;
  }

  @Override
  public String getPattern() {
    return pattern;
  }

  @Override
  public SortedSet<Character> getGuesses() {
    return this.guessed;
  }

  @Override
  public int getGuessesRemaining() {
    return this.maxGuesses;
  }

  @Override
  public String getWord() {
    this.maxGuesses = 0;
    return this.words.first();
  }
}