<?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 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' => 1, // 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
    ];
        /**
     * @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;

        $message = $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 ($isUpdateRequest) {

            // Updating Existing Application
            $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();

            $message = "Application updated successfully with id: " . $application->id;
            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();
            $elementProperties = ['application_id' => $application->id];

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

            $message = "Application created successfully with id: " . $application->id . " /n/n" . $message;
            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 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
            'preferred_language' => ['preferred_language', 'language', 'preferred language'], // From consumer_application_element

            // --- 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'],
            'product_name' => ['product_name', 'product'], // From consumer_application_element

            // --- 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'],
            'designation' => ['designation', 'job title', 'role'], // From consumer_application_element
            'department' => ['department', 'dept'], // From consumer_application_element
            'industry' => ['industry', 'industry type', 'industry sector'], // From consumer_application_element
            'profession_type' => ['profession_type', 'profession'], // From consumer_application_element

            // --- 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'],
            'current_address_text' => ['current_address_text', 'current address text'], // From consumer_application_element
            
            // --- 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'],
            'permanent_address_text' => ['permanent_address_text', 'permanent address text'], // From consumer_application_element

            // --- 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'],
            'is_auto_approved' => ['is_auto_approved', 'auto approved'], // From consumer_application_element
            'bank_id' => ['bank_id', 'bank id'], // From consumer_application_element

            // --- 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'],
            'mandatory_document_list' => ['mandatory_document_list', 'mandatory documents'], // From consumer_application_element

            // --- 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'],
            'center_id' => ['center_id', 'center id', 'merchant location id'], // From consumer_application_element
            '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'],
        ];

        // The list of mandatory fields to check
        $mandatoryFields = [
            'Solar financing for',
            'Solar power type',
            'Net loan amount',
            'First Name',
            'Last Name',
            'Gender',
            'Pan Number',
            'Loan Amount',
            'DOB',
            'Permanent or Current Address Line 1',
            'Permanent or Current City',
            'Permanent or Current Pincode',
            'Permanent or Current State',
            'Permanent or Current Address Status',
            'Mobile number',
            'Monthly Income',
            'Merchant',
            'Main Purpose category',
            'Account type',
            'KW installation - Solar',
            'Power Savings (Estimated) -- Solar',
            'Employee Status',
            'FOIR',
            'Bureau report',
            'Pan Validation',
        ];

        foreach ($this->request->all() as $key => $value){
            foreach($attributes as $attribute => $attributeValue) {
                $this->strPosArray($key, $attribute, $attributeValue);
            }
        }

        // 1. Create a single, flat, lowercase list of all possible mappings.
        $allMappedValues = [];

        foreach ($attributes as $db_column => $variations) {
            foreach ($variations as $variation) {
                $allMappedValues[] = strtolower($variation);
            }
        }
        $allMappedValues = array_unique($allMappedValues);

        // 2. Find the missing fields
        $missingFields = [];
        foreach ($mandatoryFields as $field) {
            $isFound = false;
            $lowerField = strtolower($field);

            // Check for direct match
            if (array_key_exists($lowerField, $this->parsedData)) {
                $isFound = true;
            }

            // Special check for composite "Permanent or Current" fields
            elseif (strpos($lowerField, 'permanent or current') !== false) {
                $baseField = trim(str_replace('permanent or current', '', $lowerField));
                if (array_key_exists('permanent ' . $baseField, $this->parsedData) && array_key_exists('current ' . $baseField, $this->parsedData)) {
                    $isFound = true;
                }
            }
            
            // Special check for split name fields ("First Name", "Last Name")
            elseif ($lowerField === 'first name' || $lowerField === 'last name') {
                // We have 'name' and 'full name', which can accommodate this.
                // So we consider it "found" for the purpose of this check.
                if (array_key_exists('name', $this->parsedData) || array_key_exists('full name', $this->parsedData)) {
                    $isFound = true;
                }
            }

            // Special check for synonyms
            elseif (
                ($lowerField === 'pan number' && array_key_exists('pan', $this->parsedData)) ||
                ($lowerField === 'employee status' && array_key_exists('employment status', $this->parsedData)) ||
                ($lowerField === 'bureau report' && array_key_exists('credit score', $this->parsedData)) ||
                ($lowerField === 'main purpose category' && array_key_exists('purpose', $this->parsedData)) ||
                ($lowerField === 'net loan amount' && array_key_exists('loan amount', $this->parsedData))
            ) {
                $isFound = true;
            }

            if (!$isFound) {
                $missingFields[] = $field;
            }
        }

        // 3. Store the missing fields in a comma-separated string
        $missingFieldsString = implode(", \n", $missingFields);
        if (empty($missingFieldsString)) {
            return "";
        }
        // echo "The following mandatory fields are missing from the mapping:\n";
        $message = "Please provide below fields too for further & faster processing.\n Fields : " . $missingFieldsString;
        return $message;
    }

    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)
    {
        foreach ($attributes as $attribute) {
            if (strtolower($key) == strtolower($attribute)) {
                $value = preg_replace('/[^a-zA-Z0-9\s\/\-]/', '', $this->request->get($key)); // Allow date separators
                
                // if ($baseAttribute != 'dob') {
                //     if ($baseAttribute == 'mobile_number') {
                //         $value = str_replace(' ', '', $value);
                //     } elseif ($baseAttribute == 'tenure') {
                //         $value = preg_replace('/\D/', '', $value);
                //     }
                // } else {
                //     try {
                //         $value = Carbon::createFromFormat('d/m/Y', $value)->toDateString();
                //     } catch (\Exception $e) {
                //         $value = 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()]);
        }
    }
}
