using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using NUnit.Framework;

namespace Core.Tests
{
    [TestFixture]
    public class DictionarySearcherTests
    {
        [Test]
        public void FindWords()
        {
            var dictionarySearcher = new DictionarySearcher();
            var results = dictionarySearcher.FindWords("ztuol");
            Console.WriteLine(string.Join(" ", results));
        }

        [Test]
        public void ScoreWords()
        {
            var strings = new[] {"oneword", "another", "onemores", "z"};
            foreach (var s in strings)
            {
                var score = JangleWordScorer.Score(s);
                Console.WriteLine(s + " " + score);
            }
        }

        [Test]
        public void GroupByScore()
        {
            var strings = new[] {"oneword", "another", "onemores", "z"};
            var scored = JangleWordScorer.GroupByScore(strings);
            foreach (var s in scored) Console.WriteLine(s.Key + " " + string.Join(" ", s.Value));
        }

        [Test]
        public void MatchingWords()
        {
            var dictionarySearcher = new DictionarySearcher();
            var matchingWords = dictionarySearcher.MatchingWords("b", "v");
            foreach (var matchingWord in matchingWords)
            {
                Console.WriteLine($"{matchingWord.Item1}, {matchingWord.Item2}");
            }
        }


        [Test]
        public void FindWordsIncludeExclude()
        {
            //extrachisguby
            var dictionarySearcher = new DictionarySearcher();
            var results = dictionarySearcher.FindWords("lon", "extrachisguby", 5);
            Console.WriteLine(string.Join(" ", results));
        }

        /*[Test]
        public void GetLetterPositionFreqTest()
        {
            var dictionarySearcher = new DictionarySearcher();
            var letterPositionFreq = dictionarySearcher.GetLetterPositionFreq(5);
            var index = 1;
            foreach (var f in letterPositionFreq)
            {
                Console.Write(index++);
                
                Console.WriteLine(string.Join(", ", f));
            }
        }*/

        [Test]
        public void LetterPositionFrequencyTest1()
        {
            var dictionarySearcher = new DictionarySearcher();
            var frequency = new LetterPositionFrequency(dictionarySearcher, 5);
            var allWords = dictionarySearcher.FindWords("","",5);
            
            var scoreWords = frequency.ScoreWords(allWords).OrderByDescending(f => f.Item2);
            foreach (var sw in scoreWords)
            {
                Console.WriteLine(sw);
            }
        }

        [Test]
        public void LetterPositionFrequencyTest()
        {
            var dictionarySearcher = new DictionarySearcher();
            var frequency = new LetterPositionFrequency(dictionarySearcher, 5);

            var results = dictionarySearcher.FindWords("eyr", "nzmodlchwbf", 5);
            results = results.Where(r => Regex.IsMatch(r, ".E..Y"));
            var scoreWords = frequency.ScoreWords(results).OrderBy(f => f.Item2);
            foreach (var sw in scoreWords.Take(5))
            {
                Console.WriteLine(sw);
            }
        }

        [Test]
        public void WordleTest()
        {
            var dictionarySearcher = new DictionarySearcher();
            var frequency = new LetterPositionFrequency(dictionarySearcher, 5);
            var crit = new WordleUtil.PositionCriteria[5];
            crit[0] = new WordleUtil.PositionCriteria() { Correct = null, OtherPosition = "O" };
            crit[1] = new WordleUtil.PositionCriteria() { Correct = null, OtherPosition = "C" };
            crit[2] = new WordleUtil.PositionCriteria() { Correct = 'U'};
            crit[3] = new WordleUtil.PositionCriteria() { Correct = null, OtherPosition = "OCD" };
            crit[4] = new WordleUtil.PositionCriteria() { Correct = null, OtherPosition = "O" };

            var results = dictionarySearcher.FindWords("CODU", "XBWINGEPHS", 5);

            results = results.Where(r => Regex.IsMatch(r, WordleUtil.GetRegexRestrictions(crit)));

            var scoreWords = frequency.ScoreWords(results).OrderBy(f => f.Item2);
            foreach (var sw in scoreWords.Take(10))
            {
                Console.WriteLine(sw);
            }
        }
        [Test]
        public void WordleTest2()
        {
            var dictionarySearcher = new DictionarySearcher();
            var frequency = new LetterPositionFrequency(dictionarySearcher, 5);
            var wordleState = new WordleUtil.WordleState();

            wordleState.Update("ABEAM", new[]
            {
                WordleUtil.CharacterResponse.NotInWord,
                WordleUtil.CharacterResponse.NotInWord,
                WordleUtil.CharacterResponse.NotInWord,
                WordleUtil.CharacterResponse.NotInWord,
                WordleUtil.CharacterResponse.NotInWord
            });
            wordleState.Update("SORUS", new[]
            {
                WordleUtil.CharacterResponse.NotInWord,
                WordleUtil.CharacterResponse.NotInWord,
                WordleUtil.CharacterResponse.NotInWord,
                WordleUtil.CharacterResponse.NotInWord,
                WordleUtil.CharacterResponse.NotInWord
            });
            wordleState.Update("PINKY", new[]
            {
                WordleUtil.CharacterResponse.NotInWord,
                WordleUtil.CharacterResponse.Actual,
                WordleUtil.CharacterResponse.NotInWord,
                WordleUtil.CharacterResponse.NotInWord,
                WordleUtil.CharacterResponse.NotInWord
            });
            wordleState.Update("DIGIT", new[]
            {
                WordleUtil.CharacterResponse.NotInWord,
                WordleUtil.CharacterResponse.Actual,
                WordleUtil.CharacterResponse.Actual,
                WordleUtil.CharacterResponse.OtherPosition,
                WordleUtil.CharacterResponse.Actual
            });

            wordleState.Update("FIGHT", new[]
            {
                WordleUtil.CharacterResponse.NotInWord,
                WordleUtil.CharacterResponse.Actual,
                WordleUtil.CharacterResponse.Actual,
                WordleUtil.CharacterResponse.Actual,
                WordleUtil.CharacterResponse.Actual
            });

            var results = dictionarySearcher.FindWords(wordleState.InWord, wordleState.NotInWord, 5);

            results = results.Where(r => Regex.IsMatch(r, WordleUtil.GetRegexRestrictions(wordleState.Criteria)));

            var scoreWords = frequency.ScoreWords(results).OrderByDescending(f => f.Item2);
            foreach (var sw in scoreWords.Take(10))
            {
                Console.WriteLine(sw);
            }
        }
    }
}
