<?php
/**
 * Created by PhpStorm.
 * User: mindu
 * Date: 17/8/18
 * Time: 11:05 AM
 */
namespace App\Http\Controllers\Service;

use App\ConsumerApplicationElement;
use App\ConsumerApplicationFiles;
use App\Http\Controllers\Admin\ConsumerApplicationController;
use App\Http\Controllers\Admin\DisbursementController;
use App\Http\Controllers\Admin\EMICalculation;
use App\ConsumerApplication;
use App\Http\Controllers\ApiController;
use App\Http\Controllers\Controller;
use App\JMService\JMServices;
use App\JWTAccess;
use App\KMGP2P;
use App\Merchant;
use App\MerchantOffers;
use App\PWAApplicationForm;
use App\Slack;
use App\CreditReport;
use App\SMSLogs;
use App\StatusLogs;
use App\User;
use App\Utkarsh\Utkarsh;
use App\Vivriti;
use Carbon\Carbon;
use Hashids\Hashids;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Grade\GradeController;
use App\Http\Controllers\Admin\ConsumerDocument;
use Illuminate\Support\Facades\App;
use App\Logging\CloudWatchLoggerFactory;
use App\Http\Controllers\TestingController;
use App\DigitalSignDetails;
use App\JobProvider;
use Illuminate\Support\Facades\Storage;

class ServiceController extends Controller
{

    /**
     * @var Request
     */
    private $request;
    private $groups = [
        'BIRLA IVF + CREDITFAIR' => 7656, 
        'Indira IVF grp Credit Fair' => 8, 
        'Personal' => 7062, // 1 for testing with pratik merchant whole moving to prod should move to 73 for GDS Trader
        'Team Kapil Credit fair' => 6485, 
        'Nova - varansi + Creditfair' => 4830, 
        'Creditedfire - Progenesis Thane' => 5408, 
        'Creditfair - Progenesis Pune' => 5408, 
        'Creditfair+ smiles.ai' => 7557, 
        'CF-New Roots Hair Clinic' => 5453, 
        'RAYS RENEWABLE ENERGY- CREDITFAIR-8726' => 8726,
        'Watersun Electricals <> Credit Fair - 8448' => 8448, 
        'TRIPURA ENETERPRISES - CREDITFAIR- 8305' => 8305, 
        'Vide Energy-Credit Fair' => 8451,
        'Credit Fair -Freyr Energy - 6613' => 6613,
        'OSMIUM ENERGY- CREDIT FAIR - 8764' => 8764,
        'Atria Power <> Credit Fair - 8723' => 8723,
        'Credit Far - MYSUN - 6668' => 6668,
        'ZUNROOF TECH PRIVATE LIMITED - CREDIT FAIR - 8214' => 8214,
        'Madathil-Redington-Creditfair - 7189' => 7189,
        'Credit Fair<>Spectra Televentures - 8657' => 8657,
        'Credit Fair - Loom Solar - 6977' => 6977,
        'GSR Renewable Energy LIP <> Credit Fair - 9335' => 9335,
        'Balani Agencies (Luminous Merchant) - 8554' => 8554,
        'Solarium (Delhi) - CF - 7432' => 7432,
        'Macrocosm Capital Cleanpe<> Credit Fair - 8927' => 8927,
        'Solaron HomesO Credit fair - 7511' => 7511,
        'ORBIT CREDIT FAIR LOANS - 7028' => 7028,
        'Solar Ladder <> Credit Fair - 8308' => 8308,
        'CF X SSE Eligibility Checks - 6601' => 6601,
        'Emissions Free World <> Credit Fair - 8920' => 8920,
        'Watersun Electricals <> Credit Fair - 8448' => 8448,
        'Credit Fair - Simandhar Education - 49' => 49,
        'Credit Fair <> IIMT Studies (Domestic Team) - 9413' => 9413,
        'IIDE <> Credit Fair - 3869' => 3869,
        'CATKing<>Credit Fair EMI - 6110' => 6110,
        'Imarticus Noida + Credit Fair - 6462' => 6462,
        'MCTA - Credit Fair EMI - 4796' => 4796,
        'Ficusoft <> Credit Fair - 7106' => 7106,
        'CF-Labelle bangalore/TN - 5098' => 5098,
        'Creditfair<> SymBroj Solar - 7052' => 7052,
        'Credit Fair<>Spectra Televentures' => 8657,
        'ZUNROOF TECH PRIVATE LIMITED - CREDIT FAIR' => 8214,
        'Ram Raja Solar - CF' => 7654,
        'Roofsol AP - Credit Fair' => 9352,
        'RAYS RENEWABLE ENERGY- CREDITFAIR' => 8726,
        'Praveg Solar + Credit Fair' => 7862,
        'SSE × CF internal' => 6601,
        'APS RT - Credit Fair Loan' => 7680,
        'SOLAR HOUSE - CREDITFAIR' => 9565,
        'Credit Fair - Truzon (AP)' => 9727,
        'MIRVIC ENTERPRISES (INDIA) PRIVATE LIMITED - CREDIT FAIR' => 9617,
        'Punarvi Projects  - Creditfair' => 8234,
        'SUNCITY SOLAR - CREDIT FAIR' => 9581,
        'Capital crafts <> CF (End customer financing)' => 9378,
        'Rural Green Energy // Credit Fair' => 10014,
        'Rudraksha Enterprises -- Credit fair' => 10032
    ];
        /**
     * @var array
     */
    private $parsedData = [];
    /**
     * @var false
     */
    private $user;

    public function __construct(Request $request){
        $this->request = $request;
    }

    public function getBureauData()
    {
        return $this->request->all();
    }

    public function getOffers(){
        $emiCalculation = new EMICalculation($this->request);
        $emiCalculation->merchant_id = $this->request->get('merchant_id');
        $emiCalculation->product_id = explode(',', $this->request->get('product_id'));
        $emiCalculation->loan_amount = $this->request->get('loan_amount');
        return response()->json(['status' => 'OK', 'data' => $emiCalculation->getEMIsByMerchant()]);
    }

