<?php

declare(strict_types=1);

namespace Cin\AjaxSearch5;

use TeamTNT\TNTSearch\Support\AbstractTokenizer;
use TeamTNT\TNTSearch\Support\TokenizerInterface;

final class StripTagsTokenizer extends AbstractTokenizer implements TokenizerInterface
{
  public $min_gram = 4;

  public $max_gram = 4;

  protected static $pattern = '/[^\p{L}\p{N}\p{Pc}\p{Pd}@]+/u';

  public function __construct($min_gram = 3, $max_gram = 5)
  {
    $this->min_gram = $min_gram;
    $this->max_gram = $max_gram;
  }

  public function tokenize($text, $stopwords = [])
  {
    $text   = $this->stripTags($text);
    $text   = mb_strtolower($text);
    $ngrams = [];
    $split  = preg_split($this->getPattern(), $text, -1, \PREG_SPLIT_NO_EMPTY);
    $splits = array_diff($split, $stopwords);

    foreach ($splits as $split) {
      for ($currentGram = (int) $this->min_gram; $currentGram <= (int) $this->max_gram; ++$currentGram) {
        for ($i = 0; $i <= mb_strlen($split) - $currentGram; ++$i) {
          $ngrams[] = mb_substr($split, $i, $currentGram);
        }
      }
    }

    return $ngrams;
  }

  private function stripTags(string $string): string
  {
    if (null === $string) {
      $string = '';
    }
    $string = preg_replace('/<[^>]*>/', ' ', $string);
    $string = str_replace("\r", '', $string);
    $string = str_replace("\n", ' ', $string);
    $string = str_replace("\t", ' ', $string);
    $string = str_replace('"', '', $string);

    return trim(preg_replace('/ {2,}/', ' ', $string));
  }
}
