<?php
/**
 * @copyright (c) Kufer Software GmbH, Oderstraße 7, D-84453 Mühldorf
 */

declare(strict_types = 1);

namespace Kufer\Web\Classes\Dbfilter\RegisteredCall;

use Kufer\Web\Classes\Dbfilter\AbstractSQLFilter;
use Kufer\Web\Classes\Dbfilter\SQLFilterUtils;

class RegisteredDBCallWoTage extends RegisteredDBCall
{
  public function getType(): int
  {
    return \Kufer\Web\Classes\Dbfilter\AbstractSQLFilter::TYPE_WO_TAGE;
  }

  public function getCapabilities(): int
  {
    return static::SUPPORTS_EQUALS
      | static::SUPPORTS_EQUALS_DEFAULT
      | static::SUPPORTS_IN
      | static::SUPPORTS_IN_DEFAULT;
  }

  public function like(AbstractSQLFilter $filter, $value): callable
  {
    throw new CallNotSupportedException('Abfrage like hier nicht unterstützt.');
  }

  public function contains(AbstractSQLFilter $filter, $value): callable
  {
    throw new CallNotSupportedException('Abfrage contains hier nicht unterstützt.');
  }

  public function is(AbstractSQLFilter $filter): callable
  {
    throw new CallNotSupportedException('Abfrage is hier nicht unterstützt.');
  }

  public function isDefault(AbstractSQLFilter $filter, $default): callable
  {
    throw new CallNotSupportedException('Abfrage is hier nicht unterstützt.');
  }

  public function equals(AbstractSQLFilter $filter, $value): callable
  {
    return $this->equalsDefault($filter, $value, $this->default);
  }

  public function equalsDefault(AbstractSQLFilter $filter, $value, $default): callable
  {
    if (\is_null($value)) {
      return SQLFilterUtils::filterEqualsStringDefault($this->table, $this->column, '', $default);
    }

    $value = \DateTimeOperations::getValidWoTagWithAlleString($value);
    if ($value === 'Mo, Di, Mi, Do, Fr, Sa, So' || $value === 'alle') {
      return SQLFilterUtils::filterInStringDefault($this->table, $this->column, array(
        'alle',
        'Mo, Di, Mi, Do, Fr, Sa, So'
      ), $default);
    }

    return SQLFilterUtils::filterEqualsStringDefault($this->table, $this->column, $value, $default);
  }

  public function in(AbstractSQLFilter $filter, iterable $value): callable
  {
    return $this->inDefault($filter, $value, $this->default);
  }

  public function inDefault(AbstractSQLFilter $filter, iterable $value, $default): callable
  {
    $value = implode(', ', $value);
    $value = \DateTimeOperations::getValidWoTagWithAlleString($value);
    if ($value === 'alle' || $value === '') { 
      return $this->equalsDefault($filter, $value, $default);
    }

    $wotage = array_map('\\trim', explode(',', $value));

    return function(\SelectQueryBuilder $builder) use ($wotage, $default): \SelectQueryBuilder {
      return $builder->orExpr(function(\SelectQueryBuilder $builder) use ($wotage, $default): \SelectQueryBuilder {
        $builder = $builder->orExpr(function(\SelectQueryBuilder $builder) use ($default): \SelectQueryBuilder {
          return SQLFilterUtils::filterEqualsStringDefault($this->table, $this->column, 'alle', $default)($builder);
        });
        $builder = $builder->orExpr(function(\SelectQueryBuilder $builder) use ($wotage, $default): \SelectQueryBuilder {
          return SQLFilterUtils::filterInStringDefault($this->table, $this->column, $wotage, $default)($builder);
        });

        return $builder->orExpr(function(\SelectQueryBuilder $builder) use ($wotage): \SelectQueryBuilder {
          foreach ($wotage as $wotag) {
            $builder = $builder->andExpr(function(\SelectQueryBuilder $builder) use ($wotag): \SelectQueryBuilder {
              $builder = $builder->orExpr(function(\SelectQueryBuilder $builder) use ($wotag): \SelectQueryBuilder {
                return SQLFilterUtils::filterCaseInsensitiveLike($this->table, $this->column, '%, ' . $wotag . ', %')($builder);
              });
              $builder = $builder->orExpr(function(\SelectQueryBuilder $builder) use ($wotag): \SelectQueryBuilder {
                return SQLFilterUtils::filterCaseInsensitiveLike($this->table, $this->column, $wotag . ', %')($builder);
              });

              return $builder->orExpr(function(\SelectQueryBuilder $builder) use ($wotag): \SelectQueryBuilder {
                return SQLFilterUtils::filterCaseInsensitiveLike($this->table, $this->column, '%, ' . $wotag)($builder);
              });
            });
          }

          return $builder;
        });
      });
    };
  }

  public function less(AbstractSQLFilter $filter, $value): callable
  {
    throw new CallNotSupportedException('Abfrage less hier nicht unterstützt.');
  }

  public function greater(AbstractSQLFilter $filter, $value): callable
  {
    throw new CallNotSupportedException('Abfrage greater hier nicht unterstützt.');
  }

  public function lessDefault(AbstractSQLFilter $filter, $value, $default): callable
  {
    throw new CallNotSupportedException('Abfrage less hier nicht unterstützt.');
  }

  public function greaterDefault(AbstractSQLFilter $filter, $value, $default): callable
  {
    throw new CallNotSupportedException('Abfrage greater hier nicht unterstützt.');
  }
}