<?php

namespace App\Http\Controllers;

use App\Models\Currency;
use App\Models\Invoice;
use Illuminate\Http\Request;
use App\Models\PaymentGateway;


use PayPalCheckoutSdk\Core\PayPalHttpClient;
use PayPalCheckoutSdk\Core\SandboxEnvironment;
use PayPalCheckoutSdk\Orders\OrdersGetRequest;
use PayPalCheckoutSdk\Core\ProductionEnvironment;
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;
use PayPalCheckoutSdk\Orders\OrdersAuthorizeRequest;
use Symfony\Component\HttpKernel\Exception\HttpException;


class PaymentController extends Controller
{

    protected $client;
    public function __construct()
    {
        if(file_exists(STORAGE_PATH('INSTALLED'))){
            // Creating an environment
            $paypal_gateway = PaymentGateway::where(['id'=> 2])->first(); // For Paypal
            if($paypal_gateway->mode == 'sandbox'){
                $environment = new SandboxEnvironment($paypal_gateway->sandbox_client_id, $paypal_gateway->sandbox_secret_key);
                $this->client = new PayPalHttpClient($environment);
            }else{
                $client_id = $paypal_gateway->live_client_id;
                $secret_key = $paypal_gateway->live_secret_key;
                $environment =  new ProductionEnvironment($client_id, $secret_key);
                $this->client = new PayPalHttpClient($environment);
            }
        }
    }

    public function payment(Request $request)
    {
        $item = $request->all();
        // Construct a request object and set desired parameters
        // Here, OrdersCreateRequest() creates a POST request to /v2/checkout/orders
        $request = new OrdersCreateRequest();
        
        $request->prefer('return=representation');
        if(isset($item['is_test']) && $item['is_test'] == 'yes'){
            $request->body = self::testBuildRequestBody($item);
        }else{
            $request->body = self::buildRequestBody($item);
        }
        try {
            // Call API with your client and get a response for your call
            $response = $this->client->execute($request);
            // If call returns body in response, you can get the deserialized version from the result attribute of the response
            return redirect()->to($response->result->links['1']->href);
        }catch (HttpException $ex) {
            echo $ex->statusCode;
            print_r($ex->getMessage());
        }
    }

    private static function buildRequestBody($item) {
        $invoice = Invoice::find($item['invoice_id']);   
        $currency = Currency::find($invoice->currency_id); 
        return array(   
            'intent' => 'CAPTURE', // CAPTURE, AUTHORIZE
            'application_context' =>
                array(
                    "cancel_url" => route('payment.cancel'),
                    "return_url" => route('payment.success'),
                    'brand_name' => config('app.name'),
                    'locale' => 'en-US',
                    'landing_page' => 'BILLING',
                    'user_action' => 'PAY_NOW',
                  ),
            'purchase_units' => [
                0 => [
                    'total_amount' => $invoice->total_amount,
                    'reference_id' => $item['invoice_id'],
                    'description' => $invoice->invoice_title ?? NULL,
                    'custom_id' => $item['customer_id'] ?? NULL,
                    'soft_descriptor' => 'live',
                    'amount' => [
                        'currency_code' => $currency->name,
                        'value' => $invoice->total_amount,
                    ],
                ],
            ],
        );
    }

    private static function testBuildRequestBody($item) {
        return array(   
            'intent' => 'CAPTURE', // CAPTURE, AUTHORIZE
            'application_context' =>
                array(
                    "cancel_url" => route('payment.cancel'),
                    "return_url" => route('payment.success'),
                    'brand_name' => config('app.name'),
                    'locale' => 'en-US',
                    'landing_page' => 'BILLING',
                    'user_action' => 'PAY_NOW',
                  ),
            'purchase_units' => [
                0 => [
                    'reference_id' => $item['invoice_id'],
                    'description' => $item['item_desc'] ?? NULL,
                    'custom_id' => $item['customer_id'] ?? NULL,
                    'soft_descriptor' => 'sandbox',
                    'amount' => [
                        'currency_code' => 'USD',
                        'value' => $item['item_price']*$item['item_qty'],
                    ],
                ],
            ],
        );
    }

    public function checkout(){

    }

    public function cancel_order(Request $request){
        $response = $this->client->execute(new OrdersGetRequest($request->input('token')));
        $mode = $response->result->purchase_units[0]->soft_descriptor;
        $invoice_id = $response->result->purchase_units[0]->reference_id;
        $notification = array(
            'message' => __("Your payment is failed!"),
            'alert-type' => 'error'
        );
        if ($mode == 'live') {
            // return redirect()->to(url('/client/invoice/'.$invoice_id))->with($notification); 
            return redirect('/client/invoice/'.$invoice_id)
            ->with('message', __("Your payment is failed!"))
            ->with('alert-type', 'error');
        } else {
            return redirect()->to(url('office/payment/mode#paypal-id'))->with($notification); 
        }

    }
    public function return_order(Request $request){
        $response = $this->client->execute(new OrdersGetRequest($request->input('token')));
        $token = $request->input('token');
        $mode = $response->result->purchase_units[0]->soft_descriptor;
        $invoice_id = $response->result->purchase_units[0]->reference_id;
        $total_amount = $response->result->purchase_units[0]->amount->value;
        $request = new OrdersCaptureRequest($token);
        $response = $this->client->execute($request);
        if($response->result->status == 'COMPLETED'){
            $invoice_id = $response->result->purchase_units[0]->reference_id;
            $invoice = Invoice::where(['id'=>$invoice_id])->first();
            $invoice->token = $response->result->id;
            $invoice->PayerID = $response->result->payer->payer_id;
            $invoice->invoice_data = json_encode($response->result);
            $invoice->invoice_paid = 'yes';
            $invoice->payment_confirmed = 'yes';
            $invoice->payment_mode_id = 2;
            $invoice->amount_paid = $total_amount;
            $invoice->txn_number = $token;
            $invoice->status = json_encode(['id'=> 6, 'name' => 'Paid']);
            $invoice->save();
            $invoice->touch();
        }
        $notification = array(
            'message' => __("Your payment is success!"),
            'alert-type' => 'success'
        );

        if ($mode == 'live') {
            return redirect(url('/client/invoice/'.$invoice_id))->with($notification); 
        } else {
            return redirect(url('office/payment/mode#paypal-id'))->with($notification); 
        }
    }

}
