<?php

namespace Lvl0\AnagramFinder\Core;

use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;

class Matcher
{
    private const DICTIONARY = __DIR__ . '/../assets/words.txt';

    public static function findWords(string $anagram, int $minLength = 3): Collection
    {
        $matches = self::getWordList()
            ->filter(fn (string $word) => strlen($word) >= $minLength)
            ->filter(fn (string $word) => ctype_alpha($word))
            ->filter(fn (string $word) => $word === strtolower($word))
            ->filter(fn (string $word) => self::check($anagram, $word))
            ->toArray();

        return new Collection($matches)
            ->sort(fn ($a, $b) => strlen($b) - strlen($a));
    }

    public static function check(string $anagram, string $word): bool
    {
        $pool = array_count_values(str_split($anagram));

        foreach (str_split($word) as $char) {
            if (($pool[$char] ?? 0) === 0) {
                return false;
            }

            $pool[$char]--;
        }

        return true;
    }

    private static function getWordList(): LazyCollection
    {
        return LazyCollection::make(function () {
            $fh = fopen(self::DICTIONARY, 'rb');
            try {
                while (($line = fgets($fh)) !== false) {
                    yield rtrim($line, "\r\n");
                }
            } finally {
                fclose($fh);
            }
        });
    }
}
