<?php

namespace App\Console\Commands;

use App\Constants\Status;
use App\Lib\Matrix;
use App\Models\AdminNotification;
use App\Models\Payment;
use App\Models\Transaction;
use App\Models\User;
use App\Models\UserNotification;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class AutoApprovePaymentCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'app:auto-approve-payment-command';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'This payment approves payment automatically when receiver user does not approve themself.';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $donations = Payment::with(['receiverUser', 'payerUser'])->where('status', Status::Pending)->lazy();

        foreach ($donations as $donation) {
            $expiryTime = $donation->expired_at;

            if(!$expiryTime) {
                info('expiry time null found.', $donation->toArray());
            }

            if ($expiryTime->isPast()) {
                $this->approvePayment($donation);
            }
        }
    }

    protected function approvePayment(Payment $payment)
    {
        DB::transaction(function () use ($payment) {
            $general = gs();

            $user = $payment->receiverUser;

            $user->balance += $payment->amount;
            $user->save();

            $trx = getTrx();

            $user_data = User::where('id', $user->id)->first();
            if ($user_data->debt_cleared_at === null) {
                if ($user_data->balance >= $user_data->current_debt_value) {
                    $user_data->debt_cleared_at = now();
                    $user_data->save();
                    $this->createDebtFeeUserNotification($user_data, 'Your Debt has been cleared ');
                }
            }

            $transaction = new Transaction();
            $transaction->user_id = $user->id;
            $transaction->amount = $payment->amount;
            $transaction->post_balance = $user->balance;
            $transaction->charge = 0;
            $transaction->trx_type = '+';
            $transaction->details = 'Payment received from ' . $payment->payerUser->username;
            $transaction->remark = Status::DonationReceived;
            $transaction->payment_mode = $payment->payment_mode;
            $transaction->status = Status::Approved;
            $transaction->trx = $trx;
            $transaction->save();

            $payerUser = $payment->payerUser;

            $transaction = new Transaction();
            $transaction->user_id = $payerUser->id;
            $transaction->amount = $payment->amount;
            $transaction->post_balance = $payerUser->balance;
            $transaction->charge = 0;
            $transaction->trx_type = '-';
            $transaction->details = 'Payment made to ' . $user->username;
            $transaction->remark = Status::DonationMade;
            $transaction->payment_mode = $payment->payment_mode;
            $transaction->status = Status::Approved;
            $transaction->trx = $trx;
            $transaction->save();

            $payment->status = Status::Approved;
            $payment->payment_status_confirmed_at = now();
            $payment->trx = $trx;
            $payment->save();
            $this->handlePaymentSideEffect($payment);

            $this->createUserNotification($payment, $user,'Payment Auto approved by system ' . $general->cur_sym . $payment->amount);
        });
    }

    private function createUserNotification(Payment $payment, User $user, $message)
    {
        $userNotification = new UserNotification();
        $userNotification->user_id = $payment->payer_user_id;
        $userNotification->title = $user->username . ' ' . $message;
        $userNotification->click_url = urlPath('user.notification');
        $userNotification->save();

        $adminNotification = new AdminNotification();
        $adminNotification->user_id = $user->id;
        $adminNotification->admin_id = 1;
        $adminNotification->title = $user->username . ' ' . $message;;
        $adminNotification->click_url = '#';
        $adminNotification->save();
    }

    private function createDebtFeeUserNotification( User $user_data, $message)
    {
        $userNotification = new UserNotification();
        $userNotification->user_id = $user_data->id;
        $userNotification->title = $user_data->username . ' ' . $message;
        $userNotification->click_url = urlPath('user.notification');
        $userNotification->save();
    }

    protected function handlePaymentSideEffect($payment)
    {
        $payer = $payment->payerUser;
        $admin = User::firstWhere('username', 'admin');

        if (
            $payer
            ->paidPayments()
            ->where('receiver_user_id', '!=', $admin->id)
            ->where('status', Status::Approved)
            ->count() != 7
        ) {
            return;
        }

        $payer->network_status = Status::NetworkFullActivated;
        $payer->network_activated_at = now();
        $payer->save();
        $matrix = Matrix::set($payer);
        $matrix->addUserToNetwork();
    }
}
