<?php

namespace Drupal\ufc\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\StreamWrapper\StreamWrapperManager;
use Drupal\Core\Render\Renderer;
use Drupal\node\NodeInterface;
use Drupal\node\Entity\Node;
use Drupal\media\Entity\Media;
use Drupal\file\Entity\File;
use Drupal\Core\Cache\CacheableResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
// use Symfony\Component\HttpFoundation\Response;
// use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\Request;

class DcjsRouteController extends ControllerBase {

  /**
   *  The entity type manager service.
   *
   *  @var Drupal\Core\Entity\EntityTypeManager
   *    The entity type manager service.
   */
  protected $entityTypeManager;

  /**
   *  The renderer service.
   *
   *  @var \Drupal\Core\Render\Renderer
   *    The renderer service.
   */
  protected $renderer;

 /**
   *  The Stream Wrapper Manager service.
   *
   *  @var \Drupal\Core\StreamWrapper\StreamWrapperManager
   *    Stream wrapper manager service.
   */
  protected $streamWrapperManager;


  /**
   *  Public constructor.
   *
   *  @var \Drupal\Core\Entity\EntityTypeManager $entityTypeManager
   *    The entity type manager service.
   *
   *  @var \Drupal\Core\Render\Renderer $renderer
   *    The renderer service.
   *
   *  @var \Drupal\Core\StreamWrapper\StreamWrapperManager $streamWrapperManager
   *    The stream wrapper manager service.
   *
   */
  public function __construct(
    EntityTypeManager $entityTypeManager,
    Renderer $renderer,
    StreamWrapperManager $streamWrapperManager
  ) {
    $this->entityTypeManager = $entityTypeManager;
    $this->renderer = $renderer;
    $this->streamWrapperManager = $streamWrapperManager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    // Instantiates this form class.
    return new static(
      // Load the service required to construct this class.
      $container->get('entity_type.manager'),
      $container->get('renderer'),
      $container->get('stream_wrapper_manager'),
    );
  }

  /**
   * Not working right now.
   */
  private function validateDcjsUserAgent(Request $request): bool {
    $user_agent = $request->headers->get('user-agent');
    if ($user_agent !== "DCJS Fetcher") {
      return TRUE;
    }

    return TRUE;
  }

   /**
   * Get all fighters to serve via DCJS.
   *
   * @return array<string,string>
   */
  public function allFightersForDcjs(): CacheableResponse {
    $query = $this->entityTypeManager->getStorage('node')->getQuery();
    $query->accessCheck(TRUE);
    $query->condition('type', 'fighter')->sort('title', 'ASC');
    $query->range(0, 200);
    $nids = $query->execute();
    $all_fighters = Node::loadMultiple($nids);
    $fighter_data = [];
    foreach ($all_fighters as $fighter) {
      $photo_mid = $fighter->field_player_photo->target_id;
      $fighter_id = $fighter->id();
      $link_to_content = "/node/$fighter_id";
      $fighter_name = $fighter->title->value;
      $photo_uri = $this->retrievePhotoUri($photo_mid);
      $fighter_data[] = [
        'link' => $link_to_content,
        'name' => $fighter_name,
        'picUrl' => $photo_uri,
      ];
    }
    $build = [
      '#theme' => 'fighters_dcjs_list',
      '#fighters' => $fighter_data,
    ];

    return new CacheableResponse($this->renderer->renderPlain($build));
  }

  /**
   * Retrieves an individual fighter.
   */
  public function fighterForDcjs(NodeInterface $fighter_node): CacheableResponse {
    $personal_fields = [
      'age',
      'division',
      'height',
      'weight',
      'reach',
      'leg_reach',
    ];
    $stats_fields = [
      'knockouts',
      'striking_accuracy',
      'strikes_per_minute',
      'sig_strike_defense',
      'absorbed_per_min',
      'standing_strikes',
      'clinch_strikes',
      'ground_strikes',
      'grappling_accuracy',
      'strikes_to_head',
      'strikes_to_body',
      'strikes_to_leg',
      'knockdown_ratio',
      'takedowns_per_15',
      'takedown_defense',
      'average_fight_time',
      'first_round_finishes',
    ];

    $fighter_build = [
      '#theme' => 'fighter_for_dcjs',
      '#node' => $fighter_node,
      '#personal_info' => $this->getFieldValuesFromNode($fighter_node, $personal_fields),
      '#stats' => $this->getFieldValuesFromNode($fighter_node, $stats_fields),
    ];

    $rendered = $this->renderer->renderPlain($fighter_build);

    return new CacheableResponse($rendered);
  }


  /**
   * Extracts target field values from a node.
   *
   *  @param NodeInterface $node
   *    The node.
   *
   *  @param array[] $retrieve
   *    The fields to retrieve
   *
   *  @return array[]
   */
  private function getFieldValuesFromNode(NodeInterface $node, array $retrieve): array {
    $return_data = [];
    foreach ($retrieve as $field_name) {
      $field_name_with_prefix = "field_$field_name";
      if ($field_name == 'division') {
        $div_id = $node->get($field_name_with_prefix)->target_id;
        $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($div_id);
        $return_data['division'] = $term->getName();
      }
      else {
        $return_data[$field_name] = $node->{$field_name_with_prefix}->value;
      }
    }

    return $return_data;
  }

  /**
   * Retrieve URI for a player photo.
   */
  private function retrievePhotoUri(int $media_id): string {
    $player_fid = Media::load($media_id)->field_media_image->target_id;
    $file = File::load($player_fid);
    if ($wrapper = $this->streamWrapperManager->getViaUri($file->getFileUri())) {

      return $wrapper->getExternalUrl();
    }
  }
}
