<?php

namespace common\logic;

use common\components\ActiveRecordCommon;
use common\logic\Distribution\Distribution\Service\DistributionDefinition;
use yii\data\ActiveDataProvider;
use yii\db\ActiveQuery;

abstract class AbstractRepositoryQuery extends AbstractService implements RepositoryQueryInterface
{
    protected ActiveQuery $query;

    public function loadDefinition(string $serviceClass): void
    {
        $this->definition = $this->loadService($serviceClass);
    }

    public function getDefinition()
    {
        return $this->definition;
    }

    public function baseQuery(): ActiveQuery
    {
        $class = $this->definition->getEntityFqcn();
        return $class::find();
    }

    public function createQuery(): self
    {
        $this->query = $this->baseQuery();

        return $this;
    }

    public function __call(string $name, $params): self
    {
        call_user_func_array([$this->query, $name], $params);

        return $this;
    }

    public function query()
    {
        return $this->query;
    }

    public function count()
    {
        $class = $this->definition->getEntityFqcn();
        $class::groupByPrimaryKey($class, $this->query);

        return $this->query->count();
    }

    public function find()
    {
        return $this->query->all();
    }

    public function findOne()
    {
        return $this->query->one();
    }

    public function filterById(int $id): self
    {
        $class = $this->definition->getEntityFqcn();
        $this->query->andWhere([$class::tableName().'.id' => $id]);

        return $this;
    }

    public function filterByCondition(string $condition = ''): self
    {
        if($condition && strlen($condition) > 0) {
            $this->andWhere($condition);
        }

        return $this;
    }

    public function filterIsStatusOnline()
    {
        $this->andWhere(['status' => StatusInterface::STATUS_ONLINE]);
        return $this;
    }

    public function filterIsStatusOnlineAndOffline()
    {
        $this->andWhere('status >= :status')->addParams(['status' => StatusInterface::STATUS_OFFLINE]);
        return $this;
    }

    public function filterIsStatusDeleted()
    {
        $this->andWhere(['status' => StatusInterface::STATUS_DELETED]);
        return $this;
    }

    public function getDataProvider(int $pageSize): ActiveDataProvider
    {
        return new ActiveDataProvider([
            'query' => $this->query,
            'sort' => false,
            'pagination' => [
                'pageSize' => $pageSize,
            ],
        ]);
    }
}