<?php

namespace App\Http\Controllers\Gateway;

use App\Http\Controllers\Controller;
use App\Models\Deposit;
use App\Models\Recharge;
use App\Models\Transaction;
use App\Models\User;
use App\Models\Withdrawal;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class IpnPpayController extends Controller
{
    public function ipn(Request $request)
    {

        try {

            // Validate request
            $validator = Validator::make($request->all(), [
                'mchOrderNo' => 'required|string',
                'payOrderId' => 'sometimes|required|string',
                'orderState' => 'sometimes|required',
                'state' => 'sometimes|required'
            ]);
    
            // Validation Failed
            if ($validator->fails()) throw new \Exception(implode('...', $validator->errors()->all()));

            // Find Transaction
            $recharge = Deposit::where('trx', $request->mchOrderNo)->first();
            $payout = Withdrawal::where('trx', $request->mchOrderNo)->first();

            if(!$recharge && !$payout) {
                $notify = ['code' => 200, 'msg' => 'success', 'message' => 'Transaction reference not found'];
                return response($notify, 200);
            }

            // Deposit Handle
			if( $request->orderState){
				if($request->orderState == 3 & !empty($recharge)) {
					$updateData = self::updateDeposit($recharge, $recharge->amount, $request->all());
				}
			}

            // Payout Handle
			if( $request->state){
				if(!empty($payout)) {
					$updateData = self::updatePayout($request->state, $payout, $request->amount, $request->all());
				}
			}

            // Exception
            if($updateData instanceof \Exception) throw new \Exception($updateData->getMessage());

            $notify = ['code' => 200, 'msg' => 'success', 'message' => 'Transaction was successful'];
            return response($notify, 200);
        } catch (\Exception $th) {
            //throw $th;
            $notify = ['success' => true, 'status' => 'error', 'success' => 'return', 'message'=>['error'=> $th->getMessage()]];
            return response($notify, 400);
        }

    }

    /**
     * Deposit update transaction
     */
    public static function updateDeposit( Deposit $deposit, string $amount, array $data ) {
        try {
            
            // Verify is transaction exisit
            if (!$deposit) throw new \Exception('Transaction not found');

            // Verify if transaction status not complete
            if (in_array($deposit->status, [1, 3])) throw new \Exception('Transaction was already complete');
            
            // Update transaction details
            $deposit->detail = $data;
            $deposit->status = 1;
            $deposit->save();

			$uBalance = 'balance'; 
			if(config('settings')->cur_text != 'NGN'){
				$uBalance = 'usdt_balance'; 
			}

            $user = User::find($deposit->user_id);

            // Update user balance
            $user->$uBalance = $user->$uBalance + $deposit->amount;
            $user->save();

            $transaction = Transaction::where('trx', $reference)->first();
            $transaction->status = 1;
            $transaction->save();

            return $deposit;
        } catch (\Exception $th) {
            return $th;
        }
    }

    /**
     * Payout update transaction
     */
    public static function updatePayout( string $status, Withdrawal $payout, string $amount, array $data) 
	{
        try {
            // Verify is payout exisit
            if (!$payout) throw new \Exception('Transaction not found');

            $user = User::find($payout->user_id);

            // Verify if payout status not complete
            if (in_array($payout->status, [1, 3])) throw new \Exception('Transaction was already complete');
            
            // Verify successful status
            if(in_array($status, [2])) {
                // Update payout
                $payout->status = 1;
                $payout->save();
                
                $transaction = Transaction::where('trx', $reference)->first();
                $transaction->status = 1;
                $transaction->save();
            }

            // Verify failed status | Refund amount to user
            if(in_array($status, [3, 4])) {
                // Update payout
                $payout->status = 3;
                $payout->save();

                // Refund amount to User Wallet
                $user->income = $user->income + $payout->amount;
                $user->save();

                $transaction = Transaction::where('trx', $reference)->first();
                $transaction->status = 3;
                $transaction->save();
            }

            return $payout;
        } catch (\Exception $th) {
            return $th;
        }
    }
}
