<?php

namespace Yajny\Member\BalanceTransactions;

use Yajny\Member\Entities\BalanceTransactions\MappedTransaction;
use Yajny\Member\Entities\BalanceTransactions\RawTransaction;
use Yajny\Member\Entities\BalanceTransactions\TransactionsBalanceTypeUtil;
use Yajny\Member\Entities\BalanceTransactions\TransactionSourceTypes;
use Yajny\Member\Entities\BalanceTransactions\TransactionTypes;
use Yajny\Member\Entities\BalanceTransactions\UserBalanceCalculationObject;
use Yajny\Member\Exceptions\InvalidPayoutStatusException;

class PayoutBalanceTransaction extends BalanceTransactionFactory
{
    private $payoutID;
    private $payoutStatus;
    private $payoutTime;
    public $eligibleSourceType = TransactionSourceTypes::PAYOUT;

    public function __construct($userID, $transactionAmount, $payoutID, $payoutStatus, $payoutTime)
    {
        parent::__construct($userID, $transactionAmount);
        $this->payoutID = $payoutID;
        $this->payoutStatus = $payoutStatus;
        $this->payoutTime = $payoutTime;
    }

    public function initTransaction(): RawTransaction
    {
        return new RawTransaction($this->userID, $this->transactionAmount, $this->payoutStatus, TransactionSourceTypes::PAYOUT, $this->payoutID);
    }

    /**
     * @param UserBalanceCalculationObject $user_balance
     * @param RawTransaction $raw_transaction
     * @return MappedTransaction
     * @throws InvalidPayoutStatusException
     */
    public static function mapRawTransactionToTransaction(UserBalanceCalculationObject $user_balance, RawTransaction $raw_transaction): MappedTransaction
    {
        {
            $balance_type = TransactionsBalanceTypeUtil::CONFIRMED;
            switch ($raw_transaction->status) {
                case 'created':
                    $transaction_type = TransactionTypes::CREATED_PAYOUT;
                    $amount = (float)$raw_transaction->amount;

                    $user_balance->confirmed_balance -= $amount;
                    break;
                case 'processing':
                    $transaction_type = TransactionTypes::PROCESSING_PAYOUT;
                    $amount = (float)$raw_transaction->amount;

                    $user_balance->confirmed_balance -= $amount;
                    break;
                case 'completed':
                    $transaction_type = TransactionTypes::COMPLETED_PAYOUT;
                    $amount = (float)$raw_transaction->amount;

                    $user_balance->confirmed_balance -= $amount;
                    break;
                case 'declined':
                    $transaction_type = TransactionTypes::DECLINED_PAYOUT;
                    $amount = 0;
                    break;
                case 'failed':
                    $transaction_type = TransactionTypes::FAILED_PAYOUT;
                    $amount = 0;
                    break;
                default:
                    throw new InvalidPayoutStatusException();
            }

            return new MappedTransaction(
                $raw_transaction->user_id,
                $transaction_type,
                TransactionSourceTypes::PAYOUT,
                $raw_transaction->source_id,
                $amount * -1,
                $balance_type,
                $user_balance->pending_balance,
                $user_balance->confirmed_balance,
                $raw_transaction->transaction_time
            );
        }
    }
}