<?php

namespace App\Services;

use App\Models\Creditreport;
use App\Models\Sale;
use App\Models\TmpSale;
use App\Models\Recurring;
use App\Models\User;
use App\Models\UserSecurityQuestion;
use App\Models\UserSecurityQuestionAnswer;
use App\Services\Payment\GateWay;
use App\Services\Payment\Payment;
use App\Services\SmartCredit\SmartCredit;
use App\Utility\Email;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class Package
{
    public array $data = [];
    public string $message = "";
    public string $status_code = "";
    public string $customer_token="";
    public string $tracking_token="";
    public string $payment_status_code = "";
    public  string $transaction_id = "";

    public function makePayment($inputData){
        $result = false;
        $this->status_code = config('constant.API_FAILED_CODE');
        $inputData['order_id'] = generateOrderId();
        $inputData['order_description'] = "Creditzombies Package";
        $inputData['ip'] = getClientIpAddress();
        // create pending sale
        $tmpSaleData=[
            'order_id' => $inputData['order_id']
        ];
        $tmpSaleInsetedData = (new TmpSale())->createTmpSale($tmpSaleData);

        // send payment request
        $response = (new Payment(GateWay::getGateWayInstance(config('constant.PAYMENT_GATEWAY.NMI')), $inputData))->pay();


        // log from payment gate way
        appLog([
            'action'=>'PAYMENT_GATEWAY_RESPONSE',
            'response'=>$response
        ]);

        $this->message = $response['message'];

        $sale_status = config('constant.SALE_STATUS.FAILED');
        $inputData['status_code'] = $response['status_code'];

        if($response['status_code'] == config('constant.API_SUCCESS_CODE')){

            $this->purchasePackage($inputData);
            $this->status_code = $response['status_code'];
            $sale_status = config('constant.SALE_STATUS.COMPLETED');
            $this->message = __("Successfully paid");

        }

        // from payment response insert sale table with auth_code, trans_id, invoice_id, order_id
        $inputData['sale_status']=$sale_status;
        $inputData['auth_code'] = $response['auth_code'] ?? "";
        $inputData['transaction_id'] = $response['transaction_id'] ?? "";
        $this->sales($inputData);
        // delete pending sale
        (new TmpSale())->deleteTmpSaleById($tmpSaleInsetedData->id);

        if($inputData['status_code'] == config('constant.API_FAILED_CODE')) {
            $this->paymentFailedMail($inputData);
        }

        if($sale_status == config('constant.SALE_STATUS.COMPLETED')){
            $result = true;
        }

        return [
            'status'=>$result,
            'order_id'=> $inputData['order_id'] ?? 0
        ];
    }

    public function makePayments($inputData){
        $result = false;
        $this->status_code = config('constant.API_FAILED_CODE');
        $inputData['order_id'] = generateOrderId();
        $inputData['order_description'] = "Creditzombies Package";
        $inputData['ip'] = getClientIpAddress();
        // create pending sale
        $tmpSaleData=[
            'order_id' => $inputData['order_id']
        ];
        $tmpSaleInsetedData = (new TmpSale())->createTmpSale($tmpSaleData);

        // send payment request
        $response = (new Payment(GateWay::getGateWayInstance(config('constant.PAYMENT_GATEWAY.NMI')), $inputData))->pay();


        // log from payment gate way
        appLog([
            'action'=>'PAYMENT_GATEWAY_RESPONSE',
            'response'=>$response
        ]);

        $this->message = $response['message'];

        $sale_status = config('constant.SALE_STATUS.FAILED');
        $inputData['status_code'] = $response['status_code'];

        if($response['status_code'] == config('constant.API_SUCCESS_CODE')){

            $this->purchasePackages($inputData);
            $this->status_code = $response['status_code'];
            $sale_status = config('constant.SALE_STATUS.COMPLETED');
            $this->message = __("Successfully paid");

        }

        // from payment response insert sale table with auth_code, trans_id, invoice_id, order_id
        $inputData['sale_status']=$sale_status;
        $inputData['auth_code'] = $response['auth_code'] ?? "";
        $inputData['transaction_id'] = $response['transaction_id'] ?? "";
        $this->sales($inputData);
        // delete pending sale
        (new TmpSale())->deleteTmpSaleById($tmpSaleInsetedData->id);

        if($inputData['status_code'] == config('constant.API_FAILED_CODE')) {
            $this->paymentFailedMail($inputData);
        }

        if($sale_status == config('constant.SALE_STATUS.COMPLETED')){
            $result = true;
        }

        return [
            'status'=>$result,
            'order_id'=> $inputData['order_id'] ?? 0
        ];
    }

    public function recurringPackage($paymentData)
    {

        $inputData=[];
        $result = [];
        $logData['action'] = "RECURRING_PACKAGE";

        try {
            $response = (new Payment(GateWay::getGateWayInstance(config('constant.PAYMENT_GATEWAY.NMI')), $paymentData))->makeRecurringPayment();

            DB::beginTransaction();

            $inputData['transaction_status'] = $response['transaction_status'];
            $inputData['email'] = $paymentData['email'];
            $inputData['name'] = $paymentData['first_name'] . ' ' . $paymentData['last_name'];
            $inputData['user_id'] = $paymentData['user_id'] ?? 0;
            $inputData['day_frequency'] = 0;
            $inputData['transaction_id'] = $response['transaction_id'] ;
            $inputData['subscription_id'] = $response['subscription_id'] ;
            $inputData['last_process_date'] = getCurrentDateTime();
            $inputData['plan_amount'] = config('constant.PLAN_AMOUNT');
            $inputData['day_of_month'] = config('constant.DAY_OF_MONTH');

            (new Recurring())->insert($inputData);

            DB::commit();
            $result['message'] = $response['message'];
            $result['status_code'] = $response['status_code'];
            $result['transaction_id'] = $inputData['transaction_id'];
            $result['status'] = $response['status'];
           // $result['order_id'] = $inputData['orderid'] ?? "";

        } catch (\Exception $ex) {
            DB::rollback();
            $result['message'] = $ex->getMessage();
            $result['status_code'] = config('constant.API_FAILED_CODE');
        }

        $logData['data']['message'] = $result['message'];
        $logData['data']['status_code'] = $result['status_code'];

        appLog($logData);

        return $result;
    }

    public function deleteRecurringPackage($inputData)
    {
        $result = [];

        $logData['action'] = "DELETE_RECURRING_PACKAGE";

        try {
            $response = (new Payment(GateWay::getGateWayInstance(config('constant.PAYMENT_GATEWAY.NMI')), $inputData))->deleteSubscription();

            $result['message'] = $response['message'];
            $result['status_code'] = $response['status_code'];
            $result['subscription_id'] = $inputData['subscription_id'];
            $result['status'] = $response['status'];

        }catch (\Exception $ex) {
            $result['message'] = $ex->getMessage();
            $result['status_code'] = config('constant.API_FAILED_CODE');
        }

        $logData['data']['message'] = $result['message'];
        $logData['data']['status_code'] = $result['status_code'];
        $logData['email'] = $inputData['email'];

        appLog($logData);

        return $result;
    }
/*
    public function payment($inputData)
    {
        $logData['action'] = "PURCHASE_PACKAGE";
        $sale_status = config('constant.SALE_STATUS.PENDING');

        $inputData['order_id'] = generateOrderId();
        $inputData['order_description'] = "Creditzombies Package";
        $inputData['ip'] = getClientIpAddress();

        if(isset($inputData['user_id']) && $inputData['user_id'] > 0){
            $user_id  = $inputData['user_id'];
        }else {
            $user_id = getUserId();
        }

        // create pending sale
        $tmpSaleData['order_id'] = $inputData['order_id'];
        $tmpSaleObj = new TmpSale();
        $tmpSaleInsetedData = $tmpSaleObj->createTmpSale($tmpSaleData);

        // send payment request
        $response = (new Payment(GateWay::getGateWayInstance(config('constant.PAYMENT_GATEWAY.NMI')), $inputData))->pay();

        // log from payment gate way
        appLog([
            'action'=>'PAYMENT_GATEWAY_RESPONSE',
            'response'=>$response
        ]);

        $this->message = __($response['message']);

        $sale_status = config('constant.SALE_STATUS.FAILED');

        if($response['status_code'] == config('constant.API_SUCCESS_CODE')){
            $this->status_code = $response['status_code'];
            $sale_status = config('constant.SALE_STATUS.COMPLETED');
            $this->message = __("Successfully paid");
        }

        // from payment response insert sale table with auth_code, trans_id, invoice_id, order_id
        $saleData['order_id'] = $inputData['order_id'];
        $saleData['ip'] = $inputData['ip'];
        $saleData['status'] = $sale_status;
        $saleData['auth_code'] = $response['auth_code'] ?? "";
        $saleData['transaction_id'] = $response['transaction_id'] ?? "";
        $saleData['user_id'] = $user_id;
        (new Sale())->createSale($saleData);

        // delete pending sale
        $tmpSaleObj->deleteTmpSaleById($tmpSaleInsetedData->id);

        if($sale_status != config('constant.SALE_STATUS.COMPLETED')){
            throw new \Exception($this->message);
        }

    }
*/
    public  function deleteRecurring($inputData)
    {
        $returnData= (new Recurring())->deleteRecurring($inputData);
        if($returnData) {
            $userData = [
                'is_import' => config('constant.IMPORT_REPORT_STATUS.NOT_ELIGIBLE'),
                'subscription_status' => config('constant.SUBSCRIPTION_STATUS.UNSUBSCRIBED')
            ];
            (new User())->userupdate($userData, $inputData['user_id']);
        }
        return $returnData;
    }

    public function createCustomer($inputData){

        $this->payment_status_code = config('constant.API_FAILED_CODE');
        $status_code = config('constant.API_FAILED_CODE');
        $payment_data = $inputData;
        // for one time payment
        $onetimePayment = $this->makePayment($payment_data);

        if($onetimePayment['status']) {

            // for recurring
            $this->recurringPackage($inputData);

            $this->payment_status_code = config('constant.API_SUCCESS_CODE');
            $order_id = $onetimePayment['order_id'] ?? "";

            if(config('app.REPORT_PROVIDER') == '3') {

                $smart_creditData = $this->prepareData($inputData);
                $smart_credit = (new SmartCredit(config('app.CLIENT_KEY')))
                    ->setData($smart_creditData)
//                    ->register() // for stage server
                    ->register();

                $status_code = $smart_credit->status_code ;
                $this->tracking_token = $smart_credit->tracking_token ;
                $this->customer_token = $smart_credit->customer_token ;
                $this->data = $smart_credit->data;
                $this->message = $smart_credit->message;

            }
            $this->data['order_id'] = $order_id;

        }

        $this->status_code = $status_code;

        /*// log from payment gate way
        appLog([
            'action' => 'SMART_CREDIT_API_RESPONSE',
            'response' => $smart_credit
        ]);*/
        return $this;
    }

    public  function securityQuestions()
    {
        return (new SmartCredit(config('app.CLIENT_KEY')))->security_questions();
    }

    public function checkIsEmailExistOnSmartCredit($inputData)
    {
        return (new SmartCredit(config('app.CLIENT_KEY')))->setData($inputData)->checkIsEmailExistOnSmartCredit();
    }

    public function identityQuestionAnswer()
    {
        $data='{
  "idVerificationCriteria": {
    "referenceNumber": "07271524018421870957",
    "question1": {
      "name": "YEAR_FOUNDED",
      "displayName": "What year was ConsumerDirect (aka PathwayData, aka MyPerfectCredit) founded?",
      "type": "MC",
      "choiceList": {
        "choice": [
          {
            "key": "1980",
            "display": "1980"
          },
          {
            "key": "1969",
            "display": "1969"
          },
          {
            "key": "2012",
            "display": "2012"
          },
          {
            "key": "2003",
            "display": "2003"
          },
          {
            "key": "!(1980^1969^2012^2003)",
            "display": "None of the above"
          }
        ]
      }
    },
    "question2": {
      "name": "NOT_CREDIT_BUREAU",
      "displayName": "Which company is NOT a credit bureau?",
      "type": "MC",
      "choiceList": {
        "choice": [
          {
            "key": "Experian",
            "display": "Experian"
          },
          {
            "key": "ConsumerDirect",
            "display": "ConsumerDirect"
          },
          {
            "key": "Equifax",
            "display": "Equifax"
          },
          {
            "key": "TransUnion",
            "display": "TransUnion"
          },
          {
            "key": "!(Experian^ConsumerDirect^Equifax^TransUnion^)",
            "display": "None of the above"
          }
        ]
      }
    },
    "question3": {
      "name": "INVENTED_INTERNET",
      "displayName": "Who invented the internet?",
      "type": "MC",
      "choiceList": {
        "choice": [
          {
            "key": "J. C. R. Licklider",
            "display": "J. C. R. Licklider"
          },
          {
            "key": "George Clooney",
            "display": "George Clooney"
          },
          {
            "key": "Al Gore",
            "display": "Al Gore"
          },
          {
            "key": "Howard Stark",
            "display": "Howard Stark"
          },
          {
            "key": "!(J. C. R. Licklider^George Clooney^Al Gore^Howard Stark^)",
            "display": "None of the above"
          }
        ]
      }
    }
  }
}';
        $returnData['data']=json_decode($data,true);
        $returnData['message']='success';
        $returnData['status_code']='100';
//        $questionAnswerList=(new SmartCredit(config('app.CLIENT_KEY')))->security_questions();
        return $returnData;
    }

    public function submitIdentityQuestionAnswer($inputData)
    {
        $questionAnswerList=(new SmartCredit(config('app.CLIENT_KEY')))->security_question($inputData);
        return $questionAnswerList;
    }

    private function prepareData($inputData)
    {
        $smart_creditData=[];
        $smart_creditData['email'] = $inputData['email'];
        $smart_creditData['planType'] = config('constant.package')[$inputData['package_id']];
        $smart_creditData['password'] = $inputData['password'];
        $smart_creditData['first_name'] = $inputData['first_name'];
        $smart_creditData['last_name'] = $inputData['last_name'];
        $smart_creditData['client_ip'] = getClientIpAddress();
        $smart_creditData['zip'] = $inputData['zip_code'];
        $smart_creditData['street'] = $inputData['street_no'] . " " . $inputData['street_name'];
        $smart_creditData['phone'] = $inputData['phone'];
        $smart_creditData['dob'] = $inputData['birth_date'];
        $smart_creditData['ssn'] = $inputData['full_ssn'];
        $smart_creditData['partial_ssn'] = $inputData['ssn'];
        $smart_creditData['sqa_answer'] = "Creditzombies";
        $smart_creditData['sqa_question'] = 1;
        return $smart_creditData;
    }

    public function purchasePackage($inputData){
        $logData['action'] = "PURCHASE_PACKAGE";
        $inputData['order_description'] = "Creditzombies Package";
        $inputData['ip'] = getClientIpAddress();

        if(!isset($inputData['user_id'])){
            $inputData['user_id'] = 0;
        }

        $trace_string = "";
        try {
            // start begin transaction
            DB::beginTransaction();
            $is_import = 0;
            $wave = $inputData['wave'] ?? 0;
            $is_subscribed = 0;
            $last_payment_date = $inputData['last_payment_date'] ?? null;
            if(($inputData['status_code'] == config('constant.API_SUCCESS_CODE') && $inputData['user_id']>0) || $inputData['is_free'] == 1)
            {
                $is_import = 1;
                $wave += 1;
                $is_subscribed = 1;
                $last_payment_date = getCurrentDateTime();
                $creditReportData['user_id'] = $inputData['user_id'];
                $creditReportData['email'] = $inputData['email'];
                $creditReportData['password'] = $inputData['password'];
                $creditReportData['report_type'] = config('app.REPORT_PROVIDER') ?? 3;

                (new Creditreport())->insertCreditReport($creditReportData);

                $updateUserData['zip_code'] = $inputData['zip_code'];
                $updateUserData['phone'] = $inputData['phone'];
                $updateUserData['is_import'] = $is_import;
                $updateUserData['subscription_status'] = $is_subscribed;
                $updateUserData['wave'] = $wave;
                $updateUserData['last_payment_date'] = $last_payment_date;
                $updateUserData['user_access_end_date'] = getDateAfterSpicificDay($last_payment_date,config('constant.PAYMENT_INTERVAL_DAY'));
                (new User())->userupdate($updateUserData,$inputData['user_id']);
            }


            DB::commit();

            $this->message = __("Account creation completed");
            $this->status_code = config('constant.API_SUCCESS_CODE');

        } catch (\Exception $ex){
            DB::rollback();
            $this->message = $ex->getMessage();
            $this->status_code = config('constant.API_FAILED_CODE');
            $trace_string = $ex->getTraceAsString();
        }

        $logData['data']['message'] = $this->message;
        $logData['data']['status_code'] = $this->status_code;

        if(!empty($trace_string)) {
            $logData['data']['trace'] = $trace_string;
        }

        appLog($logData);

    }

    public function purchasePackages($inputData){
        $logData['action'] = "PURCHASE_PACKAGE";
        $inputData['order_description'] = "Creditzombies Package";
        $inputData['ip'] = getClientIpAddress();

        if(!isset($inputData['user_id'])){
            $inputData['user_id'] = 0;
        }

        $trace_string = "";
        try {
            // start begin transaction
            DB::beginTransaction();

            $is_subscribed = 0;
            $last_payment_date = $inputData['last_payment_date'] ?? null;
            if($inputData['status_code'] == config('constant.API_SUCCESS_CODE') && $inputData['user_id']>0)
            {

                $is_subscribed = 1;
                $last_payment_date = getCurrentDateTime();
                $creditReportData['user_id'] = $inputData['user_id'];
                $creditReportData['email'] = $inputData['email'];
                $creditReportData['password'] = $inputData['password'];
                $creditReportData['report_type'] = config('app.REPORT_PROVIDER') ?? 3;

                (new Creditreport())->insertCreditReport($creditReportData);

                $updateUserData['zip_code'] = $inputData['zip_code'];
                $updateUserData['phone'] = $inputData['phone'];
                $updateUserData['subscription_status'] = $is_subscribed;
                $updateUserData['last_payment_date'] = $last_payment_date;
                (new User())->userupdate($updateUserData,$inputData['user_id']);
            }


            DB::commit();

            $this->message = __("Account creation completed");
            $this->status_code = config('constant.API_SUCCESS_CODE');

        } catch (\Exception $ex){
            DB::rollback();
            $this->message = $ex->getMessage();
            $this->status_code = config('constant.API_FAILED_CODE');
            $trace_string = $ex->getTraceAsString();
        }

        $logData['data']['message'] = $this->message;
        $logData['data']['status_code'] = $this->status_code;

        if(!empty($trace_string)) {
            $logData['data']['trace'] = $trace_string;
        }

        appLog($logData);

    }

    public function customerCreditReportStatus($inputData)
    {
        $creditReportDataObj = (new Creditreport())->getCreditReportInfoByUserIdAndType($inputData['user_id'], $inputData['report_type']);
        if (!empty($creditReportDataObj)) {
            $password = customDecrypt($creditReportDataObj->password);
            $inputData['email'] = $creditReportDataObj->email;
            $inputData['password'] = $password;
            $apiResponse = (new SmartCredit(config('app.CLIENT_KEY')))->customerSubscription($inputData);
            if($apiResponse->status_code == config('constant.API_SUCCESS_CODE')) {
                $this->data = $apiResponse->data;
                $this->status_code = $apiResponse->status_code;
                $this->message = $apiResponse->message;
            }
        }
        return $this;
    }

    private function sales($inputData){
        $saleData = [];
        $saleData['order_id'] = $inputData['order_id'];
        $saleData['ip'] = getClientIpAddress();
        $saleData['status'] = $inputData['sale_status'];
        $saleData['auth_code'] = $inputData['auth_code'];
        $saleData['transaction_id'] = $inputData['transaction_id'];
        $saleData['user_id'] = $inputData['user_id'] ?? 0;
        $saleData['cc_number'] =creditCardNumberMasking($inputData['card_number']);
        return (new Sale())->createSale($saleData);
    }

    public function paymentFailedMail($inputData)
    {

            $data['email'] = $inputData['email'];
            $data['email_body'] = $inputData['first_name'] . ' ' . $inputData['last_name'];
            $data['email_subject'] = "Payment Failed";
            $from = null;
            $attachment = null;
            (new Email())->send($data, $data['email_subject'], $from, $attachment, 'email.payment_failed_letter', $data['email']);

    }
}
