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;
}
}