<?php

declare(strict_types=1);

namespace Bot\Domain\Service;

use Bot\Domain\Entity\Payment;
use Bot\Domain\Entity\User;
use Bot\Domain\Repository\PaymentRepositoryInterface;

final class PaymentService
{
    public function __construct(
        private readonly PaymentRepositoryInterface $payments,
    ) {
    }

    public function createPending(
        User $user,
        string $gateway,
        int $amount,
        ?string $payload = null,
    ): Payment {
        $payment = new Payment(
            0,
            $user->getId(),
            $gateway,
            $amount,
            Payment::STATUS_PENDING,
            null,
            $payload,
        );

        $this->payments->save($payment);

        // بعد از save، payment با ID جدید ذخیره شده است
        // برای Database Repository، باید payment را از repository بازیابی کنیم
        // چون Payment readonly است و نمی‌توانیم ID را تغییر دهیم
        if ($payload !== null) {
            $savedPayment = $this->payments->findByPayload($payload);
            if ($savedPayment !== null && $savedPayment->getId() > 0) {
                return $savedPayment;
            }
        }

        // اگر پیدا نشد، payment اصلی را برمی‌گردانیم
        // (این نباید اتفاق بیفتد، اما برای اطمینان)
        return $payment;
    }

    public function markSuccess(Payment $payment, string $externalId): void
    {
        $payment->markSuccess($externalId);
        $this->payments->save($payment);
    }

    public function markFailed(Payment $payment): void
    {
        $payment->markFailed();
        $this->payments->save($payment);
    }

    public function setExternalId(Payment $payment, string $externalId): void
    {
        $payment->setExternalId($externalId);
        $this->payments->save($payment);
    }

    public function findByPayload(string $payload): ?Payment
    {
        return $this->payments->findByPayload($payload);
    }

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

    public function findByExternalId(string $externalId): ?Payment
    {
        return $this->payments->findByExternalId($externalId);
    }
}



