<?php

namespace Diamond\Repositories\MailingList;


use Diamond\Domain\MailingList\Concrete\MailingListCriteriaInterface;
use Diamond\Domain\MailingList\Concrete\MailingListEntityInterface;
use Diamond\Domain\MailingList\MailingListCollection;
use Diamond\Domain\MailingList\ProgressData;
use Diamond\Infrastructure\Models\Mailing\Mailing;
use Diamond\Infrastructure\Models\Mailing\MailingQuery;
use Diamond\Infrastructure\Models\MailingRequest\MailingRequestQuery;
use Diamond\Infrastructure\Models\MailingRequestRecipient\MailingRequestRecipientQuery;
use Diamond\Repositories\PropelAbstractRepository;
use Propel\Runtime\ActiveQuery\Criteria;
use Propel\Runtime\ActiveQuery\ModelCriteria;
use Repo\CollectionInterface;
use Repo\CrudRepositoryBuilderInterface;
use Repo\EntityInterface;
use Repo\PaginationInterface;

class MailingListRepository extends PropelAbstractRepository implements CrudRepositoryBuilderInterface
{
    public static $PATH = BASEPATH . "/app/mailing";

    /**
     * @return EntityInterface
     */
    public static function createEntity(): EntityInterface
    {
        return new  Mailing();
    }

    /**
     * @return ModelCriteria
     */
    protected function createQuery(): ModelCriteria
    {
        return MailingQuery::create();
    }

    protected function modifyCriteria(PaginationInterface $criteria, ModelCriteria $dbCriteria): void
    {
        parent::modifyCriteriaForFilterSort($criteria, $dbCriteria);
    }


    protected function createCollection(): CollectionInterface
    {
        return new MailingListCollection();
    }

    /**
     * @param PaginationInterface $criteria
     * @return CollectionInterface|MailingListCollection
     * @throws \Repo\Concrete\Exceptions\Collection
     */
    public function findByCriteria(PaginationInterface $criteria): CollectionInterface
    {
        $query = $this->createQuery();
        $this->modifyCriteria($criteria, $query);
        $result = $query->paginate($criteria->getPage(), $criteria->getLimit());

        $collection = self::createCollection();

        $rows = $result->getResults();
        /**
         * @var MailingListEntityInterface $row
         */
        foreach ($rows as $row) {
            $this->addProgressData($row);

            $data = $row->getProgressData();

            if($criteria->getFilterByActive() === true && (!$data || $data->getReadyCount() === 0)){
                continue;
            }

            $collection->push($row);
        }

        return $collection;
    }

    /**
     * @param int $id
     * @return EntityInterface|MailingListEntityInterface|null
     */
    public function findById(int $id): ?EntityInterface
    {
        if (!$row = $this->createQuery()->findOneById($id)) {
            return null;
        }
        $this->addProgressData($row);
        return $row;
    }


    /**
     * Добаляет VO о инфе по данным загрузки
     * @param MailingListEntityInterface|Mailing $entity
     */
    private function addProgressData(MailingListEntityInterface $entity): void
    {

        $request = MailingRequestQuery::create()
            ->filterByMailingId($entity->getId())
            ->orderByCreatedAt(Criteria::DESC)
            ->findOne();

        if(!$request){
            return;
        }

        $items = MailingRequestRecipientQuery::create()
            ->filterByRequestId($request->getId())
            ->find();


        if ($items->count() > 0) {
            $progressData = new ProgressData($items, $request);
            $entity->setProgressData($progressData);
        }
    }

    /**
     * @deprecated
     * @param int $id
     * @return type
     */
    public function getFilePath(int $id): string
    {

        //создание каталога
        $pathFile = self::$PATH;

        if (!is_dir($pathFile)) {
            mkdir($pathFile);
        }
        return $pathFile . '/' . md5($id) . '.json';
    }

    /**
     * @param EntityInterface $entity
     */
    public function delete(EntityInterface $entity): void
    {
        //@unlink($this->getFilePath($entity->getId()));
        parent::delete($entity);
    }


}