<?php

namespace App\Subscription\Entity;

use App\Payment\Entity\Payment;
use App\Subscription\Repository\ClinicSubscriptionRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;

#[ORM\Entity(repositoryClass: ClinicSubscriptionRepository::class)]
#[ORM\Table(name: 'clinic_subscriptions')]
#[ORM\Index(columns: ['entity_type', 'entity_id', 'expires_at'], name: 'idx_subscription_entity_expires')]
class ClinicSubscription
{
    #[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(name: 'entity_type', type: 'string', length: 10)]
    private string $entityType;

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

    #[ORM\ManyToOne(targetEntity: SubscriptionPlan::class)]
    #[ORM\JoinColumn(nullable: false, onDelete: 'RESTRICT')]
    private SubscriptionPlan $plan;

    #[ORM\ManyToOne(targetEntity: SubscriptionPeriod::class)]
    #[ORM\JoinColumn(nullable: false, onDelete: 'RESTRICT')]
    private SubscriptionPeriod $period;

    #[ORM\ManyToOne(targetEntity: Payment::class)]
    #[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
    private ?Payment $payment = null;

    #[ORM\Column(name: 'is_trial', type: 'boolean')]
    private bool $isTrial = false;

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

    #[ORM\Column(name: 'expires_at', type: 'integer', nullable: true)]
    private ?int $expiresAt = null;

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

    public function __construct(
        string $entityType,
        int $entityId,
        SubscriptionPlan $plan,
        SubscriptionPeriod $period,
        bool $isTrial = false,
        ?int $expiresAt = null,
        ?Payment $payment = null
    ) {
        $this->uuid       = Uuid::v4()->toRfc4122();
        $this->entityType = $entityType;
        $this->entityId   = $entityId;
        $this->plan       = $plan;
        $this->period     = $period;
        $this->isTrial    = $isTrial;
        $this->startsAt   = time();
        $this->expiresAt  = $expiresAt;
        $this->payment    = $payment;
        $this->createdAt  = time();
    }

    public function getId(): ?int                  { return $this->id; }
    public function getUuid(): string              { return $this->uuid; }
    public function getEntityType(): string        { return $this->entityType; }
    public function getEntityId(): int             { return $this->entityId; }
    public function getPlan(): SubscriptionPlan    { return $this->plan; }
    public function getPeriod(): SubscriptionPeriod { return $this->period; }
    public function getPayment(): ?Payment         { return $this->payment; }
    public function isTrial(): bool                { return $this->isTrial; }
    public function getStartsAt(): int             { return $this->startsAt; }
    public function getExpiresAt(): ?int           { return $this->expiresAt; }
    public function getCreatedAt(): int            { return $this->createdAt; }

    public function isActive(): bool
    {
        return $this->expiresAt === null || $this->expiresAt > time();
    }

    public function getDaysRemaining(): ?int
    {
        if ($this->expiresAt === null) {
            return null;
        }
        $remaining = $this->expiresAt - time();
        return max(0, (int) ceil($remaining / 86400));
    }

    public function toArray(): array
    {
        return [
            'uuid'         => $this->uuid,
            'plan'         => $this->plan->toArray(),
            'period'       => $this->period->toArray(),
            'is_trial'     => $this->isTrial,
            'starts_at'    => $this->startsAt,
            'expires_at'   => $this->expiresAt,
            'days_remaining' => $this->getDaysRemaining(),
            'is_active'    => $this->isActive(),
            'created_at'   => $this->createdAt,
        ];
    }
}
