0
respostas

Uma nova refatoração

Bom Dia!

Avancei um pouco a mais na refatoração e acredito que esteja em uma estrutura de boa legibilidade e estrutura

<?php

namespace Alura\Calisthenics\Domain\Student;

use Alura\Calisthenics\Domain\Video\Video;

use DateTimeImmutable;
use DateTimeInterface;
use Ds\Map;
use InvalidArgumentException;

class Student
{
    public string $street;
    public string $number;
    public string $province;
    public string $city;
    public string $state;
    public string $country;
    private string $email;
    private DateTimeInterface $bd;
    private Map $watchedVideos;
    private string $fName;
    private string $lName;

    public function __construct(
        string $email,
        DateTimeInterface $bd,
        string $fName,
        string $lName,
        string $street,
        string $number,
        string $province,
        string $city,
        string $state,
        string $country
    ) {
        $this->watchedVideos = new Map();
        $this->setEmail($email);
        $this->bd = $bd;
        $this->fName = $fName;
        $this->lName = $lName;
        $this->street = $street;
        $this->number = $number;
        $this->province = $province;
        $this->city = $city;
        $this->state = $state;
        $this->country = $country;
    }

    private function setEmail(string $email)
    {
        if (filter_var($email, FILTER_VALIDATE_EMAIL) !== false) {
            $this->email = $email;
        } else {
            throw new InvalidArgumentException('Invalid e-mail address');
        }
    }

    public function getFullName(): string
    {
        return "{$this->fName} {$this->lName}";
    }

    public function getEmail(): string
    {
        return $this->email;
    }

    public function getBd(): DateTimeInterface
    {
        return $this->bd;
    }

    public function watch(Video $video, DateTimeInterface $date)
    {
        $this->watchedVideos->put($video, $date);
    }

    public function hasAccess(): bool
    {
        if ($this->watchedVideos->count() === 0) {
            return true;
        }
        return $this->firstVideoWasWatchedInLessThen90Days();
    }

    private function firstVideoWasWatchedInLessThen90Days(): bool
    {
        $this->sortVideosByDateWatch();

        return $this->firstViewLessThen90Days();
    }

    private function sortVideosByDateWatch(): void
    {
        $this->watchedVideos->sort(fn(DateTimeInterface $dateA, DateTimeInterface $dateB) => $dateA <=> $dateB);
    }

    private function getDateByFirstViewWatch(): DateTimeInterface
    {
        /** @var DateTimeInterface $firstDate */
        return $this->watchedVideos->first()->value;
    }

    private function firstViewLessThen90Days(): bool
    {
        $today = new DateTimeImmutable();
        return $this->getDateByFirstViewWatch()->diff($today)->days >= 90;
    }


}