    public function runAutoDecision(Request $request)
    {
        try {

            $application_id = $request->query('application_id');
            $hashids = new Hashids('Creditfair by CS', 20);
            $application_unhashed_id = $hashids->decode($application_id);
            $grade = new GradeController($request);
            // $__grade = $grade->ApprovalCheckV1($application_unhashed_id);
            // $_grade = $__grade->getOutput();

            (new Slack(new Request(['title' => 'Run auto decision API', 'fields' => ['application_id' => $application_unhashed_id[0]], 'group' => Slack::$STAGE_TESTING])))->send();
            $applicationDetails = ConsumerApplication::with('merchant', 'creditReport')->where('id', $application_unhashed_id[0])->first();
            $tableOfOffers = $applicationDetails->merchant->table_of_offers ?? false;
            if (count($applicationDetails->creditReport) > 0) {
                $is_bureau_generated = $applicationDetails->creditReport[0]->id;
            }

            if (!$tableOfOffers) {
                $this->updateStatus($application_unhashed_id[0], 'waiting for decision');
                return response()->json(['status' => 'OK', 'message' => 'Not Approved']);
            }
            if (isset($is_bureau_generated)) {

                $request['id'] = $application_unhashed_id[0];
                $gradeController = new GradeController($request);
                $_grade = $gradeController->ApprovalCheckV2($request->get('id'));

//                try {
//                    $approvalStatus = $_grade->getOutput();
//                    PWAApplicationForm::approvalLog($approvalStatus, $request->get('id'), '');
//                }catch (\Exception $ex){
//
//                }

//                $isApproved = empty(array_filter($approvalStatus));

//                PWAApplicationForm::approvalLog($approvalStatus, $request->get('id'), '');
                (new Slack(new Request(['title' => 'saveDecisionTable API', 'fields' => ['application_id' => $application_unhashed_id[0]], 'group' => Slack::$STAGE_TESTING])))->send();
                $approvalStatus = $gradeController->saveDecisionInTable($_grade);
                if ($approvalStatus) {
                    $this->updateStatus($request->get('id'), 'cf approved');
                    return response()->json(['status' => 'OK', 'message' => 'Approved']);
                }
                else if($gradeController->autoReject($_grade, $request->get('id'))){
                    $this->updateStatus($request->get('id'), 'rejected');
                    return response()->json(['status' => 'OK', 'message' => 'Rejected']);
                }
                else {
                    $this->updateStatus($request->get('id'), 'waiting for decision');
                    return response()->json(['status' => 'OK', 'message' => 'Not Approved']);
                }
            }else{
                return response()->json(['status' => 'OK', 'message' => 'Bureau not generated']);

            }
        } catch (\Exception $e) {
            return response()->json(['status' => 'OK', 'message' => 'Exception occurred while running auto decesion']);

            (new Slack(new Request(['title' => 'Run auto decision API', 'group' => Slack::$STAGE_TESTING])))->send();

        }
    }

    public function updateStatus($id, $status){
        $consumer_application = ConsumerApplication::find($id);
        $consumer_application->state = $status;
        if($status == 'rejected') {
            $consumer_application->approved_amount = 0;
        }
        $consumer_application->save();
        StatusLogs::insert([
            'application_id' => $id,
            'user_id' => 107,
            'status' => $status,
            'created_at' => Carbon::now()->toDateTimeString()
        ]);
    }

