<?php
/**
 * 2026 Paysera
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@prestashop.com so we can send you a copy immediately.
 *
 * @author Paysera <plugins@paysera.com>
 * @copyright 2026 Paysera
 * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
 * International Registered Trademark & Property of Paysera
 */

declare(strict_types=1);

namespace Paysera\PrestashopPayments\Dto;

use Evp\Component\Money\Money;

if (!defined('_PS_VERSION_')) {
    exit;
}

class PaymentDetails
{
    /**
     * @param PaymentStatusTransition[] $statusTransitions
     */
    public function __construct(
        private int $id,
        private string $reference,
        private Money $amount,
        private string $status,
        private string $dateAdd,
        private string $dateUpd,
        private Customer $customer,
        private string $paymentMethod,
        private int $cartId,
        private string $orderLink,
        private PayseraPaymentInfo $payseraPaymentInfo,
        private Payer $payer,
        private array $statusTransitions = []
    ) {
    }

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

    public function getReference(): string
    {
        return $this->reference;
    }

    public function getAmount(): Money
    {
        return $this->amount;
    }

    public function getStatus(): string
    {
        return $this->status;
    }

    public function getDateAdd(): string
    {
        return $this->dateAdd;
    }

    public function getDateUpd(): string
    {
        return $this->dateUpd;
    }

    public function getCustomer(): Customer
    {
        return $this->customer;
    }

    public function getPaymentMethod(): string
    {
        return $this->paymentMethod;
    }

    public function getCartId(): int
    {
        return $this->cartId;
    }

    public function getOrderLink(): string
    {
        return $this->orderLink;
    }

    public function getPayseraPaymentInfo(): PayseraPaymentInfo
    {
        return $this->payseraPaymentInfo;
    }

    public function getPayer(): Payer
    {
        return $this->payer;
    }

    public function getPayseraPaymentId(): ?string
    {
        return $this->payseraPaymentInfo->getPayseraPaymentId();
    }

    public function getPayseraOrderId(): ?string
    {
        return $this->payseraPaymentInfo->getPayseraOrderId();
    }

    public function getPaymentLink(): ?string
    {
        return $this->payseraPaymentInfo->getPaymentLink();
    }

    public function getOriginalAmount(): ?Money
    {
        return $this->payseraPaymentInfo->getOriginalAmount();
    }

    public function getPaidAmount(): ?Money
    {
        return $this->payseraPaymentInfo->getPaidAmount();
    }

    public function getExchangeRate(): ?string
    {
        return $this->payseraPaymentInfo->getExchangeRate();
    }

    public function getPayerName(): ?string
    {
        return $this->payer->getName();
    }

    public function getPayerEmail(): ?string
    {
        return $this->payer->getEmail();
    }

    /**
     * @return PaymentStatusTransition[]
     */
    public function getStatusTransitions(): array
    {
        return $this->statusTransitions;
    }

    /**
     * @return array<string, mixed>
     */
    public function toArray(): array
    {
        $originalAmount = $this->payseraPaymentInfo->getOriginalAmount();
        $paidAmount = $this->payseraPaymentInfo->getPaidAmount();

        return [
            'id' => $this->id,
            'reference' => $this->reference,
            'amount' => $this->moneyToArray($this->amount),
            'status' => $this->status,
            'date_add' => $this->dateAdd,
            'date_upd' => $this->dateUpd,
            'customer' => $this->customer->toArray(),
            'payment_method' => $this->paymentMethod,
            'cart_id' => $this->cartId,
            'order_link' => $this->orderLink,
            'paysera_payment_id' => $this->payseraPaymentInfo->getPayseraPaymentId(),
            'paysera_order_id' => $this->payseraPaymentInfo->getPayseraOrderId(),
            'payment_link' => $this->payseraPaymentInfo->getPaymentLink(),
            'original_amount' => $originalAmount !== null ? $this->moneyToArray($originalAmount) : null,
            'paid_amount' => $paidAmount !== null ? $this->moneyToArray($paidAmount) : null,
            'exchange_rate' => $this->payseraPaymentInfo->getExchangeRate(),
            'payer_name' => $this->payer->getName(),
            'payer_email' => $this->payer->getEmail(),
            'status_transitions' => array_map(
                static fn (PaymentStatusTransition $transition): array => $transition->toArray(),
                $this->statusTransitions
            ),
        ];
    }

    /**
     * @return array{value: float, currency: string}
     */
    private function moneyToArray(Money $money): array
    {
        return [
            'value' => (float) $money->getAmount(),
            'currency' => $money->getCurrency(),
        ];
    }
}
