<?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: 'plan_configurations')]
#[ORM\HasLifecycleCallbacks]
class PlanConfiguration
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: Types::INTEGER)]
    private ?int $id = null;

    /** Plan slug: 'starter', 'professional', 'enterprise' */
    #[ORM\Column(type: Types::STRING, length: 30, unique: true)]
    private string $plan;

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

    /** Plan hierarchy weight (1=starter, 2=professional, 3=enterprise) */
    #[ORM\Column(type: Types::INTEGER)]
    private int $weight = 1;

    // === LIMITS ===

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

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

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

    // === PRICING (TRY) ===

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

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

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

    // === MODULES & FEATURES ===

    /** @var string[] Array of module slugs e.g. ['menu', 'comment', 'seo'] */
    #[ORM\Column(type: Types::JSON)]
    private array $modules = [];

    /** @var array<string, bool> Feature flags e.g. {'api_access': true} */
    #[ORM\Column(type: Types::JSON)]
    private array $features = [];

    // === TIMESTAMPS ===

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

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

    // ========================================================================
    //  Lifecycle Callbacks
    // ========================================================================

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

    #[ORM\PreUpdate]
    public function onPreUpdate(): void
    {
        $this->updatedAt = new \DateTimeImmutable();
    }

    // ========================================================================
    //  Getters & Setters
    // ========================================================================

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

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

    public function setPlan(string $plan): self
    {
        $this->plan = $plan;

        return $this;
    }

    public function getDisplayName(): string
    {
        return $this->displayName;
    }

    public function setDisplayName(string $displayName): self
    {
        $this->displayName = $displayName;

        return $this;
    }

    public function getWeight(): int
    {
        return $this->weight;
    }

    public function setWeight(int $weight): self
    {
        $this->weight = $weight;

        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 getPriceMonthly(): int
    {
        return $this->priceMonthly;
    }

    public function setPriceMonthly(int $priceMonthly): self
    {
        $this->priceMonthly = $priceMonthly;

        return $this;
    }

    public function getPriceYearly(): int
    {
        return $this->priceYearly;
    }

    public function setPriceYearly(int $priceYearly): self
    {
        $this->priceYearly = $priceYearly;

        return $this;
    }

    public function getPriceLifetime(): int
    {
        return $this->priceLifetime;
    }

    public function setPriceLifetime(int $priceLifetime): self
    {
        $this->priceLifetime = $priceLifetime;

        return $this;
    }

    /** @return string[] */
    public function getModules(): array
    {
        return $this->modules;
    }

    /** @param string[] $modules */
    public function setModules(array $modules): self
    {
        $this->modules = $modules;

        return $this;
    }

    /** @return array<string, bool> */
    public function getFeatures(): array
    {
        return $this->features;
    }

    /** @param array<string, bool> $features */
    public function setFeatures(array $features): self
    {
        $this->features = $features;

        return $this;
    }

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

    public function getUpdatedAt(): \DateTimeImmutable
    {
        return $this->updatedAt;
    }

    // ========================================================================
    //  Helper Methods
    // ========================================================================

    public function getLimitsArray(): array
    {
        return [
            'maxUsers' => $this->maxUsers,
            'maxNews' => $this->maxNews,
            'maxStorageMb' => $this->maxStorageMb,
        ];
    }

    public function getPricingArray(): array
    {
        return [
            'monthly' => $this->priceMonthly,
            'yearly' => $this->priceYearly,
            'lifetime' => $this->priceLifetime,
        ];
    }

    public function hasModule(string $moduleSlug): bool
    {
        return in_array($moduleSlug, $this->modules, true);
    }

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