<?php

/**
 * @file
 * The main module that manages website sales.
 */

use Drupal\basket\ViewsUiAddHandler;
use Drupal\basket\ToolbarHandler;
use Drupal\Component\Utility\Html;
use Drupal\Core\Render\Markup;
use Drupal\Core\Url;
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\basket\Admin\ManagerMenu;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\basket\Admin\Page\StatisticsBuyers;

define('BASKET_FOLDER', 'public://basket_order_files');
define('BASKET_INPUTMASK_LIBRARY_FILE', '/libraries/jquery.inputmask/dist/jquery.inputmask.min.js');

\Drupal::moduleHandler()->loadInclude('basket', 'inc', 'views.theme');

/**
 * Implements hook_toolbar().
 */
function basket_toolbar() {
  return \Drupal::service('class_resolver')->getInstanceFromDefinition(ToolbarHandler::class)->toolbar();
}

/**
 * Implements hook_theme().
 */
function basket_theme() {
  $tpls = [];
  $names = [
    'basket_admin_page',
    'basket_admin_header',
    'basket_admin_orders_stat_block',
    'basket_admin_menu',
    'basket_admin_basket_block_caption',
    'basket_edit_order_form',
    'basket_views_view',
    'basket_waybill',
    'basket_views_cart_data',
    'basket_views_cart_empty',
    'basket_add',
    'basket_area_buttons',
    'basket_area_buttons_goods_info',
    'basket_add_popup',
    'basket_add_extra_options_popup',
    'basket_count_block',
    'basket_rate_block',
    'basket_user_discount',
    'basket_page_finish',
    'basket_page_view',
    'basket_page_order',
    'notification_order_admin',
    'notification_order_user',
    'basket_cart_clear_all',
  ];
  $names['lk'][] = 'basket_lk_goods_table';
  foreach ($names as $tplKey => $tpl_name) {
    if (is_array($tpl_name)) {
      foreach ($tpl_name as $name) {
        $tpls[$name] = [
          'variables' => [
            'info'      => NULL,
          ],
          'path'      => drupal_get_path('module', 'basket') . '/templates/' . $tplKey,
        ];
      }
    }
    else {
      $tpls[$tpl_name] = [
        'variables' => [
          'info'      => NULL,
        ],
      ];
    }
  }
  return $tpls;
}

/**
 * Implements hook_link_alter().
 */
function basket_link_alter(&$vars) {
  if (!empty($vars['options']['is_basket']) || !empty($vars['options']['ico_name'])) {
    ManagerMenu::linkAlter($vars);
  }
}

/**
 * Implements hook_preprocess_views_view_table().
 */
function basket_preprocess_views_view_table(&$variables) {
  if ($variables['view']->id() == 'basket' || $variables['view']->id() == 'basket_users') {
    \Drupal::service('Basket')->getClass('Drupal\basket\ViewsAlters')->viewsViewTableAlter($variables);
  }
}

/**
 * Implements hook_preprocess_views_view().
 */
function basket_preprocess_views_view(&$variables) {
  if ($variables['view']->id() == 'basket') {
    \Drupal::service('Basket')->getClass('Drupal\basket\ViewsAlters')->viewsViewAlter($variables);
  }
  if ($variables['view']->id() == 'cart_goods') {
    \Drupal::service('Basket')->getClass('Drupal\basket\ViewsCartAlters')->viewsViewAlter($variables);
  }
}

/**
 * Implements hook_views_pre_build().
 */
function basket_views_pre_build(ViewExecutable $view) {
  if ($view->id() == 'basket') {
    \Drupal::service('Basket')->getClass('Drupal\basket\ViewsAlters')->viewsPreBuidAlter($view);
  }
}

/**
 * Implements hook_views_query_alter().
 */
function basket_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  \Drupal::service('Basket')->getClass('Drupal\basket\ViewsAlters')->viewsQueryAlter($view, $query);
}

/**
 * Implements hook_entity_delete().
 */
function basket_entity_delete(EntityInterface $entity) {
  \Drupal::service('Basket')->getClass('Drupal\basket\Entity')->delete($entity);
}

/**
 * Implements hook_entity_extra_field_info().
 */
