<?php

namespace App\Http\Controllers;

use App\_Slack;
use App\ABFL\Services\Services;
use App\ApplicationEMICalculation;
use App\Bank;
use App\ConsumerApplication;
use App\ConsumerApplicationElement;
use App\MerchantCategoryKYCRules;
use App\DigitalSignDetails;
use App\EMICalculation;
use App\EmiPayment;
use App\Logging\CloudWatchLoggerFactory;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Admin\AccountingController;
use App\Http\Controllers\Admin\ConsumerApplicationController;
use App\Http\Controllers\Admin\ConsumerDocument;
use App\Http\Controllers\Admin\DisbursementController;
use App\KYCDetails;
use App\Lenders;
use App\LoanManagement;
use App\Mandate;
use App\Merchant;
use App\MerchantCategory;
use App\MerchantFiles;
use App\MerchantOffers;
use App\MerchantLocation;
use App\PaymentEmi;
use App\Slack;
use App\User;
use Carbon\Carbon;
use function Composer\Autoload\includeFile;
use Hashids\Hashids;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Input;
use App\ConsumerApplicationFiles;
use Illuminate\Support\Facades\App;
use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use App\Model\LoanAgreementVendor;
use App\KarzaVideo;
use App\KarzaVideoAttribute;
use App\KarzaVideoWebhook;
use App\LoanHypothecation\LoanHypothecation;
use App\Shortio;
use App\DigioVKYC;
use App\BankValidation;
use App\Http\Controllers\FrontController;

class PostApprovalController extends Controller
{

    public function __construct() {
        $this->cloudwatchLogger = new CloudWatchLoggerFactory();
    }

    public function getKYCDone($app_id){
        try {
            $hashids = new Hashids('Creditfair by CS', 20);
            $frontController = new FrontController();
            $apiController = new ApiController();
            $id = $hashids->decode($app_id);
            if(isset($id[0])){
                $user_details = ConsumerApplication::where('id', $id[0])->first(['name', 'mobile_number', 'email', 'approved_amount', 'purpose', 'merchant_id', 'loan_amount', 'co_applicant_name','co_applicant_email','co_applicant_mobile_number','offer_id','lender_id','state']);
                $applicationElement = ConsumerApplicationElement::where('application_id', $id[0])->orderBy('created_at', 'desc')->first(['preferred_language','onfido_skip', 'agreement_resign', 'co_app_onfido_skip', 'is_consent']);
                $consumerAdditional = DB::selectOne("SELECT linked_status, co_linked_status FROM consumer_application_additional WHERE application_id = " . $id[0]);
                $offer_details = MerchantOffers::where('merchant_id', $user_details->merchant_id)->where('id', $user_details->offer_id)->where('status',1)->first();
                if(!isset($offer_details->id)){
                    (new Slack(new Request(['title' => 'Offer missing in loan agreement', 'fields' => ['application_id' => $id[0]]])))->send();
                    return redirect()->to('/404');
                }
                $net_loan_amount = $frontController->checkNetLoanAmount($offer_details, $user_details->approved_amount);
                $signed_data = DigitalSignDetails::where('application_id', $id[0])->where('applicant', 1)->first();
                $co_app_signed_data = DigitalSignDetails::where('application_id', $id[0])->where('applicant', 2)->first();

                $kycStatus = $this->checkKYCStatus($id[0])->getData();
                $data['app_kyc_completed'] = $kycStatus->applicant->kyc_completed ? true : false;
                if (isset($user_details->co_applicant_name)) {
                    $data['co_app_kyc_completed'] = $kycStatus->co_applicant->kyc_completed ? true : false;
                }
                if ($data['app_kyc_completed'] && ((isset($data['co_app_kyc_completed']) && $data['co_app_kyc_completed']) || !isset($user_details->co_applicant_name))) {
                    return $this->esign($app_id);
                } else {
                    $merchant = Merchant::where('id', $user_details->merchant_id)->first(['merchant_name', 'category_id']);
                    $kycRules = MerchantCategoryKYCRules::where('category_id', $user_details->purpose)->where('lender_id', $user_details->lender_id)->get();
                    // if(isset($applicationElement->linked_status) && $applicationElement->linked_status != 2){
                        $kycType = $frontController->checkKycCondition($user_details->approved_amount, $kycRules);
                        // if($kycType != 1){
                            // return $this->esign($app_id);
                        // }
                    // }
                    $amount = isset($user_details->approved_amount) && !empty($user_details->approved_amount) && $user_details->approved_amount != 0 ? $user_details->approved_amount : $user_details->loan_amount;
                    $content = 'Please complete the KYC and loan signing to receive disbursement of loan for ₹' . $amount;
                    if ($merchant->category_id != 3) {
                        $content = 'Please complete the payment, KYC and loan agreement signing to receive disbursement of loan for purchase from ' . $merchant->merchant_name . ' for ₹' . $amount;
                    }

                    $data['status'] = 'success';
                    $data['application_id'] = $id[0];
                    $data['hashed_application_id']= $app_id;
                    $data['request_id'] = isset($request_id) ? $request_id : '';
                    $data['identifier'] = isset($identifier) ? $identifier : '';
                    $data['source'] = 'link';
                    $data['text_content'] = isset($content) ? $content : '';
                    $data['user_details'] = $user_details;
                    $data['preferred_language'] = isset($applicationElement->preferred_language) ? $applicationElement->preferred_language : '';
                    $isHypothecationActive = $apiController->canHypothecated($id[0]);
                    $stepDetails = $frontController->getFeesData($id[0],false, true);
                    if (isset($stepDetails['set_auto_debit'])) {
                        $data['mandate'] = 1;
                    }
                    if (isset($stepDetails['payment_details']['Total Payment']['amount']) && $stepDetails['payment_details']['Total Payment']['amount'] > 0) {
                        $data['payment'] = 1;
                    }
                    if (!$stepDetails['bank']['validation']) {
                        $data['bank'] = 1;
                    }
                    if (isset($stepDetails['co_applicant_bank']) && !$stepDetails['co_applicant_bank']) {
                        $data['co_applicant_bank'] = 1;
                    }
                    $data['isHypothecationActive'] = $isHypothecationActive;
                    $data['consentGiven'] = $applicationElement->is_consent;
                    if ($kycType == 1) {
                        return view('admin.digio_vkyc_integration', $data);
                    }
                    return view('admin.karza_vkyc_integration', $data);
                }
            }
        } catch (\Exception $e) {
            $this->cloudwatchLogger->logger(json_encode(['title' => 'Post Approval Link','application id' => $app_id, 'message' => $e->getMessage(), 'line' => $e->getLine(), 'trace' => $e->getTraceAsString()]));
            return redirect()->to('/404');
        }
    }

