<?php

namespace GlobalPayments\Api\Builders;

use GlobalPayments\Api\Entities\Enums\TransactionModifier;
use GlobalPayments\Api\Entities\Enums\TransactionType;
use GlobalPayments\Api\Entities\PayByLinkData;
use GlobalPayments\Api\Entities\TransactionApi\TransactionApiData;
use GlobalPayments\Api\PaymentMethods\Interfaces\IPaymentMethod;

abstract class TransactionBuilder extends BaseBuilder
{
    /**
     * @var string
     */
    public ?string $clientTransactionId = null;

    /**
     * Request transaction type
     *
     * @internal
     * @var TransactionType
     */
    public mixed $transactionType = null;

    /**
     * Request payment method
     *
     * @internal
     * @var IPaymentMethod
     */
    public mixed $paymentMethod = null;

    /**
     * used w/TransIT gateway
     *
     * @var bool
     */
    public ?bool $multiCapture = null;

    /**
     * used w/TransIT gateway
     *
     * @var int|string|null
     */
    public int|string|null $multiCaptureSequence = null;

    /**
     * used w/TransIT gateway
     *
     * @var int
     */
    public ?int $multiCapturePaymentCount = null;

    /**
     * Request transaction modifier
     *
     * @internal
     * @var TransactionModifier
     */
    public mixed $transactionModifier = TransactionModifier::NONE;

    /**
     * Request should allow duplicates
     *
     * @internal
     * @var bool
     */
    public ?bool $allowDuplicates = null;

    /**
     * Request supplementary data
     *
     * @var array
     */
    public ?array $supplementaryData = null;

    /**
     * Entity specific to PayByLink service
     *
     * @var PayByLinkData
     */
    public mixed $payByLinkData = null;

    /**
     *A unique identifier generated by Global Payments to identify the payment link.
     *
     * string
     */
    public ?string $paymentLinkId = null;

    /**
     * @var string $transactionData
     */
    public ?string $transactionData = null;

    /**
     * @var string $entryClass
     */
    public ?string $entryClass = null;

    /**
     * @var string $paymentPurposeCode
     */
    public ?string $paymentPurposeCode = null;

    /**
     * Instantiates a new builder
     *
     * @param TransactionType $type Request transaction type
     * @param IPaymentMethod $paymentMethod Request payment method
     *
     * @return
     */
    public function __construct($type, $paymentMethod = null)
    {
        parent::__construct();
        $this->transactionType = $type;
        $this->paymentMethod = $paymentMethod;
    }

    /**
     * Set the request transaction type
     *
     * @internal
     * @param TransactionType $transactionType Request transaction type
     *
     * @return TransactionBuilder
     */
    public function withTransactionType($transactionType)
    {
        $this->transactionType = $transactionType;
        return $this;
    }

    /**
     * Set the request transaction modifier
     *
     * @internal
     * @param TransactionModifier $modifier Request transaction modifier
     *
     * @return TransactionBuilder
     */
    public function withModifier($modifier)
    {
        $this->transactionModifier = $modifier;
        return $this;
    }

    /**
     * Set the request to allow duplicates
     *
     * @param bool $allowDuplicates Request to allow duplicates
     *
     * @return TransactionBuilder
     */
    public function withAllowDuplicates($allowDuplicates)
    {
        $this->allowDuplicates = $allowDuplicates;
        return $this;
    }

    /**
     * Depending on the parameters received,
     * Add supplementary data or
     * Add multiple values to the supplementaryData array
     *
     * @param string|array<string, string>  $key
     * @param string $value
     *
     * @return $this
     */
    public function withSupplementaryData($key, $value = null)
    {
        if ($value === null && is_array($key)) {
            foreach ($key as $k => $v) {
                $this->withSupplementaryData($k, $v);
            }
        }

        if ($key && isset($value)) {
            $this->supplementaryData[$key] = $value;
        }

        return $this;
    }

    public function withPayByLinkData(PayByLinkData $payByLinkData)
    {
        $this->payByLinkData = $payByLinkData;

        return $this;
    }

    public function withPaymentLinkId($paymentLinkId)
    {
        $this->paymentLinkId = $paymentLinkId;
        return $this;
    }

    /**
     * Set the request transactionData
     *
     * @param TransactionApiData $data Request transactionData
     *
     * @return $this
     */
    public function withTransactionData(TransactionApiData $data)
    {
        $this->transactionData = $data;
        return $this;
    }

    /**
     * Three digit code used by a payment originator to identify a Canada check payment.
     *
     * @param string $paymentPurposeCode
     *
     * @return $this
     */
    public function withPaymentPurposeCode(string $paymentPurposeCode)
    {
        $this->paymentPurposeCode = $paymentPurposeCode;

        return $this;
    }

    /**
     * Standard entry class to designate how the transaction was authorized by the originator for check refunds.
     *
     * @param string $entryClass
     *
     * @return $this
     */
    public function withEntryClass(string $entryClass)
    {
        $this->entryClass = $entryClass;

        return $this;
    }
}