function basket_entity_extra_field_info() {
  $extra = [];
  \Drupal::service('Basket')->getClass('Drupal\basket\BasketExtraFields')->info($extra);
  return $extra;
}

/**
 * Implements hook_node_view().
 */
function basket_node_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  \Drupal::service('Basket')->getClass('Drupal\basket\BasketExtraFields')->nodeView($build, $entity, $display);
}

/**
 * Implements hook_form_alter().
 */
function basket_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  switch ($form_id) {
    case'views_ui_add_handler_form':
      ViewsUiAddHandler::formAlter($form, $form_state);
      break;

    case'user_form':
      \Drupal::service('Basket')->getClass('Drupal\basket\BasketExtraFields')->userFormAlter($form, $form_state);
      StatisticsBuyers::formAlter($form, $form_state);
      break;

    case'user_register_form':
      StatisticsBuyers::formAlter($form, $form_state);
      break;

    case'user_admin_permissions':
      \Drupal::service('Basket')->getClass('Drupal\basket\UserAdminPermissions')->formAlter($form, $form_state);
      break;

    case'system_themes_admin_form':
      \Drupal::service('theme.negotiator.basket_theme')->systemThemeFormAlter($form, $form_state);
      break;

    case'update_manager_update_form':
      \Drupal::service('Basket')->getClass('Drupal\basket\BasketUpdateManager')->formAlter($form, $form_state);
      break;
  }
  switch ($form['#id']) {
    case'views-exposed-form-content-page-1':
      if (!empty($form['type']['#options'])) {
        $settingsNodeTypes = \Drupal::service('Basket')->getNodeTypes();
        foreach ($form['type']['#options'] as $key => $value) {
          if ($key == 'basket_order') {
            unset($form['type']['#options'][$key]);
          }
          elseif (!empty($settingsNodeTypes[$key])) {
            unset($form['type']['#options'][$key]);
          }
        }
      }
      break;
  }
}

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function basket_form_node_form_alter(&$form, FormStateInterface $form_state) {
  $entity = $form_state->getBuildInfo()['callback_object']->getEntity();
  $settingsNodeTypes = \Drupal::service('Basket')->getNodeTypes();
  if (!empty($settingsNodeTypes[$entity->bundle()]) && !empty($form['actions']['delete']['#url'])) {
    $form['actions']['delete']['#url'] = new Url('basket.admin.pages', ['page_type' => 'stock-delete-' . $entity->id()]);
  }
  if($entity->bundle() == 'basket_order') {
    \Drupal::service('Basket')->getClass('Drupal\basket\BasketOrderForm')->formAlter($form, $form_state);
  }
}

/**
 * Implements hook_mail().
 */
function basket_mail($key, &$message, $params) {
  $options = [
    'langcode'   => $message['langcode'],
  ];
  switch ($key) {
    case'send':
      $message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed; delsp=yes';
      $message['subject']                 = $params['subject'];
      if (\Drupal::config('smtp.settings')->get('smtp_on') && \Drupal::service('module_handler')->moduleExists('smtp')) {
        $message['body'][] = Markup::create($params['message']);
      }
      else {
        $message['body'][] = Html::escape($params['message']);
      }
      break;
  }
}

/**
 * Implements hook_theme_suggestions_alter().
 */
function basket_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {
  switch ($hook) {
    case'node_edit_form':
      if ($node = \Drupal::routeMatch()->getParameter('node')) {
        $content_type = $node->bundle();
      }
      else {
        if (strpos(\Drupal::service('path.current')->getPath(), 'admin/basket/orders-edit-') !== FALSE) {
          $content_type = 'basket_order';
        }
        if (strpos(\Drupal::service('path.current')->getPath(), 'admin/basket/orders-add') !== FALSE) {
          $content_type = 'basket_order';
        }
        if (empty($content_type) && strpos(\Drupal::service('path.current')->getPath(), 'admin/basket/api-orders-') !== FALSE) {
          $content_type = 'basket_order';
        }
      }
      if (!empty($content_type) && $content_type == 'basket_order') {
        $suggestions[] = 'basket_edit_order_form';
      }
      break;

    case'views_view':
      if ($variables['view']->id() == 'basket' && $variables['view']->current_display == 'block_3') {
        $suggestions[] = 'basket_views_view';
      }
      if ($variables['view']->id() == 'basket_users' && $variables['view']->current_display == 'block_1') {
        $suggestions[] = 'basket_views_view';
      }
      break;
  }
}