    public function getAgreement(Request $request)
    {
        try {
            $application_id = $request->query('application_id');
            $type = $request->query('type');

            $hashids = new Hashids('Creditfair by CS', 20);
            $application_unhashed_id = $hashids->decode($application_id);

            $request->merge(['type' => 'Loan Agreement']);

            $consumerdocument = new ConsumerDocument($request);
            $__consumerdocument = $consumerdocument->getDocument($application_unhashed_id[0]);
            $data = $__consumerdocument->getData();
            $snappypdf = App::make('snappy.pdf.wrapper');
            $snappypdf->setOption("footer-right", "Page [page] from [topage]");
            $snappypdf->setOption('footer-font-size',10);
            $snappypdf->setOption('margin-bottom', 30);
            $snappypdf->setOption('footer-html', view('admin.editor.footer',['type'=>"Loan Agreement Esign",'lender'=> $__consumerdocument['lender']])->render());
            // $snappypdf->setTemporaryFolder(storage_path()."/")->setOption("enable-local-file-access", true);

            if ($data['lender']['id'] == \App\Avanse\Services\AvanseServices::$lender_id) {
                $view = view('admin.documents.avanse.loan_agreement_v2', $data)->render();
                if ($type == 'pdf') {
                    $pdfView = base64_encode($snappypdf->loadHTML($view)->output());
                    return response()->json(['status' => 'OK', 'message' => $pdfView]);
                }
                return response()->json(['status' => 'OK', 'message' => $view]);
                // return $view;
            } elseif ($data['lender']['id'] == \App\ABFL\Services\Services::$lender_id) {
                $pdf = 1;
                $data['pdf'] = $pdf;
                $view = view('admin.documents.abfl.combine_loan_agreement', $data)->render();
                if ($type == 'pdf') {
                    $pdfView = base64_encode($snappypdf->loadHTML($view)->output());
                    return response()->json(['status' => 'OK', 'message' => $pdfView]);
                }
                return response()->json(['status' => 'OK', 'message' => $view]);
                // return $view;
            } elseif ($data['lender']['id'] == JMServices::$lender_id) {
                $pdf = 1;
                $snappypdf->setOption('header-html', (new ConsumerDocument($request))->getPDFHeaderView());
                $data['pdf'] = $pdf;
                $view = view('admin.documents.jm.loan_agreement_v2', $data)->render();
                if ($type == 'pdf') {
                    $pdfView = base64_encode($snappypdf->loadHTML($view)->output());
                    return response()->json(['status' => 'OK', 'message' => $pdfView]);
                }
                return response()->json(['status' => 'OK', 'message' => $view]);
                // return $view;
            } elseif ($data['lender']['id'] == Utkarsh::$lender_id) {
                $pdf = 1;
                $snappypdf->setOption('header-html', (new ConsumerDocument($request))->getPDFHeaderView(Utkarsh::$lender_id));
                $data['pdf'] = $pdf;
                $view = view('admin.documents.utkarsh.loan_agreement_v3', $data)->render();
                if ($type == 'pdf') {
                    $pdfView = base64_encode($snappypdf->loadHTML($view)->output());
                    return response()->json(['status' => 'OK', 'message' => $pdfView]);
                }
                return response()->json(['status' => 'OK', 'message' => $view]);
                // return $view;
            } elseif ($data['lender']['id'] == Vivriti::$lender_id) {
                $pdf = 1;
                $data['pdf'] = $pdf;
                $view = view('admin.documents.vivriti.loan_agreement_v2', $data)->render();
                if ($type == 'pdf') {
                    $pdfView = base64_encode($snappypdf->loadHTML($view)->output());
                    return response()->json(['status' => 'OK', 'message' => $pdfView]);
                }
                return response()->json(['status' => 'OK', 'message' => $view]);
                // return $view;
            } elseif ($data['lender']['id'] == KMGP2P::$lender_id) {
                $pdf = 1;
                $data['pdf'] = $pdf;
                $view = view('admin.documents.kmgp2p.borrower_agreement', $data)->render();
                if ($type == 'pdf') {
                    $pdfView = base64_encode($snappypdf->loadHTML($view)->output());
                    return response()->json(['status' => 'OK', 'message' => $pdfView]);
                }
                return response()->json(['status' => 'OK', 'message' => $view]);
                // return $view;
            } elseif ($data['lender']['id'] == \App\LendBox::$lender_id) {
                $pdf = 1;
                $data['pdf'] = $pdf;
                $view = view('admin.documents.lendbox.borrower_agreement', $data)->render();
                if ($type == 'pdf') {
                    $pdfView = base64_encode($snappypdf->loadHTML($view)->output());
                    return response()->json(['status' => 'OK', 'message' => $pdfView]);
                }
                return response()->json(['status' => 'OK', 'message' => $view]);
                // return $view;
            } elseif ($data['is_bnpl']) {
                $view = view('admin.documents.bnpl.service_agreement', $data)->render();
                if ($type == 'pdf') {
                    $pdfView = base64_encode($snappypdf->loadHTML($view)->output());
                    return response()->json(['status' => 'OK', 'message' => $pdfView]);
                }
                return response()->json(['status' => 'OK', 'message' => $view]);
                // return $view;
            } else {
                if ($data['user']['agreement_version'] == 2) {
                    if ($data['lender']['id'] == 2) {
                        $pdf = 1;
                        $data['pdf'] = $pdf;
                        $view = view('admin.documents.borrower_loan_agreement_esign_v_two_v2', $data)->render();
                        if ($type == 'pdf') {
                            $pdfView = base64_encode($snappypdf->loadHTML($view)->output());
                            // $snappypdf->setOption("footer-right", "Page [page] from [topage]");
                            // $snappypdf->setOption('footer-font-size',10);
                            // $snappypdf->setOption('margin-bottom', 30);
                            // $snappypdf->setOption('footer-html', view('admin.editor.footer',['type'=>"Loan Agreement Esign",'lender'=> $__consumerdocument['lender']])->render());
                            return response()->json(['status' => 'OK', 'message' => $pdfView]);
                        }
                        return response()->json(['status' => 'OK', 'message' => $view]);
                        // return $view;
                    } else {
                        $view = view('admin.documents.borrower_loan_agreement_esign_v_two', $data)-> render();
                        if ($type == 'pdf') {
                            $pdfView = base64_encode($snappypdf->loadHTML($view)->output());
                            return response()->json(['status' => 'OK', 'message' => $pdfView]);
                        }
                        return response()->json(['status' => 'OK', 'message' => $view]);
                        // return $view;
                    }
                } else {
                    $view = view('admin.documents.borrower_loan_agreement', $data)->render();
                    if ($type == 'pdf') {
                        $pdfView = base64_encode($snappypdf->loadHTML($view)->output());
                        return response()->json(['status' => 'OK', 'message' => $pdfView]);
                    }
                    return response()->json(['status' => 'OK', 'message' => $view]);
                    // return $view;
                }
            }


        } catch (\Exception $e) {
            $cwFactory = new CloudWatchLoggerFactory();
            $cwFactory->logger(json_encode(['application_id' => $application_unhashed_id, 'message' => $e->getMessage(), 'line' => $e->getLine(), 'trace' => $e->getTraceAsString()]));
        }
    }

    public function signAgreement(Request $request) {
        try {
            $application_id = $request->get('application_id');
            $load_time = $request->get('load_time');
            $click_time = $request->get('click_time');
            $hashids = new Hashids('Creditfair by CS', 20);
            $application_unhashed_id = $hashids->decode($application_id);
            $isExist = DigitalSignDetails::where('application_id', $application_unhashed_id[0])->where('applicant', 1)->first(['id']);
            if (!isset($isExist)) {
                $digital_sign = new DigitalSignDetails();
                $digital_sign->application_id = $application_unhashed_id[0];
                $digital_sign->applicant = 1;
                $digital_sign->load_time = date('Y-m-d H:i:s',strtotime($load_time));
                $digital_sign->click_time = date('Y-m-d H:i:s',strtotime($click_time));
                $digital_sign->isaddress =  'UNKNOWN';
                $digital_sign->isagreementsigned = 1;
                $digital_sign->language = 'ENGLISH';
                $digital_sign->type = "consumer";
                $digital_sign->save();
                $agreementsigning = (new TestingController())->generateEsignLoanAgreement($application_unhashed_id[0]);
                if ($agreementsigning == true) {
                    // $payload = [
                    //     'payload' => json_encode(array_merge(['id' => $application_unhashed_id[0], 'status' => 'approved', 'previous_status' => 'cf approved', 'auth_user_id' => 107, 'lender_id' => 2, "residing" => "0", "linkedin" => "", "facebook" => "", "tele_verification" => "0", "contact" => "", "address_document_mapping_permanent_address" => "", "address_document_mapping_current_address" => "", "product_verification" => "0", "product_verification_reason" => "", "next_status" => "Approved", "exception_doc_list" => "[]", "approved_reason_list" => ""])),
                    //     'from' => 'statusChange',
                    //     'application_id' => $application_unhashed_id[0],
                    //     'available_at' => Carbon::now()->toDateTimeString(),
                    //     'created_at' => Carbon::now()->toDateTimeString()
                    // ];
                    $payload = [
                        'payload' => json_encode(array_merge(['id' => $application_unhashed_id[0], 'status' => 'approved', 'previous_status' => 'cf approved', 'auth_user_id' => 107, 'lender_id' => 2, "documents" => "[pro_forma_invoice, sanction_letter]"])),
                        'from' => 'emiCheckoutGenerateDocuments',
                        'application_id' => $application_unhashed_id[0],
                        'available_at' => Carbon::now()->toDateTimeString(),
                        'created_at' => Carbon::now()->toDateTimeString()
                    ];
                    JobProvider::insert($payload);
                    return response()->json(['status' => 'OK', 'message' => 'Agreement Signed Successfully']);
                }
                return response()->json(['status' => 'FAIL', 'message' => 'Agreement Signed Failed']);
            } else {
                return response()->json(['status' => 'OK', 'message' => 'Agreement Already Signed']);
            }

        } catch (\Exception $e) {
            $cwFactory = new CloudWatchLoggerFactory();
            $cwFactory->logger(json_encode(['application_id' => $application_unhashed_id, 'message' => $e->getMessage(), 'line' => $e->getLine(), 'trace' => $e->getTraceAsString()]));
        }
    }

