<?php

namespace App\Http\Controllers;

use Hashids\Hashids;
use App\CommunicationMapping;
use App\CommunicationService;
use App\Merchant;
use App\Shortio;
use Carbon\Carbon;
use App\Http\Controllers\Admin\ConsumerDocument;
use App\ConsumerApplication;
use App\ConsumerApplicationElement;
use App\Templates;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Http\Request;
use App\BNPL;
use App\ConsentLog;
use App\ConsumerApplicationFiles;
use App\Logging\CloudWatchLoggerFactory;
use App\Http\Controllers\Admin\autoBRE;
use App\MerchantOffers;
use App\QueueLog;
use App\Events\V1\EventAutoDecision;
use App\Http\Controllers\Admin\ConsumerApplicationController;
use App\Http\Controllers\Grade\AutoRejection;
use App\StatusLogs;
use Illuminate\Support\Facades\Storage;

class ConsentController extends Controller
{

    public function showConsentPage($hashed_id, $applicant_type = 1)
    {
        $hashids = new Hashids('Creditfair by CS', 20);
        $decoded = $hashids->decode($hashed_id);

        if (empty($decoded)) {
            abort(404, 'Invalid link');
        }

        $id = $decoded[0];

        if ($applicant_type == 2) {
            $application = DB::connection('mysql_primary')
                ->table('consumer_application')
                ->where('id', $id)
                ->first(['id', 'co_applicant_name as name', 'merchant_id']);
        } else {
            $application = DB::connection('mysql_primary')
                ->table('consumer_application')
                ->where('id', $id)
                ->first(['id', 'name', 'merchant_id']);
        }

        if (!$application) {
            abort(404, 'Application not found');
        }
        $doc_name = $applicant_type == 1 ? 'consent_logs' : 'co_app_consent_logs';
        $merchant = DB::table('merchant')->where('id', $application->merchant_id)->first(['merchant_name']);
        $consumerApplicationElement = ConsumerApplicationElement::where('application_id', $id)
            ->first(['is_consent', 'is_co_app_consent']);
        $consumerApplicationFiles = ConsumerApplicationFiles::where('consumer_application_id', $id)
            ->where('applicant_type', $applicant_type)
            ->where('file_type', $doc_name)
            ->whereNull('deleted_at')
            ->first(['id']);

        $alreadyLogged = $applicant_type == 1 ? $consumerApplicationElement->is_consent : $consumerApplicationElement->is_co_app_consent;
        if ($consumerApplicationElement && $consumerApplicationFiles && $consumerApplicationFiles->id && $alreadyLogged) {
            $message = 'We have already logged your Consent';
            $title = 'Thank You!';
            return view('front.message-redirect', ['message' => $message, 'title' => $title]);
        }

        return view('front.consent_page', [
            'name' => $application->name,
            'merchant_name' => $merchant->merchant_name ?? '',
            'application_id' => $hashed_id,
            'applicant_type' => $applicant_type,
        ]);
    }

