<?php
namespace App\Entity\Core\Classroom;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use JsonSerializable;
#[ORM\Table('classroom_point_pool')]
#[ORM\Entity(repositoryClass: ClassroomPointPoolRepository::class)]
class ClassroomPointPool implements JsonSerializable
{
private const int DEFAULT_POINT_GOAL_PER_STUDENT = 200;
private const array MULTIPLIERS = [
'easy' => 0.75,
'medium' => 1.00,
'hard' => 1.25
];
#[ORM\Column(name: 'id', type: 'integer')]
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'AUTO')]
private int $id;
#[ORM\JoinColumn(name: 'classroom_id', referencedColumnName: 'id', onDelete: 'CASCADE', nullable: false)]
#[ORM\ManyToOne(targetEntity: Classroom::class)]
private Classroom $classroom;
#[ORM\Column(name: 'start')]
private DateTime $start;
#[ORM\Column(name: 'complete', nullable: true)]
private ?DateTime $complete;
#[ORM\Column(name: 'point_goal')]
private int $pointGoal;
#[ORM\Column(name: 'current_points')]
private int $currentPoints;
#[ORM\Column(name: 'difficulty', type: 'string', length: 16, options: ['default' => 'medium'])]
private string $difficulty = 'medium';
#[ORM\Column(name: 'goal_description', nullable: true)]
private ?string $goalDescription;
public function getId(): int
{
return $this->id;
}
public function setId(int $id): void
{
$this->id = $id;
}
public function getClassroom(): Classroom
{
return $this->classroom;
}
public function setClassroom(Classroom $classroom): void
{
$this->classroom = $classroom;
}
public function getStart(): DateTime
{
return $this->start;
}
public function setStart(DateTime $start): void
{
$this->start = $start;
}
public function getComplete(): ?DateTime
{
return $this->complete;
}
public function setComplete(?DateTime $complete): void
{
$this->complete = $complete;
}
public function getPointGoal(): int
{
return $this->pointGoal;
}
public function setPointGoal(int $pointGoal): void
{
$this->pointGoal = $pointGoal;
}
public function getCurrentPoints(): int
{
return $this->currentPoints;
}
public function setCurrentPoints(int $currentPoints): void
{
$this->currentPoints = $currentPoints;
}
public function getDifficulty(): string
{
return $this->difficulty;
}
public function setDifficulty(string $difficulty): void
{
$this->difficulty = $difficulty;
}
public function getGoalDescription(): ?string
{
return $this->goalDescription;
}
public function setGoalDescription(?string $goalDescription): void
{
$this->goalDescription = $goalDescription;
}
public function updatePointGoal(): bool
{
$numStudents = count($this->getClassroom()->getMembers());
$multiplier = self::MULTIPLIERS[$this->difficulty] ?? self::MULTIPLIERS['medium'];
$newGoal = max($numStudents, 1) * self::DEFAULT_POINT_GOAL_PER_STUDENT * $multiplier;
if ($newGoal !== $this->pointGoal) {
$this->pointGoal = $newGoal;
return true;
}
return false;
}
public function getProgressPercentage(): float
{
if ($this->pointGoal === 0)
return 0.0;
$progress = $this->currentPoints / $this->pointGoal * 100;
return min(round($progress, 1), 100.0);
}
public function jsonSerialize(): array
{
return [
'id' => $this->id,
'classroom' => [
'id' => $this->classroom->getId(),
'name' => $this->classroom->getName()
],
'start' => $this->start,
'complete' => $this->complete,
'pointGoal' => $this->pointGoal,
'currentPoints' => $this->currentPoints,
'progressPercentage' => $this->getProgressPercentage(),
'difficulty' => $this->difficulty,
'goalDescription' => $this->goalDescription
];
}
}