    public function getLink(){
        $this->user = $this->getUser();
        if (!$this->user){
            return response()->json(['id' => 0, 'message' => 'Unauthorized'], 401);
        }
        $id = $this->request->get('application_id');
        try {
            $data = [];
            if ($this->request->get('link_type') == "esign_link" && $this->request->get('application_id')) {
                $esignLink = (new ConsumerDocument($this->request))->getEsignLink($id);
                $data['link'] = $esignLink['esign'];
            } else if ($link = $this->getLinkByType($id, $this->request->get('link_type'))) {
                $data['link'] = $link;
            }

            if (!isset($data['link']) && (isset($data['link']) && empty($data['link']))) {
                $id = 0;
                $message = "Application Id or Data is incorrect";
            } else {
                $message = $this->request->get('link_type') . ": " . $data['link'];
            }
        }catch (\Exception $e){
            $message = "Application Id or Data is incorrect";
            $id = 0;
        }

        return response()->json(['id' => $id, 'message' => $message], 200);
    }

    public function getLinkByType($id, $link_type){

        $user = ConsumerApplication::with('proFormaInvoice', 'lender', 'emi', 'merchant', 'activeOffer')->where('id', $id)->first(['id', 'approved_amount', 'merchant_id', 'offer_id', 'lender_id', 'name', 'mobile_number', 'email', 'co_applicant_name', 'co_applicant_mobile_number', 'co_applicant_email', 'state']);

        if(!isset($user->id)){
            return false;
        }

        $application = new ConsumerApplicationController();
        $disbursementController = new DisbursementController($this->request);
        if ($link_type == "processing_fee_link" && isset($user->emi->processing_fee) && $user->emi->processing_fee > 0) {
            $process['proFormaInvoice'] = $user->proFormaInvoice;
            $process['processing_fee_first_emi'] = $user->activeOffer->processing_fee_first_emi ?? '';
            $process['merchant_processing_collected'] = isset($user->merchant->is_collected) && $user->merchant->is_collected == 1 ? $user->merchant->is_collected : (isset($user->proFormaInvoice) && $user->proFormaInvoice->processing_fee_by_merchant == 1 ? $user->proFormaInvoice->processing_fee_by_merchant : 0);
            if ((new ConsumerDocument($this->request))->isProcessingFeeCollected($process)) {
                if (!($application)->isProcessingFeeApplicable($user->id)) {
                    $processingFeeData = $process;
                    $processingFeeData['lender'] = $user->lender;
                    return $application->sendProcessingFeeLink($processingFeeData, $user);
                }
            }
        }else if ($link_type == 'insurance_link' && $insurance_fee_amount = $disbursementController->isCustomerPayingInsuranceFee($user)) {
            return $application->sendInsuranceFeeLink($insurance_fee_amount, $user);
        }else if ($link_type == 'advance_payment_link' && $cf_advance_amount = $disbursementController->isCFCollectingAdvance($user)) {
            return $application->sendAdvanceAmountLink($cf_advance_amount, $user);
        }

        return false;
    }