    public function sendConsentMessage($id, $applicant_type = 1)
    {
        $hashids = new Hashids('Creditfair by CS', 20);
        
        if ($applicant_type == 2) {
            $application = DB::connection('mysql_primary')
                ->table('consumer_application')
                ->where('id', $id)
                ->first(['id', 'co_applicant_name as name', 'co_applicant_email as email', 'co_applicant_mobile_number as mobile_number', 'merchant_id']);
        } else {
            $application = DB::connection('mysql_primary')
                ->table('consumer_application')
                ->where('id', $id)
                ->first(['id', 'name', 'email', 'mobile_number', 'merchant_id']);
        }

        $mobile_number = isset($application->mobile_number) ? wall_decrypt($application->mobile_number) : null;
        $mobile_hash = $mobile_number ? hexdec(substr(md5($mobile_number), 0, 7)) : null;
        
        if ($mobile_hash !== null) {
            $hashed_id = $hashids->encode($id, $mobile_hash);
        } else {
            $hashed_id = $hashids->encode($id);
        }
        
        $consent_path = $hashed_id;
        
        if ($applicant_type == 2) {
            $consent_path .= "/2";
        }

        if ($application->merchant_id && !BNPL::is($application->merchant_id)) {
            $email = isset($application->email) ? wall_decrypt($application->email) : null;
            $merchant = Merchant::where('id', $application->merchant_id)->first(['merchant_name']);
            $consent_key = array_search('Consent', CommunicationService::$com_category);
            $email_comm = CommunicationMapping::whereRaw('FIND_IN_SET('.$consent_key.',type_ids)')
                ->where('communication_id', 1)
                ->where('merchant_id', $application->merchant_id)
                ->count();
            $communication = CommunicationMapping::where('merchant_id', $application->merchant_id)->count();

            if (isset($email) && ($email_comm == 1 || $communication == 0)) {
                $body = '
                    <div style="font-size:13px;font-family:verdana,arial;line-height:1.5">
                        Dear ' . $application->name . ',
                            By clicking "I Accept", I hereby declare all information provided by me is correct and hereby consent to Blacksoil Capital Private Limited and its <a href="' . asset('affiliate-partners') . '">affiliate lending partners</a> to receive my bureau details and other financial /KYC details for financing purpose for purchase made with ' . $merchant->merchant_name . '
                        <div>Annual household Income > 3L</div>
                        <table style="width:100%">
                            <tbody>
                                <tr>
                                    <td align="center" style="padding:30px 30px 30px 30px">
                                        <table cellpadding="0" cellspacing="0" border="0">
                                            <tbody>
                                                <tr>
                                                    <td align="center" style="border-radius:3px;background-color:#0055cc;padding:11px 26px">
                                                        <a href="' . route('consent.page', ['hashed_id' => $hashed_id, 'applicant_type' => $applicant_type]) . '" style="color:white;text-decoration:none;text-transform:uppercase;font-size:16px" target="_blank">
                                                        I Agree</a>
                                                    </td>
                                                </tr>
                                            </tbody>
                                        </table>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>';

                if ($application->merchant_id != _env("Finsall_id")) {
                    Mail::send('emails.reminders.basic_reminder',
                        ['body' => $body],
                        function ($message) use ($email) {
                            $message->to([$email])->subject('IMPORTANT: Consent required');
                        });
                }
            }

            $link = Shortio::getUrl(asset("consent-page/" . $consent_path));
            $merchant_name = $merchant->merchant_name;
            $affiliateLink = "https://lnk.creditfair.in/5jES";
            $sms_body = "By clicking on link ".$link." I hereby declare all data provided by me is correct and hereby consent to K.M.Global Credit Pvt Ltd. and its affiliate lending partners ".$affiliateLink." to receive my bureau and other financial /KYC details for financing purpose for purchase made with ".$merchant_name.". Regards, Team Credit fair (KM Global)";
            $args = [$link, $merchant_name];
            $entity = ['templateid' => '1307173331891592692', 'entityid' => Templates::$entityid];
            
            send_sms($mobile_number, [
                'message' => $sms_body,
                'id' => $application->id,
                'id_type' => 'application_id',
                'templateDetails' => $entity,
                'args' => $args
            ]);

            $WA_comm = CommunicationMapping::whereRaw('FIND_IN_SET("'.$consent_key.'",type_ids)')
                ->where('communication_id', 3)
                ->where('merchant_id', $application->merchant_id)
                ->count();

            if ($mobile_number && ($WA_comm == 1 || $communication == 0)) {
                sendWhatsAppMessage($mobile_number, [
                    'id' => $id,
                    'templateId' => Templates::$consent_bureau_pull_v1,
                    'args' => [$merchant->merchant_name, $consent_path],
                    'templateType' => 'buttonTemplate'
                ]);
            }
        }
    }

