<?php

namespace Drupal\ufc\Traits;

trait ScraperHelperTrait {

  /**
   *  Map to extract average from a blob of text, process, and set.
   */
  public function extractAndSetAverage(\DOMText|\DOMElement $elem): void {
    $child_content = strtolower($elem->textContent);
    if (strlen($child_content) < 1) {
      return;
    }
    $averages_map = [
      "strikes_per_min" => [
        "sig. str. landed",
        "cleanFloatDatapoint",
      ],
      "absorbed_per_min" => [
        "sig. str. absorbed",
        "cleanFloatDatapoint",
      ],
      "takedowns_per_15" => [
        "takedown avg",
        "cleanFloatDatapoint",
      ],
      "submission_avg_per_15" => [
        "submission avg",
        "cleanFloatDatapoint",
      ],
      "sig_strike_defense" => [
        "sig. str. defense",
        "cleanIntDatapoint",
      ],
      "takedown_defense" => [
        "takedown defense",
        "cleanIntDatapoint",
      ],
      "knockdown_ratio" => [
        "knockdown avg",
        "cleanFloatDatapoint",
      ],
      "average_fight_time" => [
        "average fight time",
        "convertAverageFightTimeToSeconds",
      ],
    ];
    foreach ($averages_map as $avg_type => $handlers) {
      // First item in $handlers is the string to search for.
      // Second item is the cleaning function.
      if (str_contains($child_content, $handlers[0])) {
        /* @var DOMElement */
        $this->{$avg_type} = $this->{$handlers[1]}($elem->firstElementChild->nodeValue);
      }
    }
  }

  /**
   *  Extracts accuracy number from a string.
   */
  public function extractAccuracyFromString(string $string): float {
    // Examples:
    //   Striking accuracy 65%
    //   Grappling Accuracy 60%
    $split_on_space = explode(" ", $string);
    $percentage = $split_on_space[2] ?? FALSE;
    // If no percentage located, simply set to 0.
    if (!$percentage) {
      return 0.0;
    }
    $percentage = (float) trim(str_replace('%', '', $percentage));
    assert(is_float($percentage));

    return $percentage;
  }

  /**
   *  Pulls strike totals.
   */
  public function setStrikes(string $input): void  {
    $clean = str_replace(["\n", '"'], "", $input);
    $break_on_space = array_filter(explode(" ", $clean));
    $data = [];
    foreach ($break_on_space as $str) {
      if (ctype_digit($str)) {
        $data[] = $str;
      }
    }
    if (!empty($data) && count($data) == 3) {
      $this->standing_strikes = (int) $data[0];
      $this->clinch_strikes = (int) $data[1];
      $this->ground_strikes = (int) $data[2];
    }
  }

  /**
   * Converts time format (MM:SS) to seconds (s).
   */
  public function convertAverageFightTimeToSeconds(string $fight_time): int {
    $seconds = 0;
    $mins_seconds = explode(':', $fight_time);
    $seconds += ( (int) $mins_seconds[0] * 60) + (int) $mins_seconds[1];
    assert(is_int($seconds));

    return $seconds;
  }

  /**
   * Cleans a float datapoint for insertion to the database.
   */
  protected function cleanFloatDatapoint(string $datapoint): float {
    $datapoint = str_replace("\n", "", $datapoint);
    $datapoint = (float) trim($datapoint);
    assert(is_float($datapoint));

    return $datapoint;
  }

  /**
   * Cleans an int datapoint for insertion to the database.
   */
  protected function cleanIntDatapoint(string $datapoint): int {
    $datapoint = str_replace("\n", "", $datapoint);
    $datapoint = (int) trim($datapoint);
    assert(is_int($datapoint));

    return $datapoint;
  }


}