    public function createLoan() {
        $this->user = $this->getUser();
        if (!$this->user) {
            return response()->json(['id' => 0, 'message' => 'Unauthorized'], 401);
        }

        $application_id = $this->request->has('application_id') ? $this->request->get('application_id') : null;

        $isUpdateRequest = isset($application_id) && $application_id != "" ? true : false;

        $this->bodyParser();
        $this->loadAdditionalAttributes($isUpdateRequest);
        $this->simplyAttributes();

        if (!$this->parsedData['merchant_id']) {
            return response()->json(['id' => 0, 'message' => 'Merchant not found, Please whitelist the merchant'], 200);
        }

        if (isset($this->parsedData['inverter_kw_installation'])) {
            $calpowersaving = $this->parsedData['inverter_kw_installation'] * 1000;
            $this->parsedData['inverter_power_savings'] = $calpowersaving;
        }

        if ($isUpdateRequest) {

            // Updating Existing Application
            if ((new ApiController())->checkEligibility(new Request([
                'pan' => $this->request->get('pan_card'),
                'email' => $this->request->get('email'),
                'mobile_number' => $this->request->get('mobile_number')
            ]))) {
                return response()->json(['id' => 0, 'message' => 'Duplicate Customer found'], 200);
            }
            $application = ConsumerApplication::find($application_id);

            if (!$application) {
                return response()->json(['id' => 0, 'message' => 'Application not found'], 404);
            }

            $allowedStatuses = ['form completed', 'in-process', 'waiting for documents','incomplete form'];
            if (!in_array(strtolower($application->state), $allowedStatuses)) {
                return response()->json([
                    'id' => $application->id,
                    'message' => "Cannot update application in status: {$application->state}"
                ], 400);
            }
            $application->fill($this->parsedData);
            $application->save();

            $applicationElement = ConsumerApplicationElement::where('application_id', $application->id)->first();
            if (!$applicationElement) {
                $applicationElement = new ConsumerApplicationElement();
                $applicationElement->application_id = $application->id;
            }

            if ($elementAttributes = $this->getPropertiesForElement($applicationElement->fillable)) {
                $applicationElement->fill($elementAttributes);
            }
            $applicationElement->save();

            $missingFields = $this->checkMandatoryFields($application->id);
            if($missingFields == '') {
                $application->state = 'form completed';
                $application->save();
                $message = "Application updated successfully with id: " . $application->id . " \n\n Thank you \n " . $missingFields;
            } else {
                $message = "Application updated successfully with id: " . $application->id . " \n\n Please provide the following fields to proceed \n " . $missingFields;
            }

            return response()->json(['id' => $application->id, 'message' => $message], 200);

        } else {

            // Creating New Application
            if ((new ApiController())->checkEligibility(new Request([
                'pan' => $this->request->get('pan_card'),
                'email' => $this->request->get('email'),
                'mobile_number' => $this->request->get('mobile_number')
            ]))) {
                return response()->json(['id' => 0, 'message' => 'Duplicate Customer found'], 200);
            }

            $application = new ConsumerApplication();
            $application->fill($this->parsedData);
            $application->save();

            $applicationElement = new ConsumerApplicationElement();
            $this->parsedData['application_id'] = $application->id;
            $elementProperties = [];

            if ($elementAttributes = $this->getPropertiesForElement($applicationElement->fillable)) {
                $elementProperties = array_merge($elementProperties, $elementAttributes);
            }
            $applicationElement->fill($elementProperties);
            $applicationElement->save();
            $missingFields = $this->checkMandatoryFields($application->id);
            if($missingFields == '') {
                $application->state = 'form completed';
                $application->save();
                $message = "Application created successfully with id: " . $application->id . " \n\n Thank you \n " . $missingFields;
            } else {
                $message = "Application created successfully with id: " . $application->id . " \n\n Please provide the following fields to proceed \n " . $missingFields;
            }
            return response()->json(['id' => $application->id, 'message' => $message], 200);
        }
    }


    public function getPropertiesForElement($fillable){
        $element_properties = [];
        foreach($this->parsedData as $key => $value) {
            if (in_array($key, $fillable)){
                $element_properties[$key] = $value;
            }
        }

        return $element_properties;
    }

    public function uploadDocumentBase(){
        $this->user = $this->getUser();
        if (!$this->user){
            return response()->json(['id' => 0, 'message' => 'Unauthorized'], 401);
        }
        $s3 = Storage::disk('s3');

        $file = base64_decode($this->request->get('image')[0]['base64']);
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mimeType = finfo_buffer($finfo, $file);

        $mimeToExtension = [
            'image/jpeg' => 'jpg',
            'image/png' => 'png',
        ];

        $extension = isset($mimeToExtension[$mimeType]) ? $mimeToExtension[$mimeType] : '';
        if (empty($extension)) {
            preg_match('/^data:image\/(\w+);base64,/', $file, $matches);
            $extension = isset($matches[1]) ? $matches[1] : '';
        }

        $path = '/' . $this->request->get('application_id') . '/' . $this->request->get('doc_type') . '.' . $extension;

        $s3->put($path, $file);

        $consumer_application_file = new ConsumerApplicationFiles();
        $consumer_application_file->consumer_application_id = $this->request->get('application_id');
        $consumer_application_file->file_type = $this->request->get('doc_type');
        $consumer_application_file->bank_name = '';
        $consumer_application_file->password = '';
        $consumer_application_file->accounttype = '';
        $consumer_application_file->statementtype = '';
        $consumer_application_file->statemenfilettype = '';
        $consumer_application_file->customer_id = '';
        $consumer_application_file->provider = '';
        $consumer_application_file->finbit_analysis_date = '';
        $consumer_application_file->bp_number = '';
        $consumer_application_file->accountUID = '';
        $consumer_application_file->file_path = $path;
        $consumer_application_file->created_by = $this->user;
        $consumer_application_file->image_score = '';
        $consumer_application_file->m_generated = 1;
        $consumer_application_file->applicant_type = 1;
        $consumer_application_file->bureau_report_type = '';
        $consumer_application_file->bureau_report_score = '';
        $consumer_application_file->is_masked = 0;
        $consumer_application_file->save();

        return response()->json(['id' => $this->request->get('application_id'), 'message' => ucfirst(strtolower($this->request->get('doc_type')))." Document received"], 200);
    }

    public function generateOTP(){
        try {
            $api = new ApiController();
            \request()->merge(['mp' => $this->request->get('mobile')]);
            $data = $api->checkStatusLogin();
            $api->isSystemByPass = true;
            $res = $data->getData();
            return response()->json(['id' => $res->status == 'OK' ? 1 : 0, 'message' => $res->error ?? ''], 200);
        }catch (\Exception $e){
            return response()->json(['id' => 0, 'message' => 'Something went wrong'], 200);
        }
    }

    public function checkMandatoryFields($application_id)
    {
        // Map display name => column name
        $mandatoryFields = [
            'Name' => 'name',
            'Gender' => 'gender',
            'Pan Number' => 'pan_card',
            'Loan Amount' => 'loan_amount',
            'DOB' => 'dob',
            'Mobile number' => 'mobile_number',
            'Monthly Income' => 'monthly_income',
            'Merchant' => 'merchant_id',
            'Tenure' => 'tenure',
            'Main Purpose category' => 'purpose',
            'Solar financing for' => 'type_of_customer',
            'Solar power type' => 'solar_power_type',
            'Net loan amount' => 'loan_amount',
            'Permanent Address Line 1' => 'permanent_address_line_1',
            'Permanent City' => 'permanent_address_city',
            'Permanent Pincode' => 'permanent_address_pincode',
            'Permanent State' => 'permanent_address_state',
            'Main Purpose category' => 'purpose',
            'KW installation' => 'inverter_KW_installation',
        ];

        // Fetch application row
        $application = DB::table('consumer_application')
            ->where('id', $application_id)
            ->first();

        // Fetch application element row (if exists)
        $applicationElement = DB::table('consumer_application_element')
            ->where('application_id', $application_id)
            ->first();

        $missingFields = [];

        foreach ($mandatoryFields as $label => $column) {
            $value = null;

            // Check in applications first
            if ($application && property_exists($application, $column)) {
                $value = $application->$column;
            }

            // If not found there, check in application_element
            if ((is_null($value) || $value === '') && $applicationElement && property_exists($applicationElement, $column)) {
                $value = $applicationElement->$column;
            }

            // If still null/empty => add to missing fields
            if (is_null($value) || $value === '') {
                $missingFields[] = $label;
            }
        }

        $missingFieldsString = implode(", \n", $missingFields);
        if (empty($missingFieldsString)) {
            return "";
        }
        return $missingFieldsString;
    }