/**
 * Implements hook_preprocess_page().
 */
function basket_preprocess_page(&$page) {
  if (function_exists('_batch_current_set')) {
    $current_batch = _batch_current_set();
    if (!empty($current_batch['basket_batch']) && !empty($page['page']['content']['content'])) {
      $page['page']['content']['content'] = \Drupal::service('Basket')->getClass('Drupal\basket\Admin\Pages')->page('batch', $page['page']['content']['content']);
    }
  }
}

/**
 * Implements hook_node_build_defaults_alter().
 */
function basket_node_build_defaults_alter(array &$build, EntityInterface $entity, $view_mode) {
  $settingsNodeTypes = \Drupal::service('Basket')->getNodeTypes();
  if (!empty($settingsNodeTypes) && !empty($settingsNodeTypes[$entity->bundle()])) {
    $build['#cache']['contexts'][] = 'basket_currency';
    $build['#cache']['tags'][] = \Drupal::service('cache_context.basket_currency')->getCacheTag();
  }
}

/**
 * Implements hook_user_login().
 */
function basket_user_login($account) {
  \Drupal::service('Basket')->cart()->movingItems($account->id());
}

/**
 * Implements hook_ENTITY_TYPE_insert().
 */
function basket_user_insert(EntityInterface $entity) {
  \Drupal::service('Basket')->cart()->movingItems($entity->id());
}

/**
 * Implements hook_page_attachments_alter().
 */
function basket_page_attachments_alter(array &$attachments) {
  if (\Drupal::routeMatch()->getRouteName() == 'basket.admin.pages') {
    foreach ($attachments['#attached']['html_head'] as $key => $html_head) {
      if (!empty($html_head[0]['#attributes']['name']) && $html_head[0]['#attributes']['name'] == 'viewport') {
        unset($attachments['#attached']['html_head'][$key]);
      }
    }
    $attachments['#attached']['html_head'][] = [[
      '#type'         => 'html_tag',
      '#tag'          => 'meta',
      '#attributes'   => [
        'name'          => 'viewport',
        'content'       => 'width=1400',
      ],
    ], 'basket_viewport',
    ];
  }
  if (\Drupal::routeMatch()->getRouteName() == 'basket.pages') {
    $attachments['#attached']['html_head'][] = [[
      '#tag'          => 'meta',
      '#attributes'   => [
        'name'          => 'robots',
        'content'       => 'noindex',
      ],
    ], 'basket_noindex',
    ];
  }
}

/**
 * Implements hook_module_implements_alter().
 */
function basket_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'page_attachments_alter') {
    $group = $implementations['basket'];
    unset($implementations['basket']);
    $implementations['basket'] = $group;
  }
}

/**
 * Implements hook_cron().
 */
function basket_cron() {
  \Drupal::service('Basket')->cron()->run();
}

/**
 * Implements hook_library_info_alter().
 */
function basket_library_info_alter(&$libraries, $extension) {
  if ($extension === 'basket' && !empty($libraries['jquery.inputmask']['js']['misc/jquery.inputmask/jquery.inputmask.bundle.min.js'])) {
    if (file_exists(DRUPAL_ROOT . BASKET_INPUTMASK_LIBRARY_FILE)) {
      $libraries['jquery.inputmask']['js'][BASKET_INPUTMASK_LIBRARY_FILE] = $libraries['jquery.inputmask']['js']['misc/jquery.inputmask/jquery.inputmask.bundle.min.js'];
      unset($libraries['jquery.inputmask']['js']['misc/jquery.inputmask/jquery.inputmask.bundle.min.js']);
    }
  }
}

/**
 * Implements hook_preprocess_HOOK().
 */
function basket_preprocess_basket_lk_goods_table($vars) {
  if (!empty($vars['info']['order']->items)) {
    foreach ($vars['info']['order']->items as $item) {
      $item->count = round($item->count, 6);
    }
  }
}

/**
 * Implements hook_preprocess_HOOK().
 */
function basket_preprocess_menu_local_tasks(&$vars) {
  if (!empty($vars['primary']['entity.node.delete_form']['#link']['url'])) {
    $params = $vars['primary']['entity.node.delete_form']['#link']['url']->getRouteParameters();
    if (!empty($params['node'])) {
      $entity = \Drupal::entityTypeManager()->getStorage('node')->load($params['node']);
      if (!empty($entity)) {
        $settingsNodeTypes = \Drupal::service('Basket')->getNodeTypes(FALSE);
        if (!empty($settingsNodeTypes[$entity->bundle()])) {
          $isDelete = \Drupal::database()->select('basket_node_delete', 'n')
            ->fields('n')
            ->condition('n.nid', $entity->id())
            ->execute()->fetchField();
          if (empty($isDelete)) {
            $vars['primary']['entity.node.delete_form']['#link']['url'] = new Url('basket.admin.pages', ['page_type' => 'stock-delete-' . $entity->id()]);
          }
          else {
            $vars['primary']['entity.node.delete_form']['#link']['title'] = \Drupal::service('Basket')->translate()->t('Permanently remove');
            $vars['primary']['basket_restore'] = [
              '#type'         => 'inline_template',
              '#template'     => '<li class="tabs__tab"><a href="javascript:void(0);" onclick="{{ onclick }}" data-post="{{ post }}">{{ basket_t(\'Restore\') }}</a></li>',
              '#context'      => [
                'onclick'       => 'basket_admin_ajax_link(this, \'' . Url::fromRoute('basket.admin.pages', ['page_type' => 'api-node_restore'])->toString() . '\')',
                'post'          => json_encode(['nid' => $entity->id()]),
              ],
              '#attached'     => [
                'library'       => [
                  'basket/admin.js',
                ],
              ],
            ];
          }
        }
      }
    }
  }
}

/**
 * Implements hook_scss_compiler_import_paths_alter().
 */
function basket_scss_compiler_import_paths_alter(array &$additional_import_paths) {
  if (!isset($additional_import_paths['basket_colors'])) {
    $additional_import_paths['basket_colors'] = drupal_get_path('module', 'basket') . '/misc/scss';
  }
}

/**
 * Implements hook_update_projects_alter().
 */
function basket_update_projects_alter(&$projects) {
  foreach ($projects as $projectName => &$project) {
    if(!empty($project['info']['package']) && $project['info']['package'] == 'Online store') {
      $project['info']['project status url'] = 'https://alternativecommerce.org/release-history';
      if(empty($project['info']['datestamp'])) {
        $project['info']['datestamp'] = time();
      }
      if(empty($project['info']['project'])) {
        $project['info']['project'] = $projectName;
      }
      if(empty($project['info']['version'])) {
        $project['info']['version'] = 'dev';
      }
    }
  }
}

/**
 * Implements hook_update_status_alter().
 */
function basket_update_status_alter(&$projects) {
  foreach ($projects as &$project) {
    if(!empty($project['info']['package']) && $project['info']['package'] == 'Online store') {
      if(!empty($project['recommended']) && !empty($project['releases'][$project['recommended']]['alternativecommerce'])) {
        $project['project_type'] = 'core';
        $project['name'] = $project['info']['name'];
        $project['title'] = $project['info']['name'];
      }
    }
  }
}

/**
 * Implements hook_locale_translation_projects_alter().
 */
function basket_locale_translation_projects_alter(&$projects) {
  foreach ($projects as $projectName => &$project) {
    if(!empty($project['info']['package']) && $project['info']['package'] == 'Online store') {
      $project['info']['interface translation server pattern'] = 'http://alternativecommerce.org/files/translations/%core/%project/%project-%version.%language.po';
    }
  }
}

/**
 * Implements hook_preprocess_HOOK().
 */
function basket_preprocess_update_report(&$vars) {
  \Drupal::service('Basket')->getClass('Drupal\basket\BasketUpdateManager')->updateReport($vars);
}

/**
 * Implements hook_entity_type_build().
 */
function basket_entity_type_build(array &$entity_types) {
  foreach (\Drupal::service('entity_display.repository')->getFormModes('node') as $modeKey => $mode) {
    $entity_types['node']->setFormClass($modeKey, 'Drupal\node\NodeForm');
  }
}