<?php

namespace App\Http\Controllers;


use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\VarDumper\VarDumper;
use App\Library\SslCommerz\SslCommerzNotification;
use App\Http\Controllers\Customer\CustomerFrontController;
use Brian2694\Toastr\Facades\Toastr;
use Illuminate\Support\Facades\Log;
use League\CommonMark\Extension\CommonMark\Node\Inline\Strong;
use Illuminate\Support\Facades\Storage;


class SslCommerzPaymentController extends Controller
{

    public function exampleEasyCheckout()
    {
        return view('exampleEasycheckout');
    }

    public function exampleHostedCheckout()
    {
        return view('exampleHosted');
    }

    public function index(Request $request)
    {
        # Here you have to receive all the order data to initate the payment.
        # Let's say, your oder transaction informations are saving in a table called "orders"
        # In "orders" table, order unique identity is "transaction_id". "status" field contain status of the transaction, "amount" is the order amount to be paid and "currency" is for storing Site Currency which will be checked with paid currency.

        $post_data = array();
        $post_data['total_amount'] = '10'; # You cant not pay less than 10
        $post_data['currency'] = "BDT";
        $post_data['tran_id'] = uniqid(); // tran_id must be unique

        # CUSTOMER INFORMATION
        $post_data['cus_name'] = 'Customer Name';
        $post_data['cus_email'] = 'customer@mail.com';
        $post_data['cus_add1'] = 'Customer Address';
        $post_data['cus_add2'] = "";
        $post_data['cus_city'] = "";
        $post_data['cus_state'] = "";
        $post_data['cus_postcode'] = "";
        $post_data['cus_country'] = "Bangladesh";
        $post_data['cus_phone'] = '8801XXXXXXXXX';
        $post_data['cus_fax'] = "";

        # SHIPMENT INFORMATION
        $post_data['ship_name'] = "Store Test";
        $post_data['ship_add1'] = "Dhaka";
        $post_data['ship_add2'] = "Dhaka";
        $post_data['ship_city'] = "Dhaka";
        $post_data['ship_state'] = "Dhaka";
        $post_data['ship_postcode'] = "1000";
        $post_data['ship_phone'] = "";
        $post_data['ship_country'] = "Bangladesh";

        $post_data['shipping_method'] = "NO";
        $post_data['product_name'] = "Computer";
        $post_data['product_category'] = "Goods";
        $post_data['product_profile'] = "physical-goods";

        # OPTIONAL PARAMETERS
        $post_data['value_a'] = "ref001";
        $post_data['value_b'] = "ref002";
        $post_data['value_c'] = "ref003";
        $post_data['value_d'] = "ref004";

        #Before  going to initiate the payment order status need to insert or update as Pending.
        $update_product = DB::table('orders')
            ->where('transaction_id', $post_data['tran_id'])
            ->updateOrInsert([
                'name' => $post_data['cus_name'],
                'email' => $post_data['cus_email'],
                'phone' => $post_data['cus_phone'],
                'amount' => $post_data['total_amount'],
                'status' => 'Pending',
                'address' => $post_data['cus_add1'],
                'transaction_id' => $post_data['tran_id'],
                'currency' => $post_data['currency']
            ]);

        $sslc = new SslCommerzNotification();
        # initiate(Transaction Data , false: Redirect to SSLCOMMERZ gateway/ true: Show all the Payement gateway here )
        $payment_options = $sslc->makePayment($post_data, 'hosted');

        try{
            $new_post_data = json_encode($payment_options);
            DB::table('orders')
            ->where('transaction_id', $post_data['tran_id'])
            ->update(['post_data' => $new_post_data]);
        }catch(\Exception $e){

        }

        if (!is_array($payment_options)) {
            print_r($payment_options);
            $payment_options = array();
        }
    }