    public function verifyOTP(){
        $api = new ApiController();
        $response = $api->verifyOtp(new Request(['mobile_number' => $this->request->get('mobile'), 'otp' => $this->request->get('otp'), 'page_lp_event' => true]));
        if ($response->getData()->message == 'OTP successfully verified') {
            return response()->json(['id' => 1, 'message' => 'verified'], 200);
        }
        return response()->json(['id' => 0, 'message' => 'failed'], 200);
    }

    public function getUser(){
        if ($this->request->get('user_identifier')){
            $user = User::where('mobile_number', $this->request->get('user_identifier'))->where('user_type', '>=', 5)->first(['id']);
            return $user->id ?? false;
        }
        return false;
    }

    public function bodyParser(){
        $this->parsedData = [];
        // $attributes = [
        //     'name' => ['pt name', 'applicant name', 'name', 'Applicant Name'], 'loan_amount' => ['loan_amount', 'amount', 'loan amount'], 'mobile_number' => ['number', 'pt number', 'mobile', 'contact number', 'Mobile No', 'Mobile number'], 'merchant_id' => ['merchant_id'],
        //     'monthly_income' => ['salary', 'monthly income', 'Monthly Income'], 'company_name' => ['company name'], 'email' => ['email', 'mail', 'email id', 'Mail id'], 'dob' => ['dob', 'date of birth'],
        //     'mother_name' => ['mother_name', 'Mother name'], 'Spouse_name' => ['spouse Name', 'spouse_name'], 'tenure' => ['Tenure']
        // ];
        $attributes = [
            // --- Personal & Contact Details ---
            'name' => ['name', 'applicant name', 'Applicant Name', 'full name', 'pt name'],
            'email' => ['email', 'mail', 'email id', 'Mail id', 'email address'],
            'mobile_number' => ['mobile_number', 'mobile', 'number', 'contact number', 'Mobile No', 'Mobile number', 'pt number'],
            'dob' => ['dob', 'date of birth', 'birth date'],
            'gender' => ['gender'],
            'marital_status' => ['marital_status', 'marital status'],
            'pan_card' => ['pan_card', 'pan', 'pan number', 'PAN'],
            'aadhaar_card' => ['aadhaar_card', 'aadhaar', 'aadhaar number', 'Aadhaar'],
            'alt_contact_number' => ['alt_contact_number', 'alternate contact', 'alternate number', 'secondary number'],
            'mother_name' => ['mother_name', 'Mother name', 'mother\'s name'], // From your example

            // --- Loan & Merchant Details ---
            'merchant_id' => ['merchant_id', 'merchant id'],
            'loan_amount' => ['loan_amount', 'amount', 'loan amount', 'requested amount'],
            'tenure' => ['tenure', 'Tenure', 'loan tenure', 'repayment period', 'emi months'],
            'purpose' => ['purpose', 'loan purpose', 'category'],
            'approved_amount' => ['approved_amount', 'approved amount', 'sanctioned amount'],
            'lender_id' => ['lender_id', 'lender id'],
            'offer_id' => ['offer_id', 'offer id'],

            // --- Employment & Income Details ---
            'monthly_income' => ['monthly_income', 'monthly income', 'Monthly Income', 'salary', 'income'],
            'company_name' => ['company_name', 'company name', 'employer', 'employer name'],
            'employee_status' => ['employee_status', 'employment status', 'employment type'],
            'company_number' => ['company_number', 'company contact', 'office number', 'company phone'],
            'experience' => ['experience', 'work experience', 'total experience'],

            // --- Address Details (Current) ---
            'current_address_line_1' => ['current_address_line_1', 'current address', 'address', 'address line 1'],
            'current_address_state' => ['current_address_state', 'current state', 'state'],
            'current_address_city' => ['current_address_city', 'current city', 'city'],
            'current_address_pincode' => ['current_address_pincode', 'current pincode', 'pincode', 'zipcode'],
            'current_address_landmark' => ['current_address_landmark', 'current landmark', 'landmark'],
            'current_address_status' => ['current_address_status', 'current address status'],
            
            // --- Address Details (Permanent) ---
            'permanent_address_line_1' => ['permanent_address_line_1', 'permanent address'],
            'permanent_address_state' => ['permanent_address_state', 'permanent state'],
            'permanent_address_city' => ['permanent_address_city', 'permanent city'],
            'permanent_address_pincode' => ['permanent_address_pincode', 'permanent pincode'],
            'permanent_address_landmark' => ['permanent_address_landmark', 'permanent landmark'],
            'permanent_address_status' => ['permanent_address_status', 'permanent address status'],

            // --- Address Details (Work & Contact) ---
            'work_address_line_1' => ['work_address_line_1', 'work address', 'office address'],
            'work_address_state' => ['work_address_state', 'work state', 'office state'],
            'work_address_city' => ['work_address_city', 'work city', 'office city'],
            'work_address_pincode' => ['work_address_pincode', 'work pincode', 'office pincode'],
            'work_address_landmark' => ['work_address_landmark', 'work landmark', 'office landmark'],
            'contact_address' => ['contact_address', 'contact address'],

            // --- Co-Applicant Details ---
            'co_applicant_name' => ['co_applicant_name', 'co applicant name', 'co-applicant name', 'Spouse_name', 'spouse Name'],
            'co_applicant_relationship' => ['co_applicant_relationship', 'co applicant relationship', 'relationship'],
            'co_applicant_dob' => ['co_applicant_dob', 'co applicant dob', 'co-applicant date of birth'],
            'co_applicant_gender' => ['co_applicant_gender', 'co applicant gender'],
            'co_applicant_pan_card' => ['co_applicant_pan_card', 'co applicant pan', 'co-applicant pan'],
            'co_applicant_aadhaar_card' => ['co_applicant_aadhaar_card', 'co applicant aadhaar', 'co-applicant aadhaar'],
            'co_applicant_email' => ['co_applicant_email', 'co applicant email'],
            'co_applicant_mobile_number' => ['co_applicant_mobile_number', 'co applicant mobile'],
            'co_applicant_required' => ['co_applicant_required', 'is co-applicant required'],
            'co_applicant_for_signing' => ['co_applicant_for_signing', 'co applicant for signing'], // From consumer_application_element
            'co_applicant_for_income' => ['co_applicant_for_income', 'co applicant for income'], // From consumer_application_element
            
            // --- Co-Applicant Address ---
            'co_applicant_address_line_1' => ['co_applicant_address_line_1', 'co applicant address'],
            'co_applicant_address_state' => ['co_applicant_address_state', 'co applicant state'],
            'co_applicant_address_pincode' => ['co_applicant_address_pincode', 'co applicant pincode'],
            'co_applicant_address_city' => ['co_applicant_address_city', 'co applicant city'],
            'co_applicant_address_landmark' => ['co_applicant_address_landmark', 'co applicant landmark'],
            'co_applicant_address_status' => ['co_applicant_address_status', 'co applicant address status'],

            // --- Co-Applicant Employment ---
            'co_applicant_employee_status' => ['co_applicant_employee_status', 'co applicant employment status'],
            'co_applicant_monthly_income' => ['co_applicant_monthly_income', 'co applicant monthly income', 'co applicant salary'],
            'co_applicant_company_name' => ['co_applicant_company_name', 'co applicant company'],
            'co_applicant_company_number' => ['co_applicant_company_number', 'co applicant company number'],
            'co_applicant_experience' => ['co_applicant_experience', 'co applicant experience'],
            'co_applicant_industry' => ['co_applicant_industry', 'co applicant industry'], // From consumer_application_element
            'co_applicant_profession_type' => ['co_applicant_profession_type', 'co applicant profession'], // From consumer_application_element
            
            // --- Application Status & Processing ---
            'state' => ['state', 'status', 'application status'],
            'completed_stage' => ['completed_stage', 'stage', 'application stage'],
            'credit_score' => ['credit_score', 'credit score', 'cibil', 'cibil score'],
            'rejection_reason' => ['rejection_reason', 'rejection reason'],

            // --- Source & Lead Details ---
            'src_merchant_name' => ['src_merchant_name', 'source merchant name', 'src merchant name'],
            'src_representative_name' => ['src_representative_name', 'source representative name', 'representative name'],
            'lead_src_email' => ['lead_src_email', 'lead source email'],
            'lead_src_phone' => ['lead_src_phone', 'lead source phone', 'lead source number'],

            // --- File & Document Fields ---
            'additional_docs_list' => ['additional_docs_list', 'additional documents list'],
            'additional_docs' => ['additional_docs', 'additional documents'],
            'file_income_proof' => ['file_income_proof', 'income proof'],
            'file_bank_statement' => ['file_bank_statement', 'bank statement'],
            'file_pan_card' => ['file_pan_card', 'pan card file'],
            'file_aadhaar_card' => ['file_aadhaar_card', 'aadhaar card file'],
            'file_electricity_bill' => ['file_electricity_bill', 'electricity bill'],

            // --- System & Miscellaneous Fields ---
            'id' => ['id', 'application_id', 'application id', 'consumer_application_id'],
            'user_id' => ['user_id', 'user id'],
            'applicant_id' => ['applicant_id', 'applicant id'],
            'co_applicant_id' => ['co_applicant_id', 'co applicant id'],
            'assigned_to' => ['assigned_to', 'assigned to'],
            'updated_by' => ['updated_by', 'updated by'],
            'pre_created_by' => ['pre_created_by', 'pre created by'],
            'misc_info' => ['misc_info', 'miscellaneous info', 'notes'],
            'long_link' => ['long_link', 'long link', 'url'],
            'created_at' => ['created_at', 'creation date', 'created on'],
            'updated_at' => ['updated_at', 'last updated', 'updated on'],

            // --- Application Element  ---
            'application_id' => ['application_id', 'application id'],

            // --- Applicant Profession & Industry ---
            'industry' => ['industry', 'applicant industry', 'industry sector'],
            'profession_type' => ['profession_type', 'profession type', 'applicant profession type'],

            // --- Co-Applicant Profession & Industry ---
            'co_applicant_industry' => ['co_applicant_industry', 'co applicant industry', 'co-applicant industry'],
            'co_applicant_profession_type' => ['co_applicant_profession_type', 'co applicant profession type', 'co-applicant profession type'],

            // --- Merchant & Center Details ---
            'center_id' => ['center_id', 'center id', 'merchant location id'],

            // --- Address (Current) ---
            'current_address_text' => ['current_address_text', 'current address text'],
            'current_formatted_text' => ['current_formatted_text', 'current formatted text'],

            // --- Address (Permanent) ---
            'permanent_address_text' => ['permanent_address_text', 'permanent address text'],
            'permanent_formatted_text' => ['permanent_formatted_text', 'permanent formatted text'],

            // --- Auto Approval ---
            'is_auto_approved' => ['is_auto_approved', 'auto approved flag', 'auto approval'],

            // --- Employment Details ---
            'designation' => ['designation', 'employment designation'],
            'department' => ['department', 'employment department'],
            'contact' => ['contact', 'employment contact', 'work contact'],

            // --- Product & Language ---
            'product_name' => ['product_name', 'product name', 'product id'],
            'preferred_language' => ['preferred_language', 'preferred language'],

            // --- Co-Applicant Flags ---
            'co_applicant_for_signing' => ['co_applicant_for_signing', 'co applicant for signing', 'co-applicant for signing'],
            'co_applicant_for_income' => ['co_applicant_for_income', 'co applicant for income', 'co-applicant for income'],

            // --- Banking & Documents ---
            'bank_id' => ['bank_id', 'bank id'],
            'mandatory_document_list' => ['mandatory_document_list', 'mandatory document list'],

            // --- Customer & Solar Details ---
            'type_of_customer' => ['type_of_customer', 'type of customer'],
            'solar_power_type' => ['solar_power_type', 'solar power type'],

            // --- Risk & Inverter Details ---
            'risk_category' => ['risk_category', 'risk category'],
            'inverter' => ['inverter', 'inverter brand'],
            'inverter_model_description' => ['inverter_model_description', 'inverter model description'],
            'inverter_monthly_power_bill' => ['inverter_monthly_power_bill', 'inverter monthly power bill'],
            'inverter_kw_installation' => ['inverter_kw_installation', 'inverter kw installation'],
            'inverter_power_savings' => ['inverter_power_savings', 'inverter power savings', 'estimated power savings'],
            // --- Payment Overdue ---
            'amount_over_due' => ['amount_over_due', 'amount overdue', 'overdue amount'],
        ];

        $requestData = $this->request->all();

        // If keys like consumer_application or consumer_application_element exist, flatten them
        if (isset($requestData['consumer_application']) && is_array($requestData['consumer_application'])) {
            $requestData = array_merge($requestData, $requestData['consumer_application']);
            unset($requestData['consumer_application']);
        }

        if (isset($requestData['consumer_application_element']) && is_array($requestData['consumer_application_element'])) {
            $requestData = array_merge($requestData, $requestData['consumer_application_element']);
            unset($requestData['consumer_application_element']);
        }

        $this->request->replace($requestData);
        // Now $requestData is always flat like:
        // ['name' => 'Sunil', 'dob' => '...', 'loan_amount' => '...', ...]
        foreach ($requestData as $key => $value) {
            foreach ($attributes as $attribute => $attributeValue) {
                $this->strPosArray($key, $attribute, $attributeValue);
            }
        }

       
        return;
    }

