<?php

namespace App\Subscription\Entity;

use App\Subscription\Repository\SubscriptionPlanRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;

#[ORM\Entity(repositoryClass: SubscriptionPlanRepository::class)]
#[ORM\Table(name: 'subscription_plans')]
class SubscriptionPlan
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private ?int $id = null;

    #[ORM\Column(type: 'string', length: 36, unique: true)]
    private string $uuid;

    #[ORM\Column(type: 'string', length: 30, unique: true)]
    private string $name;

    #[ORM\Column(type: 'smallint')]
    private int $level;

    #[ORM\Column(name: 'max_secretaries', type: 'smallint')]
    private int $maxSecretaries = 1;

    #[ORM\Column(type: 'json')]
    private array $features = [];

    #[ORM\Column(type: 'boolean')]
    private bool $active = true;

    #[ORM\Column(name: 'created_at', type: 'integer')]
    private int $createdAt;

    #[ORM\Column(name: 'updated_at', type: 'integer')]
    private int $updatedAt;

    #[ORM\OneToMany(targetEntity: SubscriptionPeriod::class, mappedBy: 'plan')]
    private Collection $periods;

    public function __construct(string $name, int $level, int $maxSecretaries, array $features)
    {
        $this->uuid           = Uuid::v4()->toRfc4122();
        $this->name           = $name;
        $this->level          = $level;
        $this->maxSecretaries = $maxSecretaries;
        $this->features       = $features;
        $this->createdAt      = time();
        $this->updatedAt      = time();
        $this->periods        = new ArrayCollection();
    }

    public function getId(): ?int          { return $this->id; }
    public function getUuid(): string      { return $this->uuid; }
    public function getName(): string      { return $this->name; }
    public function getLevel(): int        { return $this->level; }
    public function getMaxSecretaries(): int { return $this->maxSecretaries; }
    public function getFeatures(): array   { return $this->features; }
    public function isActive(): bool       { return $this->active; }
    public function getCreatedAt(): int    { return $this->createdAt; }
    public function getUpdatedAt(): int    { return $this->updatedAt; }
    public function getPeriods(): Collection { return $this->periods; }

    public function setName(string $name): self           { $this->name = $name; $this->updatedAt = time(); return $this; }
    public function setLevel(int $level): self            { $this->level = $level; $this->updatedAt = time(); return $this; }
    public function setMaxSecretaries(int $v): self       { $this->maxSecretaries = $v; $this->updatedAt = time(); return $this; }
    public function setFeatures(array $features): self    { $this->features = $features; $this->updatedAt = time(); return $this; }
    public function setActive(bool $active): self         { $this->active = $active; $this->updatedAt = time(); return $this; }

    public function hasFeature(string $feature): bool
    {
        return (bool) ($this->features[$feature] ?? false);
    }

    public function toArray(bool $withPeriods = false): array
    {
        $data = [
            'uuid'            => $this->uuid,
            'name'            => $this->name,
            'level'           => $this->level,
            'max_secretaries' => $this->maxSecretaries,
            'features'        => $this->features,
            'active'          => $this->active,
        ];

        if ($withPeriods) {
            $data['periods'] = array_values(array_map(
                fn(SubscriptionPeriod $p) => $p->toArray(),
                $this->periods->filter(fn(SubscriptionPeriod $p) => $p->isActive())->toArray()
            ));
        }

        return $data;
    }
}