    public function payViaAjax(Request $request)
    {

        // dd($request->cart_json);



        $info = (array)json_decode($request->cart_json);

        // dd($info);




        # Here you have to receive all the order data to initate the payment.
        # Lets your oder trnsaction informations are saving in a table called "orders"
        # In orders table order uniq identity is "transaction_id","status" field contain status of the transaction, "amount" is the order amount to be paid and "currency" is for storing Site Currency which will be checked with paid currency.

        $post_data = array();
        $post_data['total_amount'] = $info['amount']; # You cant not pay less than 10
        $post_data['currency'] = "BDT";
        $post_data['tran_id'] = uniqid(); // tran_id must be unique

        # CUSTOMER INFORMATION
        $post_data['cus_name'] = $info['cus_name'];
        $post_data['cus_email'] = $info['cus_email'];
        $post_data['cus_add1'] = $info['cus_addr1'];
        $post_data['cus_add2'] = "";
        $post_data['cus_city'] = "";
        $post_data['cus_state'] = "";
        $post_data['cus_postcode'] = "";
        $post_data['cus_country'] = "Bangladesh";
        $post_data['cus_phone'] = $info['cus_phone'];
        $post_data['cus_fax'] = "";

        # SHIPMENT INFORMATION
        $post_data['ship_name'] = "Store Test";
        $post_data['ship_add1'] = "Dhaka";
        $post_data['ship_add2'] = "Dhaka";
        $post_data['ship_city'] = "Dhaka";
        $post_data['ship_state'] = "Dhaka";
        $post_data['ship_postcode'] = "1000";
        $post_data['ship_phone'] = "";
        $post_data['ship_country'] = "Bangladesh";

        $post_data['shipping_method'] = "NO";
        $post_data['product_name'] = "Internet Package";
        $post_data['product_category'] = "Package";
        $post_data['product_profile'] = "Virtual-products";

        # OPTIONAL PARAMETERS
        $post_data['value_a'] = $info['customer_id'];
        $post_data['value_b'] = "ref002";
        $post_data['value_c'] = "ref003";
        $post_data['value_d'] = "ref004";


        #Before  going to initiate the payment order status need to update as Pending.
        $update_product = DB::table('orders')
            ->where('transaction_id', $post_data['tran_id'])
            ->updateOrInsert([
                'name' => $post_data['cus_name'],
                'email' => $post_data['cus_email'],
                'phone' => $post_data['cus_phone'],
                'amount' => $post_data['total_amount'],
                'status' => 'Pending',
                'address' => $post_data['cus_add1'],
                'transaction_id' => $post_data['tran_id'],
                'currency' => $post_data['currency'],
                'customer_id' => $post_data['value_a'],
                'created_at' => now(),
                'updated_at' => now()
            ]);

        $sslc = new SslCommerzNotification();
        # initiate(Transaction Data , false: Redirect to SSLCOMMERZ gateway/ true: Show all the Payement gateway here )
        $payment_options = $sslc->makePayment($post_data, 'checkout', 'json');

        try{
            $new_post_data = json_encode($payment_options);
            DB::table('orders')
            ->where('transaction_id', $post_data['tran_id'])
            ->update(['post_data' => $new_post_data]);
        }catch(\Exception $e){

        }

        if (!is_array($payment_options)) {
            print_r($payment_options);
            $payment_options = array();
        }


    }

    public function success(Request $request)
    {

        Log::error(json_encode($request->all()));
        $tran_id = $request->input('tran_id');
        $amount = $request->input('amount');
        $currency = $request->input('currency');

        $sslc = new SslCommerzNotification();

        $post_data = json_encode($request->all());

        try{

            $update_order_page = DB::table('orders')
                ->where('transaction_id', $tran_id)
                ->update(['post_data' => $post_data,]);

            if(isset($request['val_id']) && $request['val_id'] != null){
                DB::table('orders')
                ->where('transaction_id', $request->input('tran_id'))
                ->update(['val_id' => $request['val_id'] ]);
            }

            #Check order status in order tabel against the transaction id or order id.
            $order_detials = DB::table('orders')
                ->where('transaction_id', $tran_id)
                ->select('transaction_id', 'status', 'currency', 'amount')->first();
        }catch(\Exception $e){

        }


        Log::error($order_detials->status);

        $validation = $sslc->orderValidate($request->all(), $tran_id, $amount, $currency);
        Log::error($validation);
        if ($validation == TRUE) {

            $update_product = DB::table('orders')
                ->where('transaction_id', $tran_id)
                ->update(['status' => 'Processing']);
            DB::beginTransaction();
            try{
                $status = (new PaymentController)->sslpayment($request);
                DB::commit();
            }catch(\Exception $e){
                Log::error("error in ssl payment");
            }

            CustomerFrontController::getinfo($request);

            Toastr::success('Payment Successfull', 'Success');

            return redirect()->route('customerDashboard');


        } else {

            $update_product = DB::table('orders')
                ->where('transaction_id', $tran_id)
                ->update(['status' => 'Failed']);

            return redirect()->route('customerDashboard')->with('error_message', 'Validation Faild');
        }

    }