    public function getMerchantByGroup(){
        if($this->request->get('group_identifier')){
            return isset($this->groups[$this->request->get('group_identifier')]) ? $this->groups[$this->request->get('group_identifier')] : false;
        }
        return false;
    }

    public function simplyAttributes(){
        if($this->parsedData['merchant_id']) {
            foreach ($this->parsedData as $key => $value) {
                if ($key == 'tenure') {
                    $merchantOffer = MerchantOffers::where('merchant_id', $this->parsedData['merchant_id'])->where('tenure', $value)->first(['id']);
                    $this->parsedData['tenure'] = $value;
                    if(isset($merchantOffer->id)) {
                        $this->parsedData['offer_id'] = $merchantOffer->id;
                    } else {
                        $this->parsedData['offer_id'] = null;
                    }
                }
            }
        }
    }

    public function loadAdditionalAttributes($isUpdateRequest = false){
        if($isUpdateRequest) {
            $this->parsedData['merchant_id'] = $this->getMerchantByGroup();
            $this->parsedData['updated_by'] = 'WhatsApp';
        } else {
            $this->parsedData['lender_id'] = 2;
            $this->parsedData['created_by'] = $this->user;
            $this->parsedData['updated_by'] = 'WhatsApp';
            $this->parsedData['state'] = 'incomplete form';
            $this->parsedData['merchant_id'] = $this->getMerchantByGroup();
            $merchant = Merchant::where('id', $this->parsedData['merchant_id'])->first(['category_id']);
            if (isset($merchant->category_id)){
                $this->parsedData['purpose'] = $merchant->category_id;
            }
        }
    }