    public function esign($id, $applicantType = 1){
        try {
            $hashids = new Hashids('Creditfair by CS', 20);
            $frontController = new FrontController();
            $hashed_application_id = $id;
            $application_ids = $hashids->decode($id);
            if (request()->has('type')) {
                $applicantType = request()->get('type');
            }
            if(!isset($application_ids[0])){
                $datasucess = array("application_ids" => 1,"failure"=>"");
                return view('front.esign-failure', $datasucess);
            }
            $application_id = $application_ids[0];
            $applicationDetails = ConsumerApplication::with('merchant')->where('id', $application_id)->first(['merchant_id', 'co_applicant_name', 'name', 'lender_id', 'approved_amount']);

            $apiController = new ApiController();
            $isHypothecationActive = $apiController->canHypothecated($application_id);
            if ($isHypothecationActive) {

                $kycDetails = $this->checkKYCStatus($application_id)->getData();
                $datasucess = array("application_ids" => $id,
                    "applicantType" => $applicantType,
                    "hashed_application_id" =>$hashed_application_id,
                    "user_details" => $applicationDetails,
                    "fees" => $frontController->getFeesData($application_id, false, true),
                    "kycDetails" => $kycDetails,
                    "text_content" => 'Please complete the payment, KYC and loan agreement signing to receive disbursement of loan for purchase from ' . $applicationDetails->merchant->merchant_name . ' for ₹' . $applicationDetails->approved_amount
                );
                if (isset($applicantType) && $applicantType == '2' && isset($kycDetails->co_applicant)) {
                    if ($kycDetails->co_applicant->kyc_completed && $kycDetails->co_applicant->kyc_status != 'approved') {
                        $coAppData['applicationId'] = $application_id;
                        $coAppData['applicantType'] = $applicantType;
                        $coAppData['hashed_application_id'] = $id;
                        $coAppData['reKYC'] = $kycDetails->co_applicant->kyc_status == 'rejected' ? true : false;
                        return view('admin.kyc_waiting_page', $coAppData);
                    }
                }
                if (!isset($datasucess['fees']['set_auto_debit']) && $datasucess['fees']['payment_details']['Total Payment']['amount']== 0) {
                    if ($kycDetails->applicant->kyc_completed && $kycDetails->applicant->kyc_status != 'approved') {
                        $bladeData['applicationId'] = $application_id;
                        $bladeData['applicantType'] = '1';
                        $bladeData['hashed_application_id'] = $id;
                        $bladeData['reKYC'] = $kycDetails->applicant->kyc_status == 'rejected' ? true : false;
                        return view('admin.kyc_waiting_page', $bladeData);
                    }
                }
                // Hypothecation agreement e-sign
                $consumerDocs = DB::select("select consumer_application_id from consumer_application_files caf where ((caf.file_type = 'pro_forma_invoice' and caf.created_by != 107) or (caf.file_type = 'proforma' and caf.created_by is null)) and consumer_application_id =". $application_id . " and caf.deleted_at is null limit 1");
                if (!empty($consumerDocs)) {
                    $request = new Request();
                    $request->merge(['id' => $application_id]);
                    $hypothecation = new LoanHypothecation($request);
                    $links_data = $hypothecation->getHypothecationLinks();
                    if (isset($links_data)) {
                        return view('front.esign-congrats', array_merge($datasucess, ['links_data' => $links_data]));
                    }
                }
                return view('front.esign-congrats', $datasucess);
            }
            $user_details = ConsumerApplication::where('id', $application_id)->first(['name', 'mobile_number', 'email', 'approved_amount', 'merchant_id', 'loan_amount', 'co_applicant_name','co_applicant_email','co_applicant_mobile_number','offer_id','lender_id','state']);

            if(isset($user_details->lender_id) && $user_details->lender_id == 10){
                $datasucess = array("application_ids" => $id,'lender_id'=>$user_details->lender_id);
                return view('front.esign-congrats', $datasucess);
            }

            # Click wrap sign agreement
            $type = "Loan Agreement Esign";
            $request = new Request();
            $request->request->add(['type'=>$type, 'esign' => true]);
            $consumerDocument = new ConsumerDocument($request);
            $viewParameter = ($consumerDocument->getDocument($application_id));

            if ($viewParameter instanceof RedirectResponse){
                $datasucess = array("application_ids" => 1,"failure"=>"");
                return view('front.esign-failure', $datasucess);
            }

            $mobile_number = $viewParameter['user']['customer_mobile'];
            $co_applicant_mobile_number = $viewParameter['user']['co_applicant_mobile'];
            $co_applicant_name = $viewParameter['user']['co_applicant_name'];
            $preferred_language = $viewParameter['user']['preferred_language'];
            $agreement_version = $viewParameter['user']['agreement_version'];

            $firstName = $viewParameter['user']['customer_name'];
            if($firstName != "") {
                $applicant = array("name" => $firstName, "value" => "1_" . $mobile_number);
            }else{
                $applicant = array();
            }
            if($co_applicant_name != ""){
                $co_applicant = array("name" => $co_applicant_name, "value" => "2_".$co_applicant_mobile_number);
            }else{
                $co_applicant = array();
            }
            $signed_data = DigitalSignDetails::where('application_id',$application_id)->get();
            if(count($signed_data) > 0) {
                foreach ($signed_data as $signdata) {
                    if ($signdata->applicant == 1) {
                        $applicant = array();
                    }
                    if ($signdata->applicant == 2) {
                        $co_applicant = array();
                    }
                }
            }

            if($viewParameter['user']['status'] == "rejected" || $viewParameter['user']['status'] == "aborted"){
                $datasucess = array("application_ids" => $id,"failure"=>$viewParameter['user']['status']);
                return view('front.esign-failure', $datasucess);
            }

            if(count($applicant) == 0 && count($co_applicant) == 0 ){
                return $frontController->digitalsignupdate($id);
            }

            $mandate = Mandate::where('consumer_application_id', $application_id)->whereNotNull('umrn')->where('status', 'active')->first(['umrn', 'status']);
            $kyc_digio =  KYCDetails::where('application_id', $application_id)->whereNull('deleted_at')->orderBy('id', 'desc')->first();
            $userVerified = User::where('mobile_number', $mobile_number)->first(['user_verified']);

            if($viewParameter['user']['merchant_skip_otp'] && (!empty($mandate) || (!empty($kyc_digio) && !empty($kyc_digio->response))  || (!empty($userVerified) && $userVerified->user_verified == 1))){
                $skipOtp = true;
            }else{
                $skipOtp = false;
            }

            $lastName = "";
            $callbackURL = asset("esignupdate/id/".$id);
            $opendatetime = date('Y-m-d H:i:s');
            return view('front.digitalpdf',['https' => 'http',
                                            'applicant'=>$applicant,
                                            'co_applicant'=>$co_applicant,
                                            'co_applicant_mobile_number'=>$co_applicant_mobile_number,
                                            'co_applicant_name'=>$co_applicant_name,
                                            'customer_mobile' => $mobile_number,
                                            'opendatetime'=>$opendatetime,
                                            'user'=>$viewParameter['user'],
                                            'lender' => $viewParameter['lender'],
                                            'id'=>$application_id,'hasdid'=>$id,'data'=>$viewParameter['data'],
                                            'pdf'=>0, 'is_pdf'=>1,'preferred_language'=>$preferred_language,
                                            'agreement_version'=>$agreement_version, 'skipOtp'=>$skipOtp, 
                                            'combined_sl_la'=>$viewParameter['combined_sl_la'],
                                            'is_bnpl'=>$viewParameter['application']->application_element->is_bnpl, 
                                            'application'=>$viewParameter['application']]);
        } catch (\Exception $e) {
            $this->cloudwatchLogger->logger(json_encode(['title' => 'Post Approval Link', 'application id' => $id, 'message' => $e->getMessage(), 'line' => $e->getLine(), 'trace' => $e->getTraceAsString()]));
            return redirect()->to('/404');
        }
    }

