<?php

namespace Yajny\Member\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Yajny\Member\Entities\BalanceTransactions\TransactionsBalanceTypeUtil;
use Yajny\Member\Entities\BalanceTransactions\TransactionTypes;

class BalanceTransaction extends Model
{
    protected $table = 'balance_transactions';
    protected $primaryKey = 'id';
    protected $guarded = [];

    public function saveTransaction()
    {
        DB::transaction(function () {
            $user = Member::findOrFail($this->user_id);
            $allowNegativeBalance = ($user->is_merchant) ? true : false;
            if (TransactionTypes::isRevertable($this->transaction_type)) {
                /** Get Transaction to be Reverted **/
                $lastNotRevertedTransaction = self::where('source_id', $this->source_id)
                    ->where('source_type', $this->source_type)
                    ->where('user_id', $this->user_id)
                    ->where('is_reverted', 0)
                    ->first();

                if ($lastNotRevertedTransaction) {
                    /** Update User Balance to Remove Revert Amount **/
                    $user->incrementUserBalance($lastNotRevertedTransaction->balance_type, -1 * $lastNotRevertedTransaction->amount, $allowNegativeBalance);

                    /** Create Revert Transaction and Save It **/
                    $revertTransaction = $this->createRevertTransaction($lastNotRevertedTransaction, $user->pending_balance, $user->confirmed_balance);

                    /** Mark Old Transaction as Reverted and Link the Revert Transaction to It **/
                    $lastNotRevertedTransaction->is_reverted = 1;
                    $lastNotRevertedTransaction->revert_id = $revertTransaction->id;
                    $lastNotRevertedTransaction->save();
                }
            }

            /** Update User Balance to Add New Transaction Amount **/
            $user->incrementUserBalance($this->balance_type, $this->amount, $allowNegativeBalance);
            $this->save();
        });
    }

    private function createRevertTransaction(BalanceTransaction $transactionToBeReverted, $pendingBalance, $confirmedBalance): BalanceTransaction
    {
        if ($transactionToBeReverted->balance_type == TransactionsBalanceTypeUtil::PENDING) {
            $pendingBalance -= $transactionToBeReverted->amount;
            $this->pending_balance_after -= $transactionToBeReverted->amount;
        } else if ($transactionToBeReverted->balance_type == TransactionsBalanceTypeUtil::CONFIRMED) {
            $confirmedBalance -= $transactionToBeReverted->amount;
            $this->confirmed_balance_after -= $transactionToBeReverted->amount;
        }

        $revertTransaction = $transactionToBeReverted->replicate();
        $revertTransaction->transaction_type = TransactionTypes::REVERT;
        $revertTransaction->amount *= -1;
        $revertTransaction->is_reverted = 1;
        $revertTransaction->pending_balance_after = $pendingBalance;
        $revertTransaction->confirmed_balance_after = $confirmedBalance;
        $revertTransaction->save();

        return $revertTransaction;
    }
}