    public function addConstantDocument($application_id, $applicant_type = 1, $show_view = true, $status, $request, $source = null) {
        $hashids = new Hashids('Creditfair by CS', 20);
        $hashed_id = $hashids->decode($application_id);
        $message = 'Please try after sometime';
        $title = 'Sorry!';

        if (isset($hashed_id[0])) {
            $application_id_decoded = $hashed_id[0];
            $link_mobile_hash = isset($hashed_id[1]) ? $hashed_id[1] : null;
            $fileName = 'consent_logs';
            $coFileName = 'co_app_consent_logs';

            if ($status === 'deny') {
                $fileName = 'deny_consent_logs';
                $coFileName = 'deny_co_app_consent_logs';
            }

            $field_map = [
                1 => ['consent_flag' => 'is_consent', 'mobile_field' => 'mobile_number', 'name_field' => 'name', 's3_folder' => $fileName],
                2 => ['consent_flag' => 'is_co_app_consent', 'mobile_field' => 'co_applicant_mobile_number', 'name_field' => 'co_applicant_name', 's3_folder' => $coFileName]
            ];

            $config = $field_map[$applicant_type];

            $consumerApplicationElement = ConsumerApplicationElement::where('application_id', $application_id_decoded)
                ->first([$config['consent_flag'], 'type_of_customer', 'solar_power_type']);

            if (isset($consumerApplicationElement->{$config['consent_flag']}) && (!$consumerApplicationElement->{$config['consent_flag']} || $source == 'mconnect')) {
                try {
                    $application = ConsumerApplication::with('proFormaInvoice', 'breMerchant')
                        ->where('id', $application_id_decoded)
                        ->first(['id', 'name', 'co_applicant_name', 'mobile_number', 'co_applicant_mobile_number', 'lender_id', 'state', 'updated_by', 'loan_amount', 'offer_id', 'merchant_id']);

                    if ($application) {
                        $current_mobile_encrypted = $application->{$config['mobile_field']};
                        $current_mobile = isset($current_mobile_encrypted) ? wall_decrypt($current_mobile_encrypted) : null;
                        
                        if ($link_mobile_hash !== null && $current_mobile) {
                            $current_mobile_hash = hexdec(substr(md5($current_mobile), 0, 7));
                            if ($current_mobile_hash !== $link_mobile_hash) {
                                $message = 'This consent link has expired as your mobile number has changed. A new link has been sent to your updated number.';
                                $title = 'Link Expired';
                                
                                if (!$show_view) {
                                    return response()->json(['status' => 'ERROR', 'message' => $message], 400);
                                }
                                return view('front.message-redirect', ['message' => $message, 'title' => $title]);
                            }
                        }

                        $mobile = '';
                        $ip = '';
                        $ip = (new ApiController())->get_client_ip();
                        $mobile = $application->{$config['mobile_field']};

                        $req_lat = $request->input('latitude');
                        $req_lng = $request->input('longitude');

                        if (empty($req_lat) || empty($req_lng)) {
                            $consentLog = ConsentLog::where('application_id', $application_id_decoded)
                                ->where('applicant_type', $applicant_type)
                                ->first(['latitude', 'longitude']);

                            if ($consentLog) {
                                $req_lat = $req_lat ?: $consentLog->latitude;
                                $req_lng = $req_lng ?: $consentLog->longitude;
                            }
                        }

                        if ((empty($req_lat) || empty($req_lng)) && !in_array($application->updated_by, ['WHATSAPP AGENT', 'WhatsApp'])) {
                            $message = 'Location access is required to provide consent.';
                            $title = 'Location Required';
                            
                            if (!$show_view) {
                                return response()->json(['status' => 'ERROR', 'message' => $message], 400);
                            }
                            return view('front.message-redirect', ['message' => $message, 'title' => $title]);
                        }

                        $data = [
                            'loan_application_no' => $application->proFormaInvoice && isset($application->proFormaInvoice->loan_application_no)
                                ? ucwords($application->proFormaInvoice->loan_application_no) : '',
                            'name' => $application->{$config['name_field']},
                            'mobile' => $mobile,
                            'consent_timestamp' => Carbon::now()->toDateTimeString(),
                            'lender_id' => $application->lender_id
                        ];

                        if ($ip) $data['ip'] = $ip;
                        $data['latitude'] = $req_lat;
                        $data['longitude'] = $req_lng;
                        $data['status'] = $status;
                        
                        $view = view('admin.consumer-application.consent_logs_document', ['data' => $data]);

                        $pdf = App::make('snappy.pdf.wrapper');
                        $request = new Request(['type_of_applicant' => $applicant_type]);
                        (new ConsumerDocument($request))->uploadToS3($config['s3_folder'], $application_id_decoded, $pdf->loadHTML($view)->output());

                        $message = 'We have logged your Denial of Consent';
                        $title = 'Thank You!';
                        
                        if ($status != 'deny') {
                            $message = 'We have logged your Consent';
                            ConsumerApplicationElement::where('application_id', $application->id)
                                ->update([$config['consent_flag'] => 1]);
                            
                            self::removeConsentFromMandatoryList($application->id, $config['s3_folder']);

                            if ($applicant_type == 1 || $applicant_type == 2) {
                                $autoBRE = new autoBRE();
                                $merchantOffer = MerchantOffers::where('id', $application->offer_id)->first(['tenure', 'advance_type', 'advance_emi']);
                                $application_status = $application->state;
                                
                                $cwFactory = new CloudWatchLoggerFactory();
                                $cwFactory->logger(json_encode([
                                    'application_id' => $application->id, 
                                    'net_loan_amount' => $autoBRE->calculateNetLoanAmount($application->loan_amount, $merchantOffer), 
                                    'type_of_customer' => $consumerApplicationElement->type_of_customer, 
                                    'solar_power_type' => $consumerApplicationElement->solar_power_type
                                ]));

                                if (in_array($application_status, ['in-process', 'incomplete form', 'form completed', 'waiting for documents']) 
                                    && in_array($application->updated_by, ['admin', 'MERCHANT API', 'consumer_app', 'merchant admin panel', 'WhatsApp'])
                                    && $autoBRE->calculateNetLoanAmount($application->loan_amount, $merchantOffer) <= 500000 
                                    && isset($consumerApplicationElement->type_of_customer) 
                                    && isset($consumerApplicationElement->solar_power_type)
                                    && $consumerApplicationElement->type_of_customer == 1 
                                    && $consumerApplicationElement->solar_power_type == 1
                                    && !$application->breMerchant) {

                                    $result = $autoBRE->checkDataPoints($application->id, $request);
                                    
                                    if ($result) {
                                        $merchant = DB::select('select m.id, m.is_auto_approve, m.is_auto_doc, m.pre_approval, m.grade_id from consumer_application c inner join merchant m on c.merchant_id = m.id where c.id = '.$application->id);
                                        
                                        if (isset($merchant[0]->id) && ($merchant[0]->is_auto_approve || $merchant[0]->is_auto_doc || $merchant[0]->pre_approval) && $merchant[0]->grade_id) {
                                            
                                            $triggerAutoDecision = true;
                                            if ($application_status == 'waiting for documents') {
                                                $required_docs_record = ConsumerApplicationElement::where('application_id', $application->id)->first(['mandatory_document_list']);
                                                if ($required_docs_record && !empty($required_docs_record->mandatory_document_list)) {
                                                    $req_docs = explode(',', $required_docs_record->mandatory_document_list);
                                                    $other_docs = array_diff($req_docs, ['consent_logs', 'co_app_consent_logs']);
                                                    if (count($other_docs) > 0) {
                                                        $triggerAutoDecision = false;
                                                    }
                                                }
                                            }

                                            if ($triggerAutoDecision) {
                                                $jobId = QueueLog::where('application_id', $application->id)
                                                    ->where('cmd', 'command:AutoDecision')
                                                    ->where('input', 'like', '%"applicant_type":'.(int) $applicant_type.'%')
                                                    ->value('job_id');                                                
                                                if (is_null($jobId)) {
                                                    event(new EventAutoDecision(['id' => $application->id, 'applicant_type' => (int) $applicant_type]));
                                                }
                                            } else {
                                                $appController = new ConsumerApplicationController();
                                                $appController->generateSoftBureauReport($application->id, 'autoBRE', $applicant_type, false);
                                                if ($applicant_type == 1) {
                                                    $autoRejectResult = (new AutoRejection(new Request()))->autoReject(false, $application->id, 'bot');
                                                    if ($autoRejectResult) {
                                                        $consumer_application = ConsumerApplication::find($application->id);
                                                        $consumer_application->state = "rejected";
                                                        $consumer_application->save();
                                                        StatusLogs::insert([
                                                            'application_id' => $application->id,
                                                            'user_id' => 107,
                                                            'status' => 'rejected',
                                                            'created_at' => Carbon::now()->toDateTimeString()
                                                        ]);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                } catch (\Exception $e) {
                    $cwFactory = new CloudWatchLoggerFactory();
                    $cwFactory->logger(json_encode([
                        'application_id' => $application_id,
                        'message' => $e->getMessage(),
                        'line' => $e->getLine(),
                        'trace' => $e->getTraceAsString()
                    ]));
                }
            } else {
                $message = 'We have already logged your Consent';
                $title = 'Thank You!';
            }
        }

        if (!$show_view) {
            return response()->json(['status' => 'OK', 'message' => $message], 200);
        }

        return view('front.message-redirect', ['message' => $message, 'title' => $title]);
    }

    public function preEligibilityConsentDocument($application_id){
        try {
            $preEligibility = DB::table('pre_eligibility_applications')
                ->where('id', $application_id)
                ->first(['id', 'customer_name', 'mobile_number']);

            if (!$preEligibility) {
                return;
            }

            $data = [
                'loan_application_no' => $preEligibility->id,
                'name'                => $preEligibility->customer_name,
                'mobile'              => $preEligibility->mobile_number,
                'consent_timestamp'   => Carbon::now()->toDateTimeString(),
                'status'              => 'agree',
                'lender_id'           => 2
            ];

            $view = view('admin.consumer-application.consent_logs_document', ['data' => $data]);
            $pdf  = app('snappy.pdf.wrapper');

            $file_path = '/pre_eligibility/' . $application_id . '/consent_logs_' . rand(1, 99) . '.pdf';
            Storage::disk('s3')->put($file_path, $pdf->loadHTML($view)->output());
        } catch (\Exception $e) {
            (new CloudWatchLoggerFactory())->logger(json_encode([
                'title'          => 'consentDocument Failed',
                'pre_eligibility_application_id' => $application_id,
                'message'        => $e->getMessage(),
                'line'           => $e->getLine(),
                'file'           => $e->getFile(),
            ]));
        }
    }


    public function submitConsent(Request $request){
        $status = $request->input('consent_status');
        $application_id = $request->input('application_id');
        $applicant_type = $request->input('applicant_type');
        $request->merge(['em' => true]);

        if ($request->has('is_api_call') && $request->is_api_call == true) {
            return $this->addConstantDocument($application_id, $applicant_type, false, $status, $request);
        } else {
            return $this->addConstantDocument($application_id, $applicant_type, true, $status, $request);
        }
    }
    public static function removeConsentFromMandatoryList($application_id, $file_type) {
        if (!in_array($file_type, ['consent_logs', 'co_app_consent_logs'])) {
            return;
        }

        $element = ConsumerApplicationElement::where('application_id', $application_id)->first();
        if ($element && !empty($element->mandatory_document_list)) {
            $mandatoryDocs = explode(',', $element->mandatory_document_list);
            if (($key = array_search($file_type, $mandatoryDocs)) !== false) {
                unset($mandatoryDocs[$key]);
                $element->mandatory_document_list = empty($mandatoryDocs) ? null : implode(',', $mandatoryDocs);
                $element->save();
            }
        }
    }
}
