<?php

namespace App\Patient\Entity;

use App\Auth\Entity\User;
use App\Patient\Repository\SessionPaymentRepository;
use App\Shared\Tenant\TenantOwnedTrait;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;

/**
 * یک پرداختِ جزئی روی یک مراجعه (تسویه‌ی چندتکه). مجموع پرداخت‌ها به‌علاوه‌ی
 * تخفیف، بدهیِ مراجعه را صفر می‌کند.
 */
#[ORM\Entity(repositoryClass: SessionPaymentRepository::class)]
#[ORM\Table(name: 'session_payments')]
#[ORM\Index(columns: ['entity_type', 'entity_id'], name: 'idx_session_payments_entity')]
class SessionPayment
{
    use TenantOwnedTrait;

    public const METHODS = ['wallet', 'pos', 'cash', 'card'];

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private ?int $id = null;

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

    #[ORM\ManyToOne(targetEntity: PatientSession::class, inversedBy: 'payments')]
    #[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
    private PatientSession $session;

    #[ORM\Column(type: 'string', length: 15)]
    private string $method;

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

    /** uuid یک کارت‌خوان (Pos) یا حساب بانکی (BankAccount) ثبت‌شده — برای pos/card. */
    #[ORM\Column(name: 'payment_method_uuid', type: 'string', length: 36, nullable: true)]
    private ?string $paymentMethodUuid = null;

    /** شناسه تراکنش / شماره پیگیری پرداخت (اختیاری). */
    #[ORM\Column(name: 'reference', type: 'string', length: 255, nullable: true)]
    private ?string $reference = null;

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

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

    #[ORM\Column(name: 'created_by_name', type: 'string', length: 255, nullable: true)]
    private ?string $createdByName = null;

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

    public function __construct(PatientSession $session, string $method, int $amountRials, ?int $paidAt = null)
    {
        $this->uuid        = Uuid::v4()->toRfc4122();
        $this->session     = $session;
        $this->assignTenantPair($session->getEntityType(), $session->getEntityId());
        $this->method      = $method;
        $this->amountRials = $amountRials;
        $this->paidAt      = $paidAt ?? time();
        $this->createdAt   = time();
    }

    public function getId(): ?int                { return $this->id; }
    public function getUuid(): string            { return $this->uuid; }
    public function getSession(): PatientSession { return $this->session; }
    public function getMethod(): string          { return $this->method; }
    public function getAmountRials(): int        { return $this->amountRials; }
    public function getPaymentMethodUuid(): ?string { return $this->paymentMethodUuid; }
    public function getReference(): ?string      { return $this->reference; }
    public function getPaidAt(): int             { return $this->paidAt; }
    public function getCreatedBy(): ?User        { return $this->createdBy; }
    public function getCreatedByName(): ?string  { return $this->createdByName; }
    public function getCreatedAt(): int          { return $this->createdAt; }

    public function setCreatedBy(?User $u): self       { $this->createdBy = $u; return $this; }
    public function setCreatedByName(?string $n): self { $this->createdByName = $n; return $this; }
    public function setMethod(string $m): self         { $this->method = $m; return $this; }
    public function setAmountRials(int $v): self       { $this->amountRials = $v; return $this; }
    public function setPaymentMethodUuid(?string $v): self { $this->paymentMethodUuid = $v; return $this; }
    public function setReference(?string $v): self     { $this->reference = $v; return $this; }
    public function setPaidAt(int $v): self            { $this->paidAt = $v; return $this; }

    public function toArray(): array
    {
        return [
            'uuid'                => $this->uuid,
            'method'              => $this->method,
            'amount_rials'        => $this->amountRials,
            'payment_method_uuid' => $this->paymentMethodUuid,
            'reference'           => $this->reference,
            'paid_at'             => $this->paidAt,
            'created_by_name'     => $this->createdByName,
            'created_at'          => $this->createdAt,
        ];
    }
}
