<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

use App\Models\Tip;
use App\Models\Address;
use App\Models\Meme;
use MoneroIntegrations\MoneroPhp\walletRPC;

class ProcessPayments implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $timeout = 3600;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $this->get_transactions();
        $this->payout();
    }

    public function get_transactions()
    {
        try {
            $walletRPC = new walletRPC(config('app.xmr_daemon_ip'), config('app.xmr_network_port')); // Change to match your wallet (monero-wallet-rpc) IP address and port; 18083 is the customary port for mainnet, 28083 for testnet, 38083 for stagenet
            $open_wallet = $walletRPC->open_wallet(config('app.xmr_wallet_name'), '');
            $account_indexes = Meme::pluck('account_index')->toArray();
            foreach ($account_indexes as $account_index) {
                $get_transfers = $walletRPC->get_transfers('in', $account_index);
                if (isset($get_transfers['in'])) {
                    foreach ($get_transfers['in'] as $transfer) {
                        $meme = Meme::where('address', $transfer['address'])->first();
                        $tip_exists = Tip::where('txid', $transfer['txid'])->first();
                        if ($meme && !$tip_exists) {
                            $tip = new Tip();
                            $tip->meme_id = $meme->id;
                            $tip->amount = $transfer['amount'];
                            $tip->txid = $transfer['txid'];
                            $tip->is_deposit = 1;
                            $tip->save();
                            $meme = Meme::where('address', $transfer['address'])->firstOrFail();
                            $meme->payment_pending = 1;
                            $meme->save();
                        }
                    }
                }
            }
            $walletRPC->close_wallet();
        } catch (\Exception $e) {
            echo 'Caught exception: ',  $e->getMessage(), "\n";
        }
    }

    public function payout()
    {
        try {
            $walletRPC = new walletRPC(config('app.xmr_daemon_ip'), config('app.xmr_network_port')); // Change to match your wallet (monero-wallet-rpc) IP address and port; 18083 is the customary port for mainnet, 28083 for testnet, 38083 for stagenet
            $open_wallet = $walletRPC->open_wallet(config('app.xmr_wallet_name'), '');
            $memes = Meme::where('payment_pending', 1)->get();
            foreach ($memes as $meme) {
                $balance = $walletRPC->get_balance($meme->account_index);
                if ($balance['balance'] === $balance['unlocked_balance']) {
                    try {
                        $send_funds = $walletRPC->sweep_all($meme->user->address, '', $meme->account_index);
                        if ($send_funds['amount_list']) {
                            $tip = new Tip;
                            $tip->meme_id = $meme->id;
                            $tip->amount = $send_funds['amount_list'][0];
                            $tip->txid = $send_funds['tx_hash_list'][0];
                            $tip->is_deposit = 0;
                            $tip->save();
                            $meme->payment_pending = 0;
                            $meme->save();
                        }
                    } catch (\Exception $e) {
                        echo 'Caught exception: ',  $e->getMessage(), "\n";
                    }
                }
            }
            $walletRPC->close_wallet();
        } catch (\Exception $e) {
            echo 'Caught exception: ',  $e->getMessage(), "\n";
        }
    }
}