   public function strPosArray($key, $baseAttribute, $attributes, $type = 'consumer_application')
    {
        foreach ($attributes as $attribute) {
            if (strtolower($key) == strtolower($attribute)) {
                if($this->request->has($type . '.' . $key)) {
                    // If the key exists in the request, use its value
                    $value = $this->request->input($type . '.' . $key);
                } else {
                    // If not, check if the key exists in the request without the type prefix
                    $value = $this->request->input($key, null);
                }
                // $value = $this->request->input($type . '.' . $key, null);

                $this->parsedData[$baseAttribute] = $value;
            }
        }
    }

    //Temporary Code - due to cors error
    public function prodMiddleware($name){

        $id = 0;
        $url = 'https://creditfair.in/beta/'.$name;

        $headers = array(
            'Content-Type: application/json',
            'cf-x-client: '._env('CF_X_CLIENT_PRD'),
            'cf-x-client-secret: '._env('CF_X_CLIENT_SECRET_PRD')
        );

        $curl = curl_init();

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($this->request->all()));

        $response = curl_exec($curl);

        if ($response === false) {
            $error = curl_error($curl);
            $message =  'cURL error: ' . $error;
        } else {
            $data = json_decode($response, true);

            if ($data === null) {
                $message =  'Error decoding JSON: ' . json_last_error_msg();
            } else {
                $id = $data['id'] ?? 0;
                $message = $data['message'] ?? '';
            }
        }
        curl_close($curl);

        return response()->json(['id' => $id, 'message' => $message]);

    }

    public function getPincodeDetails(){
        $url = 'https://creditfair.in/api/get-pincode-details-v1?pincode'.$this->request->get('pincode');

        $headers = array(
            'Content-Type: application/json'
        );

        $curl = curl_init();

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($this->request->all()));

        $response = curl_exec($curl);

        $data = array();
        if ($response === false) {
            $error = curl_error($curl);
            $message =  'cURL error: ' . $error;
        } else {
            $data = json_decode($response, true);
        }
        curl_close($curl);

        return response()->json($data, 200);

    }

    public function updateUtkarshWebhook(){

    }

    public function processEmailTracker($tracking_id){
        $sms_logs = SMSLogs::where('tracking_id', $tracking_id)->where('read', 0)->first(['id']);
        if (isset($sms_logs->id)) {
            SMSLogs::where('id', $sms_logs->id)->update(['read' => 1, 'read_time' => Carbon::now()->toDateTimeString()]);
        }
    }
}
