<?php

namespace Drupal\abinbev_gmap\Plugin\Block;

use Drupal\abinbev_gmap\PlaceInfoService;
use Drupal\abinbev_gmap\UserDataService;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;

/**
 * Provides a 'Bees Google Map' Block.
 *
 * @Block(
 *   id = "abinbev_map_block",
 *   admin_label = @Translation("AbInbev Bees Map block"),
 *   category = @Translation("AbInbev"),
 * )
 */
class BeesMapBlock extends BlockBase implements ContainerFactoryPluginInterface {

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

  /**
   * The admin toolbar tools configuration.
   *
   * @var \Drupal\Core\Config\Config
   */
  protected $config;

  protected $placeInfoService;

  protected $userDataService;

  /**
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin ID for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   Config factory service.
   */
  public function __construct($configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, PlaceInfoService $placeInfoService, UserDataService $userDataService) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->entityTypeManager = $entity_type_manager;
    $this->config = $config_factory->get('abinbev_gmap.settings');
    $this->placeInfoService = $placeInfoService;
    $this->userDataService = $userDataService;

  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager'),
      $container->get('config.factory'),
      $container->get('place_info_service'),
      $container->get('user_data_service')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    $header_text = $this->configuration['header_text'];
    $promo_ids = $this->configuration['promo_id'];
    $promo_id = explode(',', $promo_ids);

    $poc_types = ['active', 'non-active'];
    $current_mechanic = $this->userDataService->getCurrentMechanic();

    if ($current_mechanic['flow'] == 'c' || $current_mechanic['flow'] == 'r' || $current_mechanic['flow'] == 'd') {
      $poc_types = ['active'];
    }
    $out = [];
    $data = [];

    foreach ($poc_types as $poc_type) {
      $cid = 'map_locations:' . $poc_type . ':' . $promo_ids;
      if ($cache = \Drupal::cache()->get($cid)) {
        $data = $cache->data;
      }
      else {
        $locations = \Drupal::service('bq_request_service')
            ->getActiveLocations($promo_id) ?? [];
        if ($poc_type != 'active') {
          $NALocations = \Drupal::service('bq_request_service')
              ->getLocations() ?? [];
          $NALocations = array_keys($NALocations);
          $common = array_intersect($locations, $NALocations);
          $locations = array_diff($NALocations, $common);
        }

        $places = $this->placeInfoService->getSelectedPlaces($locations);

        $current_time = new \DateTime("now");
        $current_day = $current_time->format('w');
        foreach ($places as $place_id => $place) {
          $full_info = json_decode($place->full_info);
          if (!empty($full_info->opening_hours)) {
            $hours = $full_info->opening_hours;
            if (!empty($hours->periods[$current_day])) {
              $periods = $hours->periods[$current_day];
              $open_time = new \DateTime($periods->open->time);
              $close_time = new \DateTime($periods->close->time);
              if ($close_time <= $open_time) {
                $close_time->modify('+1 day');
              }

              $is_open = FALSE;
              if ($current_time >= $open_time && $current_time <= $close_time) {
                $is_open = TRUE;
              }
              if ($current_day != 0) {
                $open_text = $full_info->opening_hours->weekday_text[$current_day - 1];
              }
              else {
                $index = count($full_info->opening_hours->weekday_text);
                $open_text = $full_info->opening_hours->weekday_text[$index - 1];
              }
            }
          }

          $data[$place_id] = [
            'title' => $place->title,
            'lat' => $place->lat,
            'lon' => $place->lon,
            'poc_id' => $place->poc_id,
            'formatted_address' => $full_info->formatted_address ?? '',
            'url' => $full_info->url ?? '',
            'opening_hours' => $full_info->opening_hours ?? NULL,
            'is_open' => $is_open ?? NULL,
            'open_text' => $open_text ?? NULL,
          ];
        }
        \Drupal::cache()->set($cid, $data);
      }
      $out[$poc_type] = $data;
    }

    $token = $_COOKIE['access_token'] ?? NULL;

    $user_has_requested_pocs = FALSE;
    if (!empty($token)) {
      $user_has_requested_pocs = $this->placeInfoService->getUserPocByAccessToken($token);
    }
    $user_info = $this->userDataService->getUserDataByToken($token);
    $user_name = '';
    $user_phone = '';
    if (!empty($user_info)) {
      $user_name = $user_info['user_name'];
      $phone = trim($user_info['user_phone']) ?? '';
      $user_phone = '+' . preg_replace('/\++|\-+|\s+/', '', $phone);
    }

    $fileId = $this->config->get('d_flow_file');
    $file_path = '';
    if (!empty($fileId)) {
      $file = \Drupal::entityTypeManager()
        ->getStorage('file')
        ->load($fileId[0]);
      if (!empty($file)) {
        $file_path = \Drupal::service('file_url_generator')
          ->generateAbsoluteString($file->getFileUri());
      }
    }
    $d_link = $this->config->get('d_flow_link') ?? '';

    return [
      '#attached' => [
        'library' => [
          'abinbev_gmap/map',
        ],
        'drupalSettings' => [
          'user_has_requested_pocs' => (bool) $user_has_requested_pocs,
          'locations' => $out,
          'user_name' => $user_name,
          'user_phone' => $user_phone,
          'current_machanic' => $current_mechanic,
          'default_map_settings' => [
            'default_zoom' => $this->config->get('google_default_zoom') ?? '16',
            'na_zoom' => $this->config->get('google_zoom_show_na_pocs') ?? '16',
            'd_flow_zoom_level' => $this->config->get('d_flow_zoom_level') ?? '6',
            'd_flow_file_path' => $file_path,
            'd_flow_link' => $d_link,
          ],
        ],
      ],
      '#theme' => 'bees_map',
      '#header_text' => $header_text,
      '#user_has_requested_pocs' => $user_has_requested_pocs,
      '#cache' => ['max-age' => 0],
    ];
  }

  public function getLocation($poc_type) {
    $cid = 'map_locations:' . $poc_type;
    if ($cache = \Drupal::cache()->get($cid)) {
      $data = $cache->data;
    }
    else {
      $locations = \Drupal::service('bq_request_service')
          ->getActiveLocations() ?? [];
      if ($poc_type != 'active') {
        $NALocations = \Drupal::service('bq_request_service')
            ->getLocations() ?? [];
        $NALocations = array_values($NALocations);
        $common = array_intersect($locations, $NALocations);
        $locations = array_diff($NALocations, $common);
      }
      $data = \Drupal::service('place_info_service')
        ->getSelectedPlaces($locations);
      \Drupal::cache()->set($cid, $data);
    }
    return json_encode($data);
  }


  public function blockForm($form, FormStateInterface $form_state) {
    $config = $this->getConfiguration();

    $form['promo_id'] = [
      '#title' => t('Promo ID list'),
      '#type' => 'textfield',
      '#description' => t('List of Promo Id for current block. Use coma(,) as delimeter for multiple ids.'),
      '#default_value' => $config['promo_id'] ?? '',
    ];

    $form['header_text'] = [
      '#title' => t('Header text'),
      '#type' => 'text_format',
      '#format' => 'full_html',
      '#allowed_formats' => ['full_html'],
      '#description' => t('Short Description shows Before Map'),
      '#default_value' => $config['header_text']['value'] ?? '',
    ];

    return $form;
  }

  public function blockSubmit($form, FormStateInterface $form_state) {
    $this->configuration['promo_id'] = $form_state->getValue('promo_id');
    $this->configuration['header_text'] = $form_state->getValue('header_text');
  }

}
