<?php declare(strict_types=1);

namespace App\Repositories;

use App\Dto\Repository\CaptchaLogRepository\QuantityByDays;
use App\Enums\CaptchaLogType;
use App\Models\CaptchaLog;
use App\Services\Search\CreateSearchInstanceCommand;
use App\Services\Search\Search;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Carbon;

final class CaptchaLogRepository
{
    public function __construct(
        private CreateSearchInstanceCommand $createSearchInstanceCommand,
    ) { }

    public function getCaptchaLogs(array $with = []): Search
    {
        $query = CaptchaLog::query()
            ->with($with)
            ->latest();

        return $this->createSearchInstanceCommand->execute($query);
    }

    public function countByType(CaptchaLogType $type, ?int $captchaId = null): int
    {
        return CaptchaLog::query()
            ->when($captchaId, function (Builder $query, int $captchaId) {
                $query->where('captcha_id', $captchaId);
            })
            ->where('type', '=', $type)
            ->count();
    }

    public function getCaptchaLogsByTypes(array $types, ?int $captchaId = null, ?int $limit = null): Collection
    {
        return CaptchaLog::query()
            ->when($captchaId, function (Builder $query, int $captchaId) {
                $query->where('captcha_id', $captchaId);
            })
            ->when($limit, function (Builder $query, int $limit) {
                $query->limit($limit);
            })
            ->whereIn('type', $types)
            ->latest()
            ->get();
    }

    public function countByDays(Carbon $from, Carbon $to): QuantityByDays
    {
        $count = CaptchaLog::query()
            ->selectRaw('DATE_FORMAT(created_at, \'%Y-%m-%d\') AS date, type, COUNT(id) AS count')
            ->where('created_at', '>=', $from)
            ->where('created_at', '<=', $to)
            ->groupBy('date', 'type')
            ->orderBy('date', 'asc')
            ->get();

        $quantity = new QuantityByDays();
        foreach ($count as $item) {
            $quantity->add($item->date, $item->type, $item->count);
        }

        return $quantity;
    }
}