    public function fail(Request $request)
    {
        // dd("fail");
        $tran_id = $request->input('tran_id');
        $post_data = json_encode($request->all());

        $update_order_page = DB::table('orders')
            ->where('transaction_id', $tran_id)
            ->update(['post_data' => $post_data]);

        if(isset($request['val_id']) && $request['val_id'] != null){
            DB::table('orders')
            ->where('transaction_id', $request->input('tran_id'))
            ->update(['val_id' => $request['val_id'] ]);
        }

        $order_detials = DB::table('orders')
            ->where('transaction_id', $tran_id)
            ->select('transaction_id', 'status', 'currency', 'amount')->first();

        if ($order_detials->status == 'Pending') {
            $update_product = DB::table('orders')
                ->where('transaction_id', $tran_id)
                ->update(['status' => 'Failed']);
            Toastr::error('Payment Falied', 'Falied');
            return redirect()->route('customerDashboard')->with('error_message', 'Transaction is Falied');
            // echo "Transaction is Falied";
        } else if ($order_detials->status == 'Processing' || $order_detials->status == 'Complete') {
            Toastr::error('Transaction is already Successful', 'Falied');
            return redirect()->route('customerDashboard')->with('success_message', 'Transaction is already Successful');
            // echo "Transaction is already Successful";
        } else {
            Toastr::error('Transaction is Invalid', 'Falied');
            return redirect()->route('customerDashboard')->with('error_message', 'Transaction is Invalid');
            // echo "Transaction is Invalid";
        }
    }

    public function cancel(Request $request)
    {
        // dd("cancel");
        $tran_id = $request->input('tran_id');

        $post_data = json_encode($request->all());

        $update_order_page = DB::table('orders')
            ->where('transaction_id', $tran_id)
            ->update(['post_data' => $post_data]);

        if(isset($request['val_id']) && $request['val_id'] != null){
            DB::table('orders')
            ->where('transaction_id', $request->input('tran_id'))
            ->update(['val_id' => $request['val_id'] ]);
        }


        $order_detials = DB::table('orders')
            ->where('transaction_id', $tran_id)
            ->select('transaction_id', 'status', 'currency', 'amount')->first();

        if ($order_detials->status == 'Pending') {
            $update_product = DB::table('orders')
                ->where('transaction_id', $tran_id)
                ->update(['status' => 'Canceled']);
            return redirect()->route('customerDashboard')->with('error_message', 'Transaction is Canceled');
            echo "Transaction is Cancel";
        } else if ($order_detials->status == 'Processing' || $order_detials->status == 'Complete') {
            return redirect()->route('customerDashboard')->with('success_message', 'Transaction is already Successful');
            echo "Transaction is already Successful";
        } else {
            return redirect()->route('customerDashboard')->with('success_message', 'Transaction is Invalid');
            echo "Transaction is Invalid";
        }
    }

    public function ipn(Request $request)
    {
        // Storage::put('file.txt', $request->all());
        // dd($request->input('tran_id'));
        #Received all the payement information from the gateway
        if ($request->input('tran_id')) #Check transation id is posted or not.
        {
            try{
                $new_post_data = json_encode($request->all());
                DB::table('orders')
                ->where('transaction_id', $request->input('tran_id'))
                ->update(['ipn_data' => $new_post_data,'software_integration_comment' => "from ipn"]);

                if(isset($request['val_id']) && $request['val_id'] != null){
                    DB::table('orders')
                    ->where('transaction_id', $request->input('tran_id'))
                    ->update(['val_id' => $request['val_id'] ]);
                }
            }catch(\Exception $e){

            }
            $tran_id = $request->input('tran_id');

            #Check order status in order tabel against the transaction id or order id.
            $order_details = DB::table('orders')
                ->where('transaction_id', $tran_id)
                ->select('transaction_id', 'status', 'currency', 'amount')->first();

            if ($order_details->status == 'Pending') {
                $sslc = new SslCommerzNotification();
                $validation = $sslc->orderValidate($request->all(), $tran_id, $order_details->amount, $order_details->currency);
                if ($validation == TRUE) {
                    /*
                    That means IPN worked. Here you need to update order status
                    in order table as Processing or Complete.
                    Here you can also sent sms or email for successful transaction to customer
                    */
                    $update_product = DB::table('orders')
                        ->where('transaction_id', $tran_id)
                        ->update(['status' => 'Processing']);

                    echo "Transaction is successfully Completed";
                } else {
                    /*
                    That means IPN worked, but Transation validation failed.
                    Here you need to update order status as Failed in order table.
                    */
                    $update_product = DB::table('orders')
                        ->where('transaction_id', $tran_id)
                        ->update(['status' => 'Failed']);

                    echo "validation Fail";
                }
            } else if ($order_details->status == 'Processing' || $order_details->status == 'Complete') {

                #That means Order status already updated. No need to udate database.

                echo "Transaction is already successfully Completed";
            } else {
                #That means something wrong happened. You can redirect customer to your product page.

                echo "Invalid Transaction";
            }
        } else {
            echo "Invalid Data";
        }
    }

    public function sslVarification()
    {
        $orders = DB::table('orders')
            ->where('status', 'Pending')
            ->whereBetween('created_at', [today()->firstOfMonth(), today()->endOfMonth()])
            ->get();


        foreach ($orders as $order) {
           $result =  (new SslCommerzNotification())->orderVarification($order);

           dd($result);
        }


        dd($orders);
    }
}
