<commit_before><?php namespace App\Domain;

use App\Trip;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent;
use Illuminate\Support\Collection;

class TripStatsCalculator
{
    private $cities;
    private $lastDate;
    private $calendar;
    private $countries;
    private $newCities;
    private $firstDate;
    private $cityVisits;
    private $daysInTrips;
    private $daysInCities;
    private $newCountries;
    private $visitedCities;
    private $daysInCountries;
    private $visitedCountries;

    public function __construct(Eloquent\Collection $trips)
    {
        $this->cities = collect();
        $this->calendar = collect();
        $this->countries = collect();
        $this->newCities = collect();
        $this->newCountries = collect();
        $this->visitedCities = collect();
        $this->visitedCountries = collect();

        $this->daysInTrips = collect();
        $this->daysInCities = collect();
        $this->daysInCountries = collect();

        $this->calculate($trips);

        $this->cityVisits = $trips->mapToDictionary(fn (Trip $trip) => [$trip->city_id => $trip->id]);
    }

    public function calendar(): Collection
    {
        return $this->calendar;
    }

    public function citiesByYearsCount(): Collection
    {
        return $this->cities
            ->reverse()
            ->map(fn (Collection $cities) => $cities->unique()->count());
    }

    public function cityVisits(): Collection
    {
        return $this->cityVisits;
    }

    public function countriesByYearsCount(): Collection
    {
        return $this->countries
            ->reverse()
            ->map(fn (Collection $countries) => $countries->unique()->count());
    }

    public function daysInCities(): Collection
    {
        return $this->daysInCities
            ->map(fn ($years) => $years->reverse()->map(fn ($days) => count($days)));
    }

    public function daysInCountries(): Collection
    {
        return $this->daysInCountries
            ->map(fn ($years) => $years->reverse()->map(fn ($days) => count($days)));
    }

    public function daysInTrips(): Collection
    {
        return $this->daysInTrips
            ->reverse()
            ->map(fn ($trips) => count($trips));
    }

    public function firstDate(): CarbonImmutable
    {
        return $this->firstDate;
    }

    public function lastDate(): CarbonImmutable
    {
        return $this->lastDate;
    }

    public function newCitiesByYearsCount(): Collection
    {
        return $this->newCities->map(fn (Collection $cities) => $cities->count());
    }

    public function newCountriesByYearsCount(): Collection
    {
        return $this->newCountries->map(fn (Collection $countries) => $countries->count());
    }

    private function calculate(Eloquent\Collection $trips): void
    {
        /** @var Trip $trip */
        foreach ($trips as $trip) {
            $trip->loadCityAndCountry();

            $this->saveLastDate($trip);
            $this->saveFirstDate($trip);

            $this->pushTripDays($trip);
            $this->pushTripCity($trip->date_start->year, $trip->city_id);
            $this->pushTripCity($trip->date_end->year, $trip->city_id);
            $this->pushTripCountry($trip->date_start->year, $trip->city->country_id);
            $this->pushTripCountry($trip->date_end->year, $trip->city->country_id);
            $this->pushTripToCalendar($trip);
        }
    }

    private function pushCity(int $cityId, int $year): void
    {
        $this->cities[$year] ??= collect();
        $this->cities[$year][] = $cityId;
    }

    private function pushCountry(int $countryId, int $year): void
    {
        $this->countries[$year] ??= collect();<commit_msg>Типизация<commit_after><?php namespace App\Domain;

use App\Trip;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent;
use Illuminate\Support\Collection;

class TripStatsCalculator
{
    private Collection $cities;
    private Collection $calendar;
    private Collection $countries;
    private Collection $newCities;
    private Collection $daysInTrips;
    private Collection $daysInCities;
    private Collection $newCountries;
    private Collection $visitedCities;
    private Collection $daysInCountries;
    private Collection $visitedCountries;
    private ?CarbonImmutable $lastDate = null;
    private ?CarbonImmutable $firstDate = null;
    private Eloquent\Collection $cityVisits;

    /** @param \Illuminate\Database\Eloquent\Collection<int, \App\Trip> $trips */
    public function __construct(Eloquent\Collection $trips)
    {
        $this->cities = collect();
        $this->calendar = collect();
        $this->countries = collect();
        $this->newCities = collect();
        $this->newCountries = collect();
        $this->visitedCities = collect();
        $this->visitedCountries = collect();

        $this->daysInTrips = collect();
        $this->daysInCities = collect();
        $this->daysInCountries = collect();

        $this->calculate($trips);

        $this->cityVisits = $trips->mapToDictionary(fn (Trip $trip) => [$trip->city_id => $trip->id]);
    }

    public function calendar(): Collection
    {
        return $this->calendar;
    }

    public function citiesByYearsCount(): Collection
    {
        return $this->cities
            ->reverse()
            ->map(fn (Collection $cities) => $cities->unique()->count());
    }

    public function cityVisits(): Collection
    {
        return $this->cityVisits;
    }

    public function countriesByYearsCount(): Collection
    {
        return $this->countries
            ->reverse()
            ->map(fn (Collection $countries) => $countries->unique()->count());
    }

    public function daysInCities(): Collection
    {
        return $this->daysInCities
            ->map(fn ($years) => $years->reverse()->map(fn ($days) => count($days)));
    }

    public function daysInCountries(): Collection
    {
        return $this->daysInCountries
            ->map(fn ($years) => $years->reverse()->map(fn ($days) => count($days)));
    }

    public function daysInTrips(): Collection
    {
        return $this->daysInTrips
            ->reverse()
            ->map(fn ($trips) => count($trips));
    }

    public function firstDate(): CarbonImmutable
    {
        return $this->firstDate;
    }

    public function lastDate(): CarbonImmutable
    {
        return $this->lastDate;
    }

    public function newCitiesByYearsCount(): Collection
    {
        return $this->newCities->map(fn (Collection $cities) => $cities->count());
    }

    public function newCountriesByYearsCount(): Collection
    {
        return $this->newCountries->map(fn (Collection $countries) => $countries->count());
    }

    /** @param \Illuminate\Database\Eloquent\Collection<int, \App\Trip> $trips */
    private function calculate(Eloquent\Collection $trips): void
    {
        foreach ($trips as $trip) {
            $trip->loadCityAndCountry();

            $this->saveLastDate($trip);
            $this->saveFirstDate($trip);

            $this->pushTripDays($trip);
            $this->pushTripCity($trip->date_start->year, $trip->city_id);
            $this->pushTripCity($trip->date_end->year, $trip->city_id);
            $this->pushTripCountry($trip->date_start->year, $trip->city->country_id);
            $this->pushTripCountry($trip->date_end->year, $trip->city->country_id);
            $this->pushTripToCalendar($trip);
        }
    }

    private function pushCity(int $cityId, int $year): void
    {
        $this->cities[$year] ??= collect();
        $this->cities[$year][] = $cityId;
    }

    private function pushCountry(int $countryId, int $year): void
    {
        $this->countries[$year] ??= collect();
{'fraction_non_alphanumeric': 0.14826294717809635, 'fraction_numerical': 0.0, 'mean_word_length': 2.659735349716446, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 171, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7038762', 'n_tokens_mistral': 2336, 'n_tokens_neox': 2251, 'n_words': 441}