<?php

namespace App\PayoutCF;

use App\CFPayoutBalance;
use App\CFPayoutBeneficiary;
use App\CFPayoutDirectTransfer;
use App\CFPayoutRequestTransfer;
use App\CFPayoutRequestTransferStatus;
use App\CFPayoutWebhook;
use App\RefundPayments;
use App\Slack;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Admin\ConsumerApplicationController;
use App\Console\Commands\VendorWebhook;

class CF_Logs{

    const CREATE = 'C';
    const REVISE = 'R';
    const EXISTS = 'E';

    public function isBeneficiaryVerified(Request  $req){
        if ($req->get('beneId')) {
            $cfPayoutBeneficiary = CFPayoutBeneficiary::where('beneId', $req->get('beneId'))->where('status', 'VERIFIED')->first(['id']);
            return isset($cfPayoutBeneficiary->status);
        }
        return false;
    }

    public function isBenIDExists(Request  $req){
        if ($req->get('beneId')) {
            $cfPayoutBeneficiary = CFPayoutBeneficiary::where('beneId', $req->get('beneId'))->first();
            if ($cfPayoutBeneficiary && ($cfPayoutBeneficiary->bankAccount != $req->get('bankAccount') || $cfPayoutBeneficiary->bankAccount != $req->get('ifsc'))){
                return self::REVISE;
            }
            return $cfPayoutBeneficiary ? self::EXISTS : self::CREATE;
        }
        return self::CREATE;
    }

    public function addBeneficiaryLog(Request $req, $res){
        try {
            $cfPayoutBeneficiary = new CFPayoutBeneficiary();
            $cfPayoutBeneficiary->fill([
                "beneId" => $res->data->beneId,
                "name" => $res->data->name,
                "groupName" => $res->data->groupName,
                "email" => $res->data->email,
                "phone" => $res->data->phone,
                "address1" => $res->data->address1 . ' ' . $res->data->address2,
                "city" => $res->data->city,
                "state" => $res->data->state,
                "pincode" => $res->data->pincode,
                "bankAccount" => $res->data->bankAccount,
                "ifsc" => $res->data->ifsc,
                "status" => $res->data->status,
                "created_at" => Carbon::now()->toDateTimeString()
            ]);
            $cfPayoutBeneficiary->save();
            return $cfPayoutBeneficiary->id;
        }catch (\Exception $e){
            (new Slack(new Request(['title' =>'CF Logs '.__FUNCTION__, 'fields' => ['Message' => $e->getMessage(), 'File' => $e->getFile(), 'Trace' => $e->getTraceAsString(), 'Line' => $e->getLine(), 'Link' => $e->get('link')], 'group' => Slack::$STAGE_TESTING])))->send();
        }
        return false;
    }

    public function updateBeneficiaryLog(Request $req, $res){
        $cfPayoutBeneficiary = CFPayoutBeneficiary::where('beneId', $req->get('beneId'))->first(['id', 'status']);
        if(isset($cfPayoutBeneficiary->id)){
            CFPayoutBeneficiary::where('id', $cfPayoutBeneficiary->id)->update(['status' => $res->data->status]);
        }
    }

    public function requestTransferLog(Request $req, $res){
        try {
            $cfPayoutRequestTransfer = new CFPayoutRequestTransfer();
            $cfPayoutRequestTransfer->fill([
                "application_id" => $req->get('id'),
                "beneId" => $req->get('beneId'),
                "amount" => $req->get('amount'),
                "transferId" => $req->get('transferId'),
                "referenceId" => $res->data->referenceId,
                "utr" => $res->data->utr,
                "acknowledged" => $res->data->acknowledged,
                "created_at" => Carbon::now()->toDateTimeString()
            ]);
            $cfPayoutRequestTransfer->save();
            return $cfPayoutRequestTransfer->id;
        }catch (\Exception $e){
            (new Slack(new Request(['title' =>'CF Logs '.__FUNCTION__, 'fields' => ['Message' => $e->getMessage(), 'File' => $e->getFile(), 'Trace' => $e->getTraceAsString(), 'Line' => $e->getLine(), 'Link' => $e->get('link')], 'group' => Slack::$STAGE_TESTING])))->send();
        }
        return false;
    }

