<?php

namespace App\Insurance\Entity;

use App\Insurance\Repository\TenantInsuranceRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;

#[ORM\Entity(repositoryClass: TenantInsuranceRepository::class)]
#[ORM\Table(name: 'tenant_insurances')]
#[ORM\UniqueConstraint(name: 'uniq_tenant_insurance_version', columns: ['entity_type', 'entity_id', 'insurance_id', 'version'])]
#[ORM\Index(columns: ['entity_type', 'entity_id', 'is_active'], name: 'idx_tenant_insurance_active')]
class TenantInsurance
{
    public const TYPE_DOCTOR = 'doctor';
    public const TYPE_CLINIC = 'clinic';

    #[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\Column(name: 'insurance_id', type: 'integer')]
    private int $insuranceId;

    #[ORM\Column(type: 'integer')]
    private int $version = 1;

    #[ORM\Column(name: 'is_active', type: 'boolean')]
    private bool $isActive = true;

    #[ORM\Column(name: 'coverage_percent', type: 'decimal', precision: 5, scale: 2)]
    private string $coveragePercent = '0.00';

    /** درصدِ سهم اجباری بیمار از مبلغ تحت پوشش؛ فقط در قرارداد تکمیلی اثر دارد. */
    #[ORM\Column(name: 'franchise_percent', type: 'decimal', precision: 5, scale: 2)]
    private string $franchisePercent = '0.00';

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

    /** Contract-level insurance kind ('basic'|'supplementary'); overrides the catalog type when set. */
    #[ORM\Column(name: 'kind', type: 'string', length: 20, nullable: true)]
    private ?string $kind = null;

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

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

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

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

    public function __construct(string $entityType, int $entityId, int $insuranceId, int $version = 1)
    {
        $this->uuid          = Uuid::v4()->toRfc4122();
        $this->entityType    = $entityType;
        $this->entityId      = $entityId;
        $this->insuranceId   = $insuranceId;
        $this->version       = $version;
        $this->effectiveFrom = time();
        $this->createdAt     = time();
        $this->updatedAt     = 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 getInsuranceId(): int         { return $this->insuranceId; }
    public function getVersion(): int             { return $this->version; }
    public function isActive(): bool              { return $this->isActive; }
    public function getCoveragePercent(): float   { return (float) $this->coveragePercent; }
    public function getFranchisePercent(): float  { return (float) $this->franchisePercent; }
    public function getAnnualCeilingRials(): ?int { return $this->annualCeilingRials; }
    public function getKind(): ?string            { return $this->kind; }
    public function getEffectiveFrom(): int       { return $this->effectiveFrom; }
    public function getEffectiveTo(): ?int        { return $this->effectiveTo; }

    public function setActive(bool $v): self              { $this->isActive = $v; $this->updatedAt = time(); return $this; }
    public function setCoveragePercent(float $v): self    { $this->coveragePercent = (string) $v; $this->updatedAt = time(); return $this; }
    public function setFranchisePercent(float $v): self   { $this->franchisePercent = (string) $v; $this->updatedAt = time(); return $this; }
    public function setAnnualCeilingRials(?int $v): self  { $this->annualCeilingRials = $v; $this->updatedAt = time(); return $this; }
    public function setKind(?string $v): self             { $this->kind = $v; $this->updatedAt = time(); return $this; }
    public function setEffectiveFrom(int $v): self        { $this->effectiveFrom = $v; $this->updatedAt = time(); return $this; }
    public function setEffectiveTo(?int $v): self         { $this->effectiveTo = $v; $this->updatedAt = time(); return $this; }

    public function toArray(): array
    {
        return [
            'uuid'                 => $this->uuid,
            'entity_type'          => $this->entityType,
            'entity_id'            => $this->entityId,
            'insurance_id'         => $this->insuranceId,
            'version'              => $this->version,
            'is_active'            => $this->isActive,
            'coverage_percent'     => (float) $this->coveragePercent,
            'franchise_percent'    => (float) $this->franchisePercent,
            'annual_ceiling_rials' => $this->annualCeilingRials,
            'kind'                 => $this->kind,
            'effective_from'       => $this->effectiveFrom,
            'effective_to'         => $this->effectiveTo,
        ];
    }
}
