<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Carbon;
use App\Models\User;
use App\Models\UserCharge;
use App\Models\UserIp;
use App\Models\UserTransaction;
use App\Models\PayoutModel;
use App\Models\ApiLog;

class PayoutVouch extends Controller
{
    public function doPayout(Request $request)
    {
        $jsonData = $request->json()->all();        
        $Authorization = $request->header('Authorization');

        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'accountNumber' => 'required',
            'bankIfsc' => ['required','regex:/^[A-Z]{4}\d[A-Z0-9]{6}$/'],
            'mobileNumber' => 'required',
            'beneBankName' => 'required',
            'referenceNumber' => 'required|unique:payout_transactions,orderId',
            'transferAmount' => 'required',
            'transferMode' => 'required',
        ]);

        if($validator->fails()) {
            $responseData = [                
                'status' => FALSE,
                'error'=> TRUE,
                'message' => $validator->errors(),
            ];
            return response()->json($responseData, 422);
        }

        $getUser = User::where("user_token",$Authorization)->where("status",1)->where("api_status",1)->where("user_type",1)->first();
        if(empty($getUser)){
            $responseData = [                
                'status' => FALSE,
                'error'=> TRUE,
                'message' => 'Invalid credentials',
            ];
            return response()->json($responseData , 401);
        }
        $userId = $getUser->id;
        $api_status = $getUser->api_status;
        if($api_status == 0){
            $responseData = [                
                'status' => FALSE,
                'error'=> TRUE,
                'message' => 'We are facing technical issue from bank side.',
            ];
            return response()->json($responseData , 200);die;
        }
        $bank_deactive = $getUser->bank_deactive;
        if($bank_deactive == 1){
            $responseData = [                
                'status' => FALSE,
                'error'=> TRUE,
                'message' => 'Your API has been Deactivated by the Bank due to security reasons.',
            ];
            return response()->json($responseData , 200);die;
        }
        $tecnical_issue = $getUser->tecnical_issue;
        if($tecnical_issue == 1){
            $responseData = [                
                'status' => FALSE,
                'error'=> TRUE,
                'message' => 'We are facing technical issue from bank side.',
            ];
            return response()->json($responseData , 200);die;
        }
        $vouch = $getUser->vouch;
        if($vouch != 1){
            $responseData = [                
                'status' => FALSE,
                'error'=> TRUE,
                'message' => 'This service is not active at this time. please use FINO bank api.',
            ];
            return response()->json($responseData , 200);die;
        }
        $ipAddress = $request->ip();
        $checkIp = UserIp::where(['userId'=>$userId,'ipAddress'=>$ipAddress])->first();
        if(empty($checkIp)){
            $responseData = [                
                'status' => FALSE,
                'error'=> TRUE,
                'message' => 'your ip is not whitlisted, requested ip is '.$ipAddress,
            ];
            return response()->json($responseData , 401);
        }

        $txn_id = rand(12312,99099).Carbon::now()->timestamp;
        $name = $request['name'];
        $accountNumber = $request['accountNumber'];
        $bankIfsc = $request['bankIfsc'];
        $mobileNumber = $request['mobileNumber'];
        $beneBankName = $request['beneBankName'];
        $referenceNumber = $request['referenceNumber'];
        $transferAmount = (int)$request['transferAmount'];
        $transferMode = $request['transferMode'];

        $getCommission = UserCharge::where('start_amount', '<=', $transferAmount)->where('end_amount', '>=', $transferAmount)->where('userId', '=', $userId)->first();
        if(empty($getCommission)){
            $charge = 20;
            $chargeType = "F";
        }else{
            $charge = $getCommission->payout_charge;
            $chargeType = $getCommission->payout_charge_type;
        }
        $gst = 18;
        if($chargeType == "F"){
            $totalCharge = $charge;
            $totalGst = ($totalCharge*$gst)/100;
        }else if($chargeType == "P"){
            $totalCharge = ($Amount*$charge)/100;
            $totalGst = ($totalCharge*$gst)/100;
        }
        $totalDeductAmount = $transferAmount +$totalCharge+$totalGst;
        $openBal = $getUser->wallet;
        $lien =$getUser->lien;
        $rolling_reserve = $getUser->rolling_reserve;
        $closeBal = $openBal - $totalDeductAmount;                    
        $checkAmount = $totalDeductAmount+$lien+$rolling_reserve;
        if($openBal == 0 || $openBal < $checkAmount){           
            $responseData = [                
                'status' => FALSE,
                'error'=> TRUE,
                'message' => 'Insufficient fund',
            ];
            return response()->json($responseData , 200);
        }
        
        $UserInstance = new User();
        $UserInstance->deductFund($userId,$totalDeductAmount);

        $remark = "Money Transfer Via Payout ";
        UserTransaction::create([
            'userId' => $userId,
            'txnId' => $txn_id,
            'orderId' => $referenceNumber,
            'type' => "DEBIT",  
            'operator' => "PAYOUT",
            'openBalance' =>$openBal, 
            'amount' => $totalDeductAmount,
            'walletBalance' =>$closeBal,
            'credit' =>0, 
            'debit' =>$totalDeductAmount,
            "status" => "PENDING",
            'remark' => $remark,   
            'api'=>"VOUCH",
            'requestIp' => $ipAddress,          
            'created_by' => $userId,
        ]);

        PayoutModel::create([
            'userId' => $userId,
            'txnId' => $txn_id,
            'orderId' => $referenceNumber,
            'amount' => $transferAmount,
            'charge' =>$totalCharge,   
            'gst'=>$totalGst,
            'totalAmount' => $totalDeductAmount,   
            'mode'=>$transferMode,
            'beneName' => $name,          
            'beneBank' => $beneBankName,
            'beneAccount' => $accountNumber,   
            'beneIfsc' => $bankIfsc,          
            'status' => "PENDING",
            'api'=>"VOUCH",
            'IpAddress' => $ipAddress,
        ]);
                
        $transaction_note = "PAY".$mobileNumber;

        $escrow_id = "SEOSPAY-01";
        $header = array(
            'Content-Type:application/json',
            'apikey:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJkNjkwYTdmYS00YjQ4LTRiMDAtYmVlNi0xMmFkMWZlYTA5MDgiLCJuYW1lIjoiTWFwcHNpbmsgQWR2aXNvcnkgUHJpdmF0ZSBMaW1pdGVkIiwicmVnIjoiVEduU2NWbTk5eHBGSzhxMG5uMkwiLCJjb25maWciOiJTZW9zUEFZIiwiZW52IjoibGl2ZSIsImlhdCI6MTY5NTI5MDA4NH0.FP544qP1ymHNu0MXJA6wQl9xke3kl7JsZ4WSY1JUX0Y'
        );

        $requestBody = [
            "escrow_id" => $escrow_id,
            "terms_and_conditions_met" => true,
            "payouts" => [
                [
                    "payout_ref" => $txn_id,
                    "amount" => $transferAmount,
                    "payout_mode" => $transferMode,
                    "transaction_note" => $transaction_note,
                    "payee" => [
                        "user_ref" => $name . '' . $mobileNumber,
                        "user_name" => $name,
                        "user_mobile_number" => $mobileNumber
                    ],
                    "beneficiary" => [
                        "account_name" => $name,
                        "account_no" => $accountNumber,
                        "ifsc" => $bankIfsc
                    ],
                ],
            ],
            "timestamp" => date("d/m/Y H:i:s a")
        ];

        

        $requestBodyJson = json_encode($requestBody, JSON_UNESCAPED_SLASHES);
        $pem_private_key =  $pem_private_key = file_get_contents(asset('public/vouchpay.key'));
        $encryptedData = openssl_sign($requestBodyJson, $binary_signature, $pem_private_key, OPENSSL_ALGO_SHA256);
        $binary_signature = base64_encode($binary_signature);        

        $finalRequestBody = [
            "escrow_id" => $escrow_id,
            "terms_and_conditions_met" => true,
            "payouts" => [
                [
                    "payout_ref" => $txn_id,
                    "amount" => $transferAmount,
                    "payout_mode" => $transferMode,
                    "transaction_note" => $transaction_note,
                    "payee" => [
                        "user_ref" => $name . '' . $mobileNumber,
                        "user_name" => $name,
                        "user_mobile_number" => $mobileNumber
                    ],
                    "beneficiary" => [
                        "account_name" => $name,
                        "account_no" => $accountNumber,
                        "ifsc" => $bankIfsc
                    ],
                ],
            ],
            "timestamp" => date("d/m/Y H:i:s a"),
            "signature" => $binary_signature
        ];

        //file_put_contents("log/vouch-output.txt", print_r($finalRequestBody, true), FILE_APPEND);

        $payload = json_encode($finalRequestBody);

        $curl = curl_init();

        curl_setopt_array($curl, [
            CURLOPT_URL => 'https://sim.iamvouched.com/v1/escrow/payout',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => $payload,
            CURLOPT_HTTPHEADER => $header
        ]);

        $response = curl_exec($curl);
        //$response = '{"data":[{"payout_ref":"985441695360856","status":"processed","message":"Transaction Successful","data":{"bankref":"326511345627"}}],"message":"Payout Instructions Registered, You will receive updates via webhooks","status":200}';
        $err = curl_error($curl);
        curl_close($curl);

        // echo $response;die;
        ApiLog::create([
            'txnId' => $txn_id,
            'request' => $payload,
            'response' => $response,  
            'service' => "PAYOUT",
            'service_api' =>"VOUCH",   
        ]);

        $responseData = json_decode($response, true);     
        
        $message = "";
        if(isset($responseData['message']) && $responseData['message'] == "BAD_REQUEST"){
            $message = $responseData['message'];
        }

        if(isset($responseData['message']) && $responseData['message'] == "Invalid Signature"){
            $message = $responseData['message'];
        }
         
        if($message === "BAD_REQUEST" || $message === "Invalid Signature"){

            $statusMessage = "Transaction failed at bank end";
            if(isset($responseData['error'])){
                $statusMessage =$responseData['error'];
            }
            $updateUser = [
                'walletBalance' =>$openBal,
                'status' => "FAILED"
            ];  

            $UserTransaction = new UserTransaction();      
            $UserTransaction->updateUserTxnData($updateUser,$txn_id);

            $updatePayout = [                         
                "status"=>"FAILED",
                "remark"=>$statusMessage,
            ];                  
            $PayoutModel = new PayoutModel();      
            $PayoutModel->updatePayoutData($updatePayout,$txn_id);

            $UserInstance = new User();
            $UserInstance->addFund($userId,$totalDeductAmount);

            $responseData = [
                "status" => "FAILED",
                "message" => $statusMessage,
                "data" => array(
                    "payout_ref" => $referenceNumber,
                    "bank_ref" => ""
                ),
            ];
            return response()->json($responseData , 200);
            die;
        }

        if($responseData['data'][0]['status'] == "failed "){

            $statusMessage = "Transaction failed at bank end";
            $updateUser = [
                'walletBalance' =>$openBal,
                'status' => "FAILED"
            ];  

            $UserTransaction = new UserTransaction();      
            $UserTransaction->updateUserTxnData($updateUser,$txn_id);

            $updatePayout = [                         
                "status"=>"FAILED",
                "remark"=>$statusMessage,
            ];                  
            $PayoutModel = new PayoutModel();      
            $PayoutModel->updatePayoutData($updatePayout,$txn_id);

            $UserInstance = new User();
            $UserInstance->addFund($userId,$totalDeductAmount);

            $responseData = [
                "status" => "FAILED",
                "message" => $statusMessage,
                "data" => array(
                    "payout_ref" => $referenceNumber,
                    "bank_ref" => ""
                ),
            ];
            return response()->json($responseData , 200);
            die;
        }

        if($responseData['data'][0]['status'] == "processed" && $responseData['status'] == 200) {

            $resDataM = @$responseData['data'][0];
            $rrn = @$resDataM['data']['bankref'];
            $statusMessage = "Transaction is Successful.";

            $updatePayout = [
                "utr"=>$rrn,
                "status"=>"SUCCESS",
                "remark"=>$statusMessage,
            ];                  
            $PayoutModel = new PayoutModel();      
            $PayoutModel->updatePayoutData($updatePayout,$txn_id);
            
            
            $updateUser = [
                'status' => "SUCCESS"
            ];  

            $UserTransaction = new UserTransaction();      
            $UserTransaction->updateUserTxnData($updateUser,$txn_id);

            $responseData = [
                "status" => "SUCCESS",
                "message" => $statusMessage,
                "data" => array(
                    "payout_ref" => $referenceNumber,
                    "bank_ref" => $rrn
                ),
            ];
            return response()->json($responseData , 200);
            die;
        }
        
        $responseData = [
            "status" => "PENDING",
            "message" => "Transaction is under process",
            "data" => array(
                "payout_ref" => $referenceNumber,
                "bank_ref" => ""
            ),
        ];
        return response()->json($responseData , 200);
        die;
    }
}