    public function directTransferLog(Request  $req, $res){
        try {
            (new Slack(new Request(['title' =>'CF Cashfree Logs '.__FUNCTION__, 'fields' => ['ID' => is_numeric($req->get('id'))], 'group' => Slack::$STAGE_TESTING])))->send();
            if (is_numeric($req->get('id'))) {
                (new Slack(new Request(['title' =>'CF Cashfree Logs '.__FUNCTION__, 'fields' => ['res' => json_encode($res)], 'group' => Slack::$STAGE_TESTING])))->send();
                $cfPayoutDirectTransfer = new CFPayoutDirectTransfer();
                $cfPayoutDirectTransfer->fill([
                    "application_id" => $req->get('id'),
                    "transferId" => $req->get('transferId'),
                    "referenceId" => $res->data->referenceId ?? null,
                    "utr" => $res->data->utr ?? null,
                    "acknowledged" => $res->data->acknowledged ?? 0,
                    "message" => $res->message,
                    "is_refund" => $req->has('is_refund') && $req->get('is_refund') ? 1 : 0,
                    "created_at" => Carbon::now()->toDateTimeString(),
                    "phase" => $req->get('phase')
                ]);

                if(isset($res->data->utr) && $res->data->utr) {
                    $application = new ConsumerApplicationController();
                    $application->webhook($req->get('id'), ['status' => 'utr', 'type' => 'UTR-Webhook', 'data' => $application->getMConnectPayload($req->get('id'), 'utr', ['utr' => $res->data->utr])]);
                }

                $cfPayoutDirectTransfer->save();
                return $cfPayoutDirectTransfer->id;
            }
        }catch (\Exception $e){
            (new Slack(new Request(['title' =>'CF Cashfree Logs '.__FUNCTION__, 'fields' => ['Message' => $e->getMessage(), 'File' => $e->getFile(), 'Trace' => $e->getTraceAsString(), 'Line' => $e->getLine()], 'group' => Slack::$STAGE_TESTING])))->send();
            $RefundPayments = RefundPayments::where('transferId', $req->get('transferId'))->first(['id']);
            if(isset($RefundPayments->id) && isset($res->data->utr)){
                $refundPayment = RefundPayments::find($RefundPayments->id);

                $acknowledged = $res->data->acknowledged ?? 0;

                $refundPayment->fill([
                    'status' => $acknowledged == 1 ? 'SUCCESS' : 'PENDING',
                    'referenceId' => $res->data->referenceId ?? null,
                    'acknowledged' => $acknowledged,
                    'utr' => $res->data->utr ?? null,
                    'message' => $res->message
                ]);

                $refundPayment->save();
            }else {
                (new Slack(new Request(['title' => 'CF Logs ' . __FUNCTION__, 'fields' => ['Message' => $e->getMessage(), 'File' => $e->getFile(), 'Trace' => $e->getTraceAsString(), 'Line' => $e->getLine()], 'group' => Slack::$STAGE_TESTING])))->send();
            }
        }
        return false;
    }

    public function getTransferStatusLog(Request $req, $res){
        try {
            if(isset($res->data->transfer->transferId) || isset($res->cf_transfer_id)) {
                $cfPayoutBeneficiary = new CFPayoutRequestTransferStatus();
                

                if(_env('CASHFREE_ENDPOINT_VERSION', 1) == 2){
                    $data = [
                        "application_id" => $req->get('id'),
                        "referenceId" => $res->cf_transfer_id,
                        "transferId" => $req->get('referenceId') ? $req->get('referenceId') : $res->transfer_id,
                        "bankAccount" => $res->beneficiary_details->beneficiary_instrument_details->bank_account_number,
                        "beneId" => $res->beneficiary_details->beneficiary_id ?? '0',
                        "amount" => $res->transfer_amount,
                        "status" => $res->status,
                        "utr" => $res->transfer_utr ?? '',
                        "addedOn" => $res->added_on,
                        "processedOn" => $res->updated_on,
                        "acknowledged" => $res->status == CFConfiguration::$status ? 1 : 0,
                        "created_at" => Carbon::now()->toDateTimeString()
                    ];
                }else{
                    $data = [
                        "application_id" => $req->get('id'),
                        "referenceId" => $req->get('referenceId'),
                        "transferId" => $res->data->transfer->transferId,
                        "bankAccount" => $res->data->transfer->bankAccount,
                        "beneId" => $res->data->transfer->beneId,
                        "amount" => $res->data->transfer->amount,
                        "status" => $res->data->transfer->status,
                        "utr" => $res->data->transfer->utr ?? '',
                        "addedOn" => $res->data->transfer->addedOn,
                        "processedOn" => $res->data->transfer->processedOn,
                        "acknowledged" => $res->data->transfer->acknowledged,
                        "created_at" => Carbon::now()->toDateTimeString()
                    ];
                }
                
                
                $cfPayoutBeneficiary->fill($data);
                $cfPayoutBeneficiary->save();
            }
            if(_env('CASHFREE_ENDPOINT_VERSION', 1) == 2){
                $acknowledged = in_array($res->status, ['SUCCESS']) ? 1 : 0;
                $this->directTransferLog($req, (object) ['data' => (object)['acknowledged' => $acknowledged, 'utr' => $res->transfer_utr ?? '', 'referenceId' => $res->cf_transfer_id ?? 0, 'transferId' => $req->get('referenceId') ? $req->get('referenceId') : $res->transfer_id], 'message' => $res->status !== CFConfiguration::$status && $res->status_description ? $res->status_description : $res->status, 'phase' => $res->phase ?? 0]);
            }else{
                $this->directTransferLog($req, (object) ['data' => (object)['acknowledged' => $res->data->transfer->acknowledged ?? 0, 'utr' => $res->data->transfer->utr ?? '', 'referenceId' => $req->get('referenceId'), 'transferId' => $res->data->transfer->transferId ?? 0], 'message' => $res->data->transfer->status ?? $res->message, 'phase' => $res->data->transfer->phase ?? 0]);
            }
            return $cfPayoutBeneficiary->id ?? false;
        }catch (\Exception $e){
            (new Slack(new Request(['title' =>'CF Logs '.__FUNCTION__, 'fields' => ['Message' => $e->getMessage(), 'File' => $e->getFile(), 'Trace' => $e->getTraceAsString(), 'Line' => $e->getLine()], 'group' => Slack::$STAGE_TESTING])))->send();
        }
        return false;
    }

