<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Transaction;
use App\PaymentProviders\PSP\Payment;
use Illuminate\Support\Facades\DB;
use Validator;

class PaymentController extends Controller
{
    public function callbackPayment(Request $request)
    {
        $rules = [
            'id' => 'required|exists:transactions,id',
            'token' => 'required',
            'status' => 'required|numeric|in:0,1',
        ];
        $validator = Validator::make($request->all(), $rules);
        if ($validator->fails()) {
            abort(404);
        }

        try {
            DB::beginTransaction();
            $transaction = Transaction::lockForUpdate()->find($request->id);
            if ($transaction)
			{
                if ($transaction->status && $transaction->verified)
				{
                    return $this->showReceipt($transaction);
                } else if (!$transaction->status && !$transaction->verified && isset($transaction->payment_info['token']) && $transaction->payment_info['token'] == $request->token) {
					$paymentProvider = new Payment();
					$verify = $paymentProvider->verify($request->token, $transaction->amount);
					if ($verify && isset($verify->Status) && isset($verify->Amount) && isset($verify->InvoiceID))
					{
                        if ($verify->Status == 100 && $verify->Amount == $transaction->amount)
						{
                            $transaction->update([
                                'payment_info' => [
                                    'token' 		=> $request->token,
                                    'trans_id' 		=> $verify->InvoiceID,
                                    'card_number' 	=> $verify->MaskCardNumber,
                                    'status' 		=> $verify->Status,
                                ],

                                'status' 		=> 1,
                                'verified' 		=> 1,
                                'paid_at' 		=> date('Y-m-d H:i:s'),
                                'verified_at' 	=> date('Y-m-d H:i:s'),
                            ]);
                            switch ($transaction->type)
							{
                                case Transaction::$type['form']:
                                    $transaction->form()->update(['pay_count' => $transaction->form()->pay_count + 1]);
                                    break;
                                case Transaction::$type['factor']:
                                    $transaction->factor()->update([
                                        'paid' => 1,
                                        'transaction_id' => $transaction->id,
                                    ]);
                                    break;
                            }
                            \DB::commit();

                            return $this->showReceipt($transaction);
                        }
                    }
                }
            }
            DB::rollBack();

            return $this->showReceipt($transaction);
        } catch (\Exception $e) {
            if (env('APP_ENV') === 'local') {
                throw $e;
            } else {
                abort(500);
            }
        }
    }

    public function pay(Request $request, $id)
    {
        $request->request->add(['id' => $id]);
        $rules = [
            'id' => 'required|exists:transactions,id,status,0,verified,0',
        ];
        $validator = Validator::make($request->all(), $rules);
        if ($validator->fails()) {
            abort(404);
        }

        $transaction = Transaction::find($id);

        return $this->payWithPayment($transaction);
    }

    private function payWithPayment(Transaction $transaction)
    {
        $paymentProvider = new Payment();
        $paymentInfo = $paymentProvider->send($transaction->amount, $transaction->id);
        if (isset($paymentProvider->paymentUrl) && $paymentProvider->paymentUrl) {
            $transaction->update([
                'payment_info' => [
                    'token' => $paymentInfo['token'],
                ],
            ]);

            return redirect($paymentProvider->paymentUrl);
        }

        return redirect()->back()
            ->with('alert', 'danger')
            ->with('message', isset($paymentProvider->errorMessage) ? $paymentProvider->errorMessage : 'Error');
    }

    private function showReceipt(Transaction $transaction)
    {
        return view('home.receipt')
            ->with('transaction', $transaction);
    }
}