    public function checkKYCStatus($applicationId) {
        $application = DB::select("select co_applicant_name from consumer_application where id = " . $applicationId);
        $applicant = [
            'kyc_completed' => false,
            'kyc_status' => null
        ];
        if (!empty($application[0]->co_applicant_name)) {
            $co_applicant = [
                'kyc_completed' => false,
                'kyc_status' => null
            ];
        }
        $karzaKYCRecords = KarzaVideoAttribute::where('application_id', $applicationId)
            ->whereIn('applicant_type', [1, 2])
            ->orderBy('id', 'desc')
            ->get(['id']);
        $digioKYCDetails = DigioVKYC::where('application_id', $applicationId)->get(['id', 'kyc_journey', 'kyc_status', 'applicant_type']);
        if (count($karzaKYCRecords) > 0) {
            foreach ($karzaKYCRecords as $karzaRecord) {
                $customer_webhook = KarzaVideoWebhook::where('karza_id', $karzaRecord->id)->get(['data', 'applicant_type']);
                if(!empty($customer_webhook)){
                    foreach ($customer_webhook as $key => $value) {
                        $kyc_data = json_decode($value->data);
                        if (isset($kyc_data->approvedByAgent) && $kyc_data->approvedByAgent == "ACCEPTED") {
                            // $applicantType = substr($kyc_data->customerId, -1);
                            if ($value->applicant_type == 1) {
                                $applicant['kyc_completed'] = true;
                            } else {
                                $co_applicant['kyc_completed'] = true;
                            }
                        }
                        if (isset($kyc_data->approvedByAuditor) && $kyc_data->approvedByAuditor == "ACCEPTED") {
                            // $applicantType = substr($kyc_data->customerId, -1);
                            if ($value->applicant_type == 1) {
                                $applicant['kyc_status'] = 'approved';
                            } else {
                                $co_applicant['kyc_status'] = 'approved';
                            }
                        }
                        if (isset($kyc_data->approvedByAuditor) && $kyc_data->approvedByAuditor == "REJECTED") {
                            // $applicantType = substr($kyc_data->customerId, -1);
                            if ($value->applicant_type == 1) {
                                $applicant['kyc_status'] = 'rejected';
                            } else {
                                $co_applicant['kyc_status'] = 'rejected';
                            }
                        }
                    }
                }
            }
        }
        if (count($digioKYCDetails) > 0) {
            foreach ($digioKYCDetails as $digioData) {
                if ($digioData->kyc_journey == 'complete') {
                    if ($digioData->applicant_type == 1) {
                        $applicant['kyc_completed'] = true;
                        $applicant['kyc_status'] = $digioData->kyc_status; // confirm if null is to be considered as rejected
                    } else {
                        $co_applicant['kyc_completed'] = true;
                        $co_applicant['kyc_status'] = $digioData->kyc_status;
                    }
                }
            }
        }
        if (isset($co_applicant)) {
            return \response()->json([
                'status' => 'OK',
                'applicant' => $applicant,
                'co_applicant' => $co_applicant
            ], 200);
        }
        return \response()->json([
            'status' => 'OK',
            'applicant' => $applicant
        ], 200);
    }
}