<?php

declare(strict_types=1);

namespace Seka\Portal\Modul\Statistiky\Repositories\Eloquent\Presenters;

use League\Fractal\Resource\Item;
use League\Fractal\Resource\Collection;
use League\Fractal\TransformerAbstract;
use League\Fractal\Resource\NullResource;
use Prettus\Repository\Presenter\FractalPresenter;
use Seka\Portal\Modul\Statistiky\Entities\Zaznam\Zaznam;
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
use Seka\Portal\Modul\Statistiky\Entities\Zaznam\ValueObjects\Subjekt;
use Seka\Portal\Modul\Statistiky\Exceptions\NeznamiDruhUdajovZaznamuException;
use Seka\Portal\Modul\Statistiky\Entities\Zaznam\Enums\DruhSubjektuZaznamuEnum;
use Seka\Portal\Modul\Statistiky\Entities\Zaznam\ValueObjects\UdajePreTypZaznamuPracovisko;
use Seka\Portal\Modul\Statistiky\Entities\Zaznam\ValueObjects\UdajePreTypZaznamuPouzivatel;
use Seka\Portal\Modul\Statistiky\Repositories\Eloquent\Transformers\ZaznamDataTableTransformer;

/**
 * Class ZaznamDataTablePresenter
 *
 * @package Seka\Portal\Modul\Statistiky\Repositories\Eloquent\Presenters
 */
final class ZaznamDataTablePresenter extends FractalPresenter
{
    /**
     * @return \Seka\Portal\Modul\Statistiky\Repositories\Eloquent\Transformers\ZaznamDataTableTransformer
     */
    public function getTransformer(): TransformerAbstract
    {
        return new ZaznamDataTableTransformer();
    }

    /**
     * @param $data
     *
     * @return \League\Fractal\Resource\Collection|\League\Fractal\Resource\Item|\League\Fractal\Resource\NullResource
     * @throws \Seka\Portal\Modul\Statistiky\Exceptions\NeznamiDruhUdajovZaznamuException
     */
    protected function transformCollection($data)
    {
        if (is_null($data) || $data->isEmpty()) {
            return new NullResource();
        }

        /** @var \Seka\Portal\Modul\Statistiky\Entities\Zaznam\Zaznam $zaznam */
        $zaznam = $data->first();

        if ($zaznam->udaje instanceof UdajePreTypZaznamuPracovisko) {
            if ($data->count() === 1) {
                $_zaznam = clone $zaznam;
            } else {
                $_zaznam = new Zaznam([
                    'subjekt_druh' => DruhSubjektuZaznamuEnum::PRACOVISKO()->value,
                ]);
                $this->sumUdajePreTypZaznamuPracovisko($_zaznam, $data);
            }

            return new Item($_zaznam, $this->getTransformer(), $this->resourceKeyCollection);
        }

        if ($zaznam->udaje instanceof UdajePreTypZaznamuPouzivatel) {
            $out = [];
            $zaznamyPodlaPouzivatela = $data->groupBy('subjekt_nazov');

            foreach ($zaznamyPodlaPouzivatela as $menoPouzivatela => $zaznamyPouzivatela) {
                $_zaznam = new Zaznam();
                $_zaznam->subjekt = new Subjekt(DruhSubjektuZaznamuEnum::POUZIVATEL(), $menoPouzivatela);

                $this->sumUdajePreTypZaznamuPouzivatel($_zaznam, $zaznamyPouzivatela);

                $out[] = $_zaznam;
            }

            return new Collection($out, $this->getTransformer(), $this->resourceKeyCollection);
        }

        throw new NeznamiDruhUdajovZaznamuException('Neznami druh udajov zaznamu pre transformaciu.');
    }

    /**
     * @param \Seka\Portal\Modul\Statistiky\Entities\Zaznam\Zaznam $zaznam
     * @param \Illuminate\Database\Eloquent\Collection             $data
     */
    private function sumUdajePreTypZaznamuPracovisko(Zaznam &$zaznam, EloquentCollection $data)
    {
        $data->each(function (Zaznam $item) use (&$zaznam) {
            foreach ($item->udaje->zoznamPoctuKontrolPodlaStavu() as $pocet) {
                $zaznam->udaje->zoznamPoctuKontrolpodlaStavu()->add($pocet);
            }

            foreach ($item->udaje->zoznamPoctuKontrolPodlaDruhuAHodnotenia() as $pocet) {
                $zaznam->udaje->zoznamPoctuKontrolPodlaDruhuAHodnotenia()->add($pocet);
            }

            foreach ($item->udaje->zoznamPoctuKontrolPodlaKategorieVozidla() as $pocet) {
                $zaznam->udaje->zoznamPoctuKontrolPodlaKategorieVozidla()->add($pocet);
            }

            foreach ($item->udaje->zoznamPoctuKontrolAObratuPodlaSubjektuFakturacie() as $pocet) {
                $zaznam->udaje->zoznamPoctuKontrolAObratuPodlaSubjektuFakturacie()->add($pocet);
            }

            foreach ($item->udaje->zoznamPoctuKontrolPodlaDruhuPalivaAEmisnehoSystemuVozidla() as $pocet) {
                $zaznam->udaje->zoznamPoctuKontrolPodlaDruhuPalivaAEmisnehoSystemuVozidla()->add($pocet);
            }
        });
    }

    /**
     * @param \Seka\Portal\Modul\Statistiky\Entities\Zaznam\Zaznam $zaznam
     * @param \Illuminate\Database\Eloquent\Collection             $data
     */
    private function sumUdajePreTypZaznamuPouzivatel(Zaznam &$zaznam, $data)
    {
        $data->each(function (Zaznam $item) use (&$zaznam) {
            foreach ($item->udaje->zoznamPoctuKontrolPodlaDruhu() as $pocet) {
                $zaznam->udaje->zoznamPoctuKontrolPodlaDruhu()->add($pocet);
            }

            foreach ($item->udaje->zoznamPoctuKontrolPodlaHodnotenia() as $pocet) {
                $zaznam->udaje->zoznamPoctuKontrolPodlaHodnotenia()->add($pocet);
            }

            foreach ($item->udaje->zoznamPoctuKontrolPodlaStavu() as $pocet) {
                $zaznam->udaje->zoznamPoctuKontrolPodlaStavu()->add($pocet);
            }

            foreach ($item->udaje->zoznamPoctuKontrolSObratom() as $pocet) {
                $zaznam->udaje->zoznamPoctuKontrolSObratom()->add($pocet);
            }

            foreach ($item->udaje->zoznamPoctuKontrolPodlaKategorieVozidla() as $pocet) {
                $zaznam->udaje->zoznamPoctuKontrolPodlaKategorieVozidla()->add($pocet);
            }

            foreach ($item->udaje->zoznamPoctuKontrolPodlaDruhuPalivaAEmisnehoSystemuVozidla() as $pocet) {
                $zaznam->udaje->zoznamPoctuKontrolPodlaDruhuPalivaAEmisnehoSystemuVozidla()->add($pocet);
            }
        });
    }
}
