<?php

namespace Drupal\basket\Query;

use Drupal\views\Views;

/**
 * Determination of the product image according to the settings.
 */
class BasketGetNodeImgQuery {

  /**
   * Set getQuery.
   *
   * @var object
   */
  protected static $getQuery;

  /**
   * Set getNodeTypesFields.
   *
   * @var array
   */
  protected static $getNodeTypesFields;

  /**
   * Set getNodeTypeField.
   *
   * @var string
   */
  protected static $getNodeTypeField;

  /**
   * {@inheritdoc}
   */
  public static function getQuery() {
    if (!self::$getQuery) {
      self::$getQuery = NULL;
      $getNodeTypesFields = self::getNodeTypesFields();
      if (!empty($getNodeTypesFields)) {
        $queries = [];
        foreach ($getNodeTypesFields as $imgField => $keyNodeTypes) {
          $imgFields = explode('->', $imgField);
          $isAddPrice = FALSE;
          switch (count($imgFields)) {
            case 1:
              $imgFields = reset($imgFields);
              if (\Drupal::database()->schema()->tableExists('node__' . $imgFields)) {
                $queries[$imgField] = \Drupal::database()->select('node__' . $imgFields, $imgFields);
                $queries[$imgField]->condition($imgFields . '.delta', 0);
                $queries[$imgField]->addExpression($imgFields . '.entity_id', 'nid');
                $queries[$imgField]->addExpression($imgFields . '.' . $imgFields . '_target_id', 'fid');
              }
              break;

            case 2:
              if (\Drupal::database()->schema()->tableExists("node__$imgFields[0]") && \Drupal::database()->schema()->tableExists("paragraph__$imgFields[1]")) {
                $queries[$imgField] = \Drupal::database()->select("node__$imgFields[0]", $imgFields[0]);
                $queries[$imgField]->addExpression("$imgFields[0].entity_id", 'nid');
                $queries[$imgField]->condition("$imgFields[0].delta", 0);
                $queries[$imgField]->leftJoin("paragraph__$imgFields[1]", $imgFields[1], "$imgFields[1].entity_id = $imgFields[0].$imgFields[0]_target_id");
                $queries[$imgField]->addExpression("$imgFields[1].$imgFields[1]_target_id", 'fid');
              }
              break;
          }
        }
        if (!empty($queries)) {
          $priceQuery = NULL;
          foreach ($queries as $subQuery) {
            if (is_null($priceQuery)) {
              $priceQuery = $subQuery;
            }
            else {
              $priceQuery->union($subQuery, 'ALL');
            }
          }
          self::$getQuery = $priceQuery;
        }
      }
    }
    return self::$getQuery;
  }

  /**
   * {@inheritdoc}
   */
  public static function getNodeTypesFields() {
    if (!self::$getNodeTypesFields) {
      self::$getNodeTypesFields = [];
      $results = \Drupal::database()->select('basket_node_types', 'n')
        ->fields('n', ['type', 'image_field'])
        ->isNotNull('n.image_field')
        ->execute()->fetchAll();
      if (!empty($results)) {
        foreach ($results as $result) {
          self::$getNodeTypesFields[$result->image_field][$result->type] = $result->type;
        }
      }
    }
    return self::$getNodeTypesFields;
  }

  /**
   * {@inheritdoc}
   */
  public static function viewsJoin(&$view) {
    if (empty($view->query->relationships[$view->field . '_getFirstImgQuery'])) {
      $subQuery = self::getQuery();
      if (!empty($subQuery)) {
        $join = Views::pluginManager('join')->createInstance('standard', [
          'type'          => 'LEFT',
          'table'         => $subQuery,
          'field'         => 'nid',
          'left_table'    => 'node_field_data',
          'left_field'    => 'nid',
          'operator'      => '=',
        ]);
        $rel = $view->query->addRelationship($view->field . '_getFirstImgQuery', $join, 'node_field_data');
        $view->query->addField($view->field . '_getFirstImgQuery', 'fid', 'basket_node_first_img');
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getNodeImgFirst($entity) {
    $getFid = 0;
    $getSettings = \Drupal::service('Basket')->getClass('Drupal\basket\BasketExtraFields')->getNodeTypeSettings($entity->bundle());
    if (!empty($getSettings->image_field)) {
      $query = \Drupal::database()->select('node_field_data', 'n');
      $query->condition('n.nid', $entity->id());
      // ---
      $imageFields = explode('->', $getSettings->image_field);
      $addFid = FALSE;
      $imageFieldName = NULL;
      switch (count($imageFields)) {
        case 1:
          $imageFields = reset($imageFields);
          if (\Drupal::database()->schema()->tableExists('node__' . $imageFields)) {
            $query->leftJoin('node__' . $imageFields, $imageFields, $imageFields . '.entity_id = n.nid');
            $query->fields($imageFields, [$imageFields . '_target_id']);
            $addFid = TRUE;
            $imageFieldName = $imageFields;
          }
          break;

        case 2:
          if (\Drupal::database()->schema()->tableExists("node__$imageFields[0]") && \Drupal::database()->schema()->tableExists("paragraph__$imageFields[1]")) {
            $query->leftJoin("node__$imageFields[0]", $imageFields[0], "$imageFields[0].entity_id = n.nid");
            $query->leftJoin("paragraph__$imageFields[1]", $imageFields[1], "$imageFields[1].entity_id = $imageFields[0].$imageFields[0]_target_id");
            $query->fields($imageFields[1], ["$imageFields[1]_target_id"]);
            $addFid = TRUE;
            $imageFieldName = $imageFields[1];
          }
          break;
      }
      if (!$addFid) {
        $query->addExpression(0, 'fid');
      }
      $getFid = $query->execute()->fetchField();
      if (empty($getFid) && !empty($imageFieldName)) {
        $getFid = self::getDefFid($entity);
      }
    }
    return !empty($getFid) ? $getFid : 0;
  }

  /**
   * {@inheritdoc}
   */
  public static function getDefFid($entity) {
    if (!isset(self::$getNodeTypeField[$entity->bundle()])) {
      self::$getNodeTypeField[$entity->bundle()] = \Drupal::database()->select('basket_node_types', 'n')
        ->fields('n', ['image_field'])
        ->condition('n.type', $entity->bundle())
        ->execute()->fetchField();
    }
    if (!empty(self::$getNodeTypeField[$entity->bundle()])) {
      $imgFieldLines = explode('->', self::$getNodeTypeField[$entity->bundle()]);
      switch (count($imgFieldLines)) {
        case 1:
          $fieldStorageConfig = \Drupal::database()->select('config', 'c')
            ->fields('c', ['data'])
            ->condition('c.name', 'field.field.node.' . $entity->bundle() . '.' . $imgFieldLines[0], 'LIKE')
            ->execute()->fetchField();
          break;

        case 2:
          $fieldStorageConfig = \Drupal::database()->select('config', 'c')
            ->fields('c', ['data'])
            ->condition('c.name', 'field.field.paragraph.%', 'LIKE')
            ->condition('c.name', '%.' . $imgFieldLines[1], 'LIKE')
            ->execute()->fetchField();
          break;
      }
      if (!empty($fieldStorageConfig)) {
        $fieldStorageConfig = unserialize($fieldStorageConfig);
        if (!empty($fieldStorageConfig['settings']['default_image']['uuid'])) {
          $file = \Drupal::service('entity.repository')->loadEntityByUuid('file', $fieldStorageConfig['settings']['default_image']['uuid']);
          if (!empty($file)) {
            return $file->id();
          }
        }
      }
    }
    return NULL;
  }

}
