<?php

declare(strict_types=1);

namespace App\Entity\Central;

use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Table(name: 'licenses')]
#[ORM\HasLifecycleCallbacks]
class License
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: Types::INTEGER)]
    private ?int $id = null;

    #[ORM\ManyToOne(targetEntity: Tenant::class)]
    #[ORM\JoinColumn(nullable: false)]
    private Tenant $tenant;

    #[ORM\Column(type: Types::STRING, length: 64, unique: true)]
    private string $licenseKey;

    #[ORM\Column(type: Types::STRING, length: 20)]
    private string $type;

    #[ORM\Column(type: Types::STRING, length: 20)]
    private string $plan;

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
    private \DateTimeImmutable $startsAt;

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
    private ?\DateTimeImmutable $expiresAt = null;

    #[ORM\Column(type: Types::BOOLEAN, options: ['default' => true])]
    private bool $isActive = true;

    #[ORM\Column(type: Types::INTEGER, options: ['default' => 5])]
    private int $maxUsers = 5;

    #[ORM\Column(type: Types::INTEGER, options: ['default' => 0])]
    private int $maxNews = 0;

    #[ORM\Column(type: Types::INTEGER, options: ['default' => 5120])]
    private int $maxStorageMb = 5120;

    /** Price in minor currency unit (e.g. TRY as integer, 799 = 799₺) */
    #[ORM\Column(type: Types::INTEGER, options: ['default' => 0])]
    private int $price = 0;

    #[ORM\Column(type: Types::STRING, length: 10, options: ['default' => 'TRY'])]
    private string $currency = 'TRY';

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
    private \DateTimeImmutable $createdAt;

    private const VALID_TYPES = ['monthly', 'yearly', 'lifetime'];
    private const VALID_PLANS = ['starter', 'professional', 'enterprise'];

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getTenant(): Tenant
    {
        return $this->tenant;
    }

    public function setTenant(Tenant $tenant): self
    {
        $this->tenant = $tenant;

        return $this;
    }

    public function getLicenseKey(): string
    {
        return $this->licenseKey;
    }

    public function setLicenseKey(string $licenseKey): self
    {
        $this->licenseKey = $licenseKey;

        return $this;
    }

    public function getType(): string
    {
        return $this->type;
    }

    public function setType(string $type): self
    {
        if (!in_array($type, self::VALID_TYPES, true)) {
            throw new \InvalidArgumentException(
                sprintf('Invalid type "%s". Allowed: %s', $type, implode(', ', self::VALID_TYPES))
            );
        }

        $this->type = $type;

        return $this;
    }

    public function getPlan(): string
    {
        return $this->plan;
    }

    public function setPlan(string $plan): self
    {
        if (!in_array($plan, self::VALID_PLANS, true)) {
            throw new \InvalidArgumentException(
                sprintf('Invalid plan "%s". Allowed: %s', $plan, implode(', ', self::VALID_PLANS))
            );
        }

        $this->plan = $plan;

        return $this;
    }

    public function getStartsAt(): \DateTimeImmutable
    {
        return $this->startsAt;
    }

    public function setStartsAt(\DateTimeImmutable $startsAt): self
    {
        $this->startsAt = $startsAt;

        return $this;
    }

    public function getExpiresAt(): ?\DateTimeImmutable
    {
        return $this->expiresAt;
    }

    public function setExpiresAt(?\DateTimeImmutable $expiresAt): self
    {
        $this->expiresAt = $expiresAt;

        return $this;
    }

    public function isActive(): bool
    {
        return $this->isActive;
    }

    public function setIsActive(bool $isActive): self
    {
        $this->isActive = $isActive;

        return $this;
    }

    public function getMaxUsers(): int
    {
        return $this->maxUsers;
    }

    public function setMaxUsers(int $maxUsers): self
    {
        $this->maxUsers = $maxUsers;

        return $this;
    }

    public function getMaxNews(): int
    {
        return $this->maxNews;
    }

    public function setMaxNews(int $maxNews): self
    {
        $this->maxNews = $maxNews;

        return $this;
    }

    public function getMaxStorageMb(): int
    {
        return $this->maxStorageMb;
    }

    public function setMaxStorageMb(int $maxStorageMb): self
    {
        $this->maxStorageMb = $maxStorageMb;

        return $this;
    }

    public function getPrice(): int
    {
        return $this->price;
    }

    public function setPrice(int $price): self
    {
        $this->price = $price;

        return $this;
    }

    public function getCurrency(): string
    {
        return $this->currency;
    }

    public function setCurrency(string $currency): self
    {
        $this->currency = $currency;

        return $this;
    }

    public function getFormattedPrice(): string
    {
        $symbol = match ($this->currency) {
            'TRY' => '₺',
            'USD' => '$',
            'EUR' => '€',
            default => $this->currency,
        };

        return number_format($this->price, 0, ',', '.') . ' ' . $symbol;
    }

    public function getCreatedAt(): \DateTimeImmutable
    {
        return $this->createdAt;
    }

    #[ORM\PrePersist]
    public function onPrePersist(): void
    {
        $this->createdAt = new \DateTimeImmutable();
    }
}