    public function webhook(Request  $request){
        if($request->has('event') && $request->get('event')){

            $CFPayoutWebhook = new CFPayoutWebhook();
            $CFPayoutWebhook->fill($request->all());
            $CFPayoutWebhook->created_at = Carbon::now()->toDateTimeString();
            $CFPayoutWebhook->save();

            $CFPayoutDirectTransfer = CFPayoutDirectTransfer::where('transferId', $request->get('transferId'))->where('referenceId', $request->get('referenceId'))->first(['id']);
            // (new Slack(new Request(['title' => 'vendor webhook cashfree', 'fields' => ['app_id' => $request->get('transferId'), 'event' => $request->get('event')], 'group' => Slack::$STAGE_TESTING])))->send();
            // (new ConsumerApplicationController())->vendorWebhook($request->get('transferId'), ['type' => 'Cashfree-Webhook','status' => $request->get('event'), 'data' => ['UTR' =>$request->get('utr')]]);
            try{
                $vendorWebhook = new VendorWebhook();
                $payload = (new ConsumerApplicationController())->vendorWebhook($request->get('transferId'), ['type' => 'Cashfree-Webhook','status' => $request->get('event'), 'data' => ['UTR' =>$request->get('utr')]]);
                if (isset($payload)) {
                    $vendorWebhook->handle('Cashfree-Webhook', $payload);
                }
            } catch (\Exception $e){
                $cwFactory = new CloudWatchLoggerFactory();
                $cwFactory->logger(json_encode(['message' => $e->getMessage(), 'line' => $e->getLine(), 'trace' => $e->getTraceAsString()]));
            }

            switch ($request->get('event')){
                case 'TRANSFER_SUCCESS':
                    if ($request->get('referenceId')){
                        $transferNumber = explode('_',$request->get('transferId'));
                        if(!empty($transferNumber[1])){
                            $phaseNumber = (int)$transferNumber[1];
                        }else{
                            $phaseNumber = 0;
                        }
                        $this->directTransferLog(new Request(['id' => $request->get('transferId'), 'transferId' => $request->get('transferId'), 'phase' => $phaseNumber]), (object)['data' => (object)['acknowledged' => $request->get('acknowledged'), 'utr' => $request->get('utr'), 'referenceId' => $request->get('referenceId'), 'transferId' => $request->get('transferId')], 'message' => 'SUCCESS']);
                    }
                    break;
                case 'TRANSFER_ACKNOWLEDGED':
                    $CFPayoutDirectTransfer = CFPayoutDirectTransfer::where('transferId', $request->get('transferId'))->where('referenceId', $request->get('referenceId'))->where('message', 'SUCCESS')->first(['id']);
                    if (isset($CFPayoutDirectTransfer->id)) {
                        CFPayoutDirectTransfer::where('id', $CFPayoutDirectTransfer->id)->update(['acknowledged' => $request->get('acknowledged')]);
                    }
                    break;
            }

            return true;
        }

        return false;
    }
}
