<?php
namespace App\Entity;
use App\Repository\SubmissionRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: SubmissionRepository::class)]
class Submission
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\ManyToOne(inversedBy: 'submissions')]
#[ORM\JoinColumn(nullable: false)]
private ?User $user = null;
#[ORM\ManyToOne(inversedBy: 'submissions')]
#[ORM\JoinColumn(nullable: false)]
private ?Activity $activity = null;
#[ORM\ManyToOne(inversedBy: 'submissions')]
#[ORM\JoinColumn(nullable: false)]
private ?Season $season = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $evidenceUrl = null;
#[ORM\Column(length: 50)]
private ?string $status = null;
#[ORM\Column]
private ?int $pointsAwarded = null;
#[ORM\Column]
private ?\DateTimeImmutable $submittedAt = null;
#[ORM\Column(nullable: true)]
private ?\DateTimeImmutable $approvedAt = null;
#[ORM\ManyToOne]
private ?User $approvedBy = null;
#[ORM\Column(type: Types::JSON, nullable: true)]
private ?array $activityData = null;
#[ORM\Column]
private ?bool $teamSubmission = false;
#[ORM\Column(type: Types::JSON, nullable: true)]
private ?array $teamMembers = null;
public function __construct()
{
$this->submittedAt = new \DateTimeImmutable();
$this->status = 'pending';
$this->pointsAwarded = 0;
}
public function getId(): ?int
{
return $this->id;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): static
{
$this->user = $user;
return $this;
}
public function getActivity(): ?Activity
{
return $this->activity;
}
public function setActivity(?Activity $activity): static
{
$this->activity = $activity;
return $this;
}
public function getSeason(): ?Season
{
return $this->season;
}
public function setSeason(?Season $season): static
{
$this->season = $season;
return $this;
}
public function getEvidenceUrl(): ?string
{
return $this->evidenceUrl;
}
public function setEvidenceUrl(?string $evidenceUrl): static
{
$this->evidenceUrl = $evidenceUrl;
return $this;
}
public function getStatus(): ?string
{
return $this->status;
}
public function setStatus(string $status): static
{
$this->status = $status;
return $this;
}
public function getPointsAwarded(): ?int
{
return $this->pointsAwarded;
}
public function setPointsAwarded(int $pointsAwarded): static
{
$this->pointsAwarded = $pointsAwarded;
return $this;
}
public function getSubmittedAt(): ?\DateTimeImmutable
{
return $this->submittedAt;
}
public function setSubmittedAt(\DateTimeImmutable $submittedAt): static
{
$this->submittedAt = $submittedAt;
return $this;
}
public function getApprovedAt(): ?\DateTimeImmutable
{
return $this->approvedAt;
}
public function setApprovedAt(?\DateTimeImmutable $approvedAt): static
{
$this->approvedAt = $approvedAt;
return $this;
}
public function getApprovedBy(): ?User
{
return $this->approvedBy;
}
public function setApprovedBy(?User $approvedBy): static
{
$this->approvedBy = $approvedBy;
return $this;
}
/**
* Check if the submission is pending
*/
public function isPending(): bool
{
return $this->status === 'pending';
}
/**
* Check if the submission is approved
*/
public function isApproved(): bool
{
return $this->status === 'approved';
}
/**
* Check if the submission is rejected
*/
public function isRejected(): bool
{
return $this->status === 'rejected';
}
/**
* Approve the submission
*/
public function approve(User $approver, int $points = null): static
{
$this->status = 'approved';
$this->approvedAt = new \DateTimeImmutable();
$this->approvedBy = $approver;
if ($points !== null) {
$this->pointsAwarded = $points;
} else {
$this->pointsAwarded = $this->activity->getPoints();
}
return $this;
}
/**
* Reject the submission
*/
public function reject(User $approver): static
{
$this->status = 'rejected';
$this->approvedAt = new \DateTimeImmutable();
$this->approvedBy = $approver;
$this->pointsAwarded = 0;
return $this;
}
public function getActivityData(): ?array
{
return $this->activityData;
}
public function setActivityData(?array $activityData): static
{
$this->activityData = $activityData;
return $this;
}
public function isTeamSubmission(): ?bool
{
return $this->teamSubmission;
}
public function setTeamSubmission(bool $teamSubmission): static
{
$this->teamSubmission = $teamSubmission;
return $this;
}
public function getTeamMembers(): ?array
{
return $this->teamMembers;
}
public function setTeamMembers(?array $teamMembers): static
{
$this->teamMembers = $teamMembers;
return $this;
}
/**
* Get specific activity data value
*/
public function getActivityDataValue(string $key, $default = null)
{
if ($this->activityData === null || !isset($this->activityData[$key])) {
return $default;
}
return $this->activityData[$key];
}
/**
* Set specific activity data value
*/
public function setActivityDataValue(string $key, $value): static
{
if ($this->activityData === null) {
$this->activityData = [];
}
$this->activityData[$key] = $value;
return $this;
}
/**
* Add a team member to the submission
*/
public function addTeamMember(User $user): static
{
if ($this->teamMembers === null) {
$this->teamMembers = [];
}
if (!in_array($user->getId(), $this->teamMembers)) {
$this->teamMembers[] = $user->getId();
}
return $this;
}
/**
* Remove a team member from the submission
*/
public function removeTeamMember(User $user): static
{
if ($this->teamMembers === null) {
return $this;
}
$key = array_search($user->getId(), $this->teamMembers);
if ($key !== false) {
unset($this->teamMembers[$key]);
$this->teamMembers = array_values($this->teamMembers);
}
return $this;
}
/**
* Check if a user is a team member in this submission
*/
public function isTeamMember(User $user): bool
{
if ($this->teamMembers === null) {
return false;
}
return in_array($user->getId(), $this->teamMembers);
}
/**
* Get the display name for the activity, including passport item if applicable
*/
public function getActivityDisplayName(): string
{
$activityName = $this->activity ? $this->activity->getName() : 'Unknown Activity';
// Check if this is a passport activity with a selected item
$validationSchema = $this->activity ? $this->activity->getValidationSchema() : null;
if ($validationSchema &&
isset($validationSchema['type']) &&
$validationSchema['type'] === 'passport' &&
$this->activityData &&
isset($this->activityData['selectedItem'])) {
return $activityName . ' (' . $this->activityData['selectedItem'] . ')';
}
return $activityName;
}
}