<?php

namespace App\Console\Commands;

use App\Models\Pouzivatel\Pouzivatel;
use App\Services\PushNotificationsService\PushNotificationsServiceContract;
use Illuminate\Console\Command;

/**
 * Class FcmTokenValidationCheckCommand
 */
class FcmTokenValidationCheckCommand extends Command
{
    /**
     * limit pre chunk z databazy
     */
    private const CHUNK_LIMIT = 200;

    /**
     * @var string
     */
    protected $signature = 'notifikacia:overenie-platnosti-tokenov 
                            {--odstranit-neplatne : Odstranit neplatne tokeny z databazy}';

    /**
     * Popis prikazu
     *
     * @var string
     */
    protected $description = 'Preverí platnosť všetkých existujúcich notifikačných tokenov používateľov';

    private PushNotificationsServiceContract $pushNotificationsService;

    /**
     * Nazov stlpca notifikacneho tokenu v databaze
     */
    private string $tokenColumnName = 'notification_token';

    public function __construct(PushNotificationsServiceContract $pushNotificationsService)
    {
        parent::__construct();
        $this->pushNotificationsService = $pushNotificationsService;
    }

    public function handle(): void
    {
        $invalidTokenCounter = 0;

        $this->info('Vyhladavaju sa vsetky notifikacne tokeny pouzivatelov...');

        Pouzivatel::query()->select($this->tokenColumnName)->whereNotNull($this->tokenColumnName)->chunk(
            self::CHUNK_LIMIT,
            function ($tokens) use (&$invalidTokenCounter) {
                /** @var \Illuminate\Database\Eloquent\Collection<Pouzivatel> $tokens */
                $tokensArray = $tokens->pluck($this->tokenColumnName)->toArray();
                $badTokens = $this->pushNotificationsService->validateUsersTokens($tokensArray);
                $invalidTokenCounter += count($badTokens);

                if ($this->option('odstranit-neplatne')) {
                    $this->removeNotificationTokens($badTokens, $this->tokenColumnName);
                }
            },
        );

        $this->info(sprintf('Bolo najdenych %s neplatnych notifikacnych tokenov.', $invalidTokenCounter));
        if ($this->option('odstranit-neplatne')) {
            $this->info(sprintf('Odstranilo sa %s neplatnych notifikacnych tokenov.', $invalidTokenCounter));
        }
    }

    private function removeNotificationTokens(array $badTokens, string $tokenColumnName): void
    {
        if (! empty($badTokens)) {
            Pouzivatel::query()->whereIn($tokenColumnName, $badTokens)->update([$tokenColumnName => null]);
        }
    }
}
