<?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\Entities\Zaznam\Enums\DruhSubjektuZaznamuEnum;
use Seka\Portal\Modul\Statistiky\Http\Controllers\Controller;
use Seka\Portal\Modul\Statistiky\Http\Requests\ZaznamFilterRequest;
use Seka\Portal\Modul\Statistiky\Http\View\ZaznamDatumFilterEnum;
use Seka\Portal\Modul\Statistiky\Repositories\Eloquent\Criteria\Zaznam\ZaznamDatumBetweenCriteria;
use Seka\Portal\Modul\Statistiky\Repositories\ZaznamRepositoryContract;

/**
 * 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\View\ZaznamDatumFilterEnum $dateFilter
     *
     * @return mixed
     */
    abstract protected function makeView(ZaznamDatumFilterEnum $dateFilter);

    /**
     * @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)
    {
        $dateFilterEnum = ZaznamDatumFilterEnum::from($filterRequest->get('datefilter'));

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

    /**
     * @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 = $dnes->copy()->subWeek()->startOfWeek();
                $do = $od->copy()->endOfWeek();
                break;
            case ZaznamDatumFilterEnum::AKTUALNY_MESIAC:
                $od = $dnes->startOfMonth();
                break;
            case ZaznamDatumFilterEnum::PREDCHADZAJUCI_MESIAC:
                $od = $dnes->copy()->subMonth()->startOfMonth();
                $do = $od->copy()->endOfMonth();
                break;
            case ZaznamDatumFilterEnum::AKTUALNY_STVRTROK:
                $od = $dnes->startOfQuarter();
                break;
            case ZaznamDatumFilterEnum::PREDCHADZAJUCI_STVRTROK:
                $od = $dnes->copy()->subQuarter()->startOfQuarter();
                $do = $od->copy()->endOfQuarter();
                break;
            case ZaznamDatumFilterEnum::AKTUALNY_POLROK:
                $od = ($dnes->month < 7) ? $dnes->startOfYear() : $dnes->month(7)->startOfMonth();
                break;
            case ZaznamDatumFilterEnum::PREDCHADZAJUCI_POLROK:
                $od = ($dnes->month < 7) ? $dnes->copy()->subYear()->month(7)->startOfMonth() : $dnes->copy()->startOfYear();
                $do = ($od->year != $do->year) ? $od->copy()->month(12)->endOfMonth() : $od->copy()->month(6)->endOfMonth();
                break;
            case ZaznamDatumFilterEnum::AKTUALNY_ROK:
                $od = $dnes->startOfYear();
                break;
            case ZaznamDatumFilterEnum::PREDCHADZAJUCI_ROK:
                $od = $dnes->copy()->subYear()->startOfYear();
                $do = $od->copy()->endOfYear();
                break;
            case ZaznamDatumFilterEnum::POUZIVATELOM_SPECIFIKOVANY_ROZSAH:
                $od = Carbon::createFromTimestamp(strtotime(request('date_from', 'now')));
                $do = Carbon::createFromTimestamp(strtotime(request('date_to', 'now')));
                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,
                ]
            );
    }
}
