<?php

declare(strict_types=1);

namespace Seka\Portal\Modul\Statistiky\Http\Controllers\Frontend;

use Carbon\Carbon;
use DateTimeInterface;
use Illuminate\Database\Eloquent\Collection;
use Seka\Portal\Modul\Statistiky\Http\Controllers\Controller;
use Seka\Portal\Modul\Statistiky\Http\View\ZaznamDatumFilterEnum;
use Seka\Portal\Modul\Statistiky\Http\Requests\ZaznamFilterRequest;
use Seka\Portal\Modul\Statistiky\Repositories\ZaznamRepositoryContract;
use Seka\Portal\Modul\Statistiky\Entities\Zaznam\Enums\DruhSubjektuZaznamuEnum;
use Seka\Portal\Modul\Statistiky\Repositories\Eloquent\Criteria\Zaznam\ZaznamDatumBetweenCriteria;

/**
 * Class FilterController
 *
 * @package Seka\Portal\Modul\Statistiky\Http\Controllers\Frontend
 */
abstract class FilterController extends Controller
{
    /**
     * @var \Seka\Portal\Modul\Statistiky\Repositories\ZaznamRepositoryContract
     */
    protected ZaznamRepositoryContract $zaznamRepository;

    /**
     * PracoviskoController constructor.
     */
    public function __construct(ZaznamRepositoryContract $zaznamRepository)
    {
        $this->zaznamRepository = $zaznamRepository;
    }

    /**
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View|mixed
     */
    public function index()
    {
        return $this->makeView(ZaznamDatumFilterEnum::AKTUALNY_TYZDEN());
    }

    /**
     * @param \Seka\Portal\Modul\Statistiky\Http\Requests\ZaznamFilterRequest $filterRequest
     *
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View|mixed
     */
    public function filter(ZaznamFilterRequest $filterRequest)
    {
        /* @var \Seka\Portal\Modul\Statistiky\Http\View\ZaznamDatumFilterEnum $dateFilterEnum */
        $dateFilterEnum = $filterRequest->get('datefilter');

        return $this->makeView($dateFilterEnum);
    }

    /**
     * @param \Seka\Portal\Modul\Statistiky\Http\View\ZaznamDatumFilterEnum $dateFilter
     *
     * @return mixed
     */
    abstract protected function makeView(ZaznamDatumFilterEnum $dateFilter);

    /**
     * @param \Seka\Portal\Modul\Statistiky\Http\View\ZaznamDatumFilterEnum $dateFilterEnum
     *
     * @return \DateTimeInterface[]
     */
    protected function getFromDate(ZaznamDatumFilterEnum $dateFilterEnum): array
    {
        $do = Carbon::now()->startOfDay();
        $dnes = Carbon::now()->startOfDay();

        switch ($dateFilterEnum) {
            case ZaznamDatumFilterEnum::AKTUALNY_TYZDEN():
                $od = $dnes->startOfWeek();
                break;
            case ZaznamDatumFilterEnum::PREDCHADZAJUCI_TYZDEN():
                $od = (clone $dnes)->subWeek()->startOfWeek();
                $do = (clone $od)->endOfWeek();
                break;
            case ZaznamDatumFilterEnum::AKTUALNY_MESIAC():
                $od = $dnes->startOfMonth();
                break;
            case ZaznamDatumFilterEnum::PREDCHADZAJUCI_MESIAC():
                $od = (clone $dnes)->subMonth()->startOfMonth();
                $do = (clone $od)->endOfMonth();
                break;
            case ZaznamDatumFilterEnum::AKTUALNY_STVRTROK():
                $od = $dnes->startOfQuarter();
                break;
            case ZaznamDatumFilterEnum::PREDCHADZAJUCI_STVRTROK():
                $od = (clone $dnes)->subQuarter()->startOfQuarter();
                $do = (clone $od)->endOfQuarter();
                break;
            case ZaznamDatumFilterEnum::AKTUALNY_POLROK():
                $od = $dnes->month < 7 ? $dnes->startOfYear() : $dnes->month(7)->startOfMonth();
                break;
            case ZaznamDatumFilterEnum::PREDCHADZAJUCI_POLROK():
                $od = (clone $dnes);
                $od = $od->month < 7 ? $od->subYear()->startOfYear()->addMonths(6) : $od->month(7)->startOfMonth();
                if ($od->year != $do->year) $do = (clone $od)->addMonths(5)->endOfMonth();
                break;
            case ZaznamDatumFilterEnum::AKTUALNY_ROK():
                $od = $dnes->startOfYear();
                break;
            case ZaznamDatumFilterEnum::PREDCHADZAJUCI_ROK():
                $od = (clone $dnes)->subYear()->startOfYear();
                $do = (clone $od)->endOfYear();
                break;
            default:
                $od = Carbon::now()->startOfDay();
        }

        return [$od, $do];
    }

    /**
     * @param int                                                                         $pekId
     * @param \DateTimeInterface                                                          $from
     * @param \DateTimeInterface                                                          $to
     * @param \Seka\Portal\Modul\Statistiky\Entities\Zaznam\Enums\DruhSubjektuZaznamuEnum $druhSubjektuZaznamu
     *
     * @return \Illuminate\Database\Eloquent\Collection
     * @throws \Prettus\Repository\Exceptions\RepositoryException
     */
    protected function getData(
        int $pekId,
        DateTimeInterface $from,
        DateTimeInterface $to,
        DruhSubjektuZaznamuEnum $druhSubjektuZaznamu
    ): Collection
    {
        $criteria = new ZaznamDatumBetweenCriteria($from, $to);
        $this->zaznamRepository->pushCriteria($criteria);

        return $this->zaznamRepository
            ->skipPresenter()
            ->findWhere(
                [
                    'pracovisko_id' => $pekId,
                    'subjekt_druh' => $druhSubjektuZaznamu,
                ]
            );
    }
}
