<?php
namespace App\LoanHypothecation;

use App\ConsumerApplication;
use App\ConsumerApplicationFiles;
use App\DigitalSignDetails;
use App\Documents\BlackSoil\NonSolarSanctionLetterData;
use App\Http\Controllers\Admin\ConsumerDocument;
use App\LoanHypothecationModel;
use App\Logging\CloudWatchLoggerFactory;
use App\Slack;
use App\Vivriti;
use Carbon\Carbon;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\ApiController;
use Illuminate\Support\Facades\View;
use App\Http\Controllers\Admin\ConsumerApplicationController;
use App\Singularity\Singularity;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\WebhookController;
use App\Http\Controllers\Grade\GradeController;
use App\Http\Controllers\PostApprovalController;
use App\Jobs\AutoDCD;


/**
 * Created by PhpStorm.
 * User: sunil khorwal
 * Date: 6/6/16
 * Time: 1:52 PM
 */
class LoanHypothecation
{

    /**
     * @var Request
     */
    private $request;
    private $url;

    private $entity = null;
    /**
     * @var bool
     */
    private $is_resend = false;
    private $method = 'POST';
    /**
     * @var bool
     */
    private $fetch = false;
    private $application_id;

    private $digio = false;
    private $digio_audit_trail = false;

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

    public function initiateHypothecation($config = array())
    {

        if ($this->fetch == false && $data = $this->isSigningCompleted()) {
            return $data;
        }

        if ($config && $config['url']) {
            $this->url = $config['url'];
        }
        else {
            $host = _env('LEEGALITY_HYPOTHECATION_URL');
            if ($this->request->get('application') && $this->request->get('application')->lender_id == Vivriti::$lender_id) {
                $this->entity = Vivriti::$lender_id;
            }
            $this->url = $host . _env('LEEGALITY_HYPOTHECATION_URL_REQUEST');
        }
        return $this->process();
    }

    private function process()
    {
        $curl = curl_init();

        $auth_token = _env('LEEGALITY_X_Auth_Token');

        if ($this->entity == Vivriti::$lender_id) {
            $auth_token = _env('VIVRITI_LEEGALITY_X_Auth_Token');
        }

        if ($this->digio) {
            $clientId = _env('DIGIO_CLIENT_ID');
            $clientSecret = _env('DIGIO_CLIENT_SECRET');
        }
        else {
            $header = [
                'X-Auth-Token: ' . $auth_token,
            ];
        }

        $options = [
            CURLOPT_URL => $this->url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => $this->method,
        ];


        if ($this->digio) {
            $options[CURLOPT_USERPWD] = $clientId . ':' . $clientSecret;
        }

        if (!$this->digio) {
            if ($payload = $this->getPayload()) {
                array_push($header,
                    'Content-Type: application/json'
                );
                //array_push($options, [CURLOPT_POSTFIELDS => json_encode($payload)]);
                $options[CURLOPT_POSTFIELDS] = json_encode($payload);
            }
        }
        else {
            $header = [
                'Content-Type: application/json'
            ];
        }

        $options[CURLOPT_HTTPHEADER] = $header;
        //array_push($options, [CURLOPT_HTTPHEADER => $header]);

        curl_setopt_array($curl, $options);

        $response = curl_exec($curl);
        (new Slack(new Request(['title' => 'Leegality', 'fields' => ['url' => $this->url, 'res' => $response], 'group' => Slack::$STAGE_TESTING])))->send();
        $err = curl_error($curl);

        curl_close($curl);

        if (!$this->digio) {
            $cwFactory = new CloudWatchLoggerFactory();
            $data = array('application_id' => $this->request->get('id'), 'user_id' => isset(Auth::user()->id) ?Auth::user()->id : '', 'vendor' => 'leegality', 'api_url' => $this->url, 'Response' => $response, 'error_msg' => $err ?? '');
            $cwFactory->logger(json_encode($data));
        }

        if ($err) {
            return false;
        }

        if ($this->digio) {
            return $this->handleDigioResponse($response);
        }

        return $this->handleResponse(json_decode($response));
    }

    public function handleDigioResponse($response)
    {
        $responseObj = new \stdClass();
        $data = new \stdClass();

        if($this->digio_audit_trail){
            $data->auditTrail = $response;
        }else {
            $data->file = $response;
        }

        $responseObj->data = $data;
        $this->saveLoanAgreement($responseObj);

        return false;
    }

    public function handleResponse($response)
    {
        if (isset($response->data->documentId) && !isset($response->data->file) && ($this->fetch == false)) {
            $loanHypothecationModel = new LoanHypothecationModel();
            $loanHypothecationModel->fill([
                'application_id' => $this->request->get('id'),
                'documentId' => $response->data->documentId,
                'response' => json_encode($response),
                'status' => 'pending',
                'first_party_signing' => 0,
                'applicant_signing' => 0,
                'co_applicant_signing' => 0,
                'created' => Carbon::now()->toDateTimeString(),
            ]);

            $loanHypothecationModel->save();

            foreach ($response->data->invitees as $invitee) {
                if ($invitee->active) {
                    return $invitee->signUrl;
                }
            }
        }
        else if (isset($response->data->file) && ($this->fetch == true)) {
            $this->saveLoanAgreement($response);
        }

        return false;
    }

    private function saveLoanAgreement($response)
    {
        $s3 = Storage::disk('s3');

        $fileName = 'loan_agreement_esign';
        $path = $this->application_id . '/' . $fileName . '.pdf';
        if($this->digio && !$this->digio_audit_trail){
            $s3->put($path, $response->data->file, [
                'ContentType' => 'application/pdf',
            ]);
            $this->saveToFile($fileName, $path);
        }else if(!$this->digio_audit_trail){
            $s3->put($path, base64_decode($response->data->file));
            $this->saveToFile($fileName, $path);
        }

        if (isset($response->data->auditTrail)) {
            $fileName = 'auditTrail';

            $path = $this->application_id . '/' . $fileName . '.pdf';

            if($this->digio && $this->digio_audit_trail){
                $s3->put($path, $response->data->auditTrail, [
                    'ContentType' => 'application/pdf',
                ]);
            }else {
                $s3->put($path, base64_decode($response->data->auditTrail));
            }
            $this->saveToFile($fileName, $path);
        }

        if(!$this->digio) {
            $path = $this->application_id . '/' . 'hypothecation_response.json';
            $s3->put($path, json_encode($response));
        }
    }

    private function saveToFile($fileName, $path)
    {
        $consumer_application_file = new ConsumerApplicationFiles();
        $consumer_application_file->consumer_application_id = $this->application_id;
        $consumer_application_file->file_type = $fileName;
        $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 = Auth::user()->id ?? 107;
        $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();
    }

    private function getPayload()
    {

        if ($this->is_resend) {

            $loanHypothecationModel = LoanHypothecationModel::where('application_id', $this->request->get('id'))->orderBy('created_at', 'desc')->whereNull('deleted_at')->where('status', 'pending')->first();

            $links = [];
            $response = json_decode($loanHypothecationModel->response);
            foreach ($response->data->invitees as $invitee) {
                $links[] = $invitee->signUrl;
            }

            return [
                "signUrls" => $links
            ];
        }
        else if ($this->fetch) {
            return [];
        }
        $application = $this->getData()['application'];
        $exceptional_ids = explode(',', _env('STAMP_SERIES_SPECIFIC_CASES'));
        if (isset($application->approved_amount) && $application->approved_amount <= 500000 && !in_array($this->request->get('id'), $exceptional_ids)) {
            $stamp_series = _env('STAMP_SERIES_MAHA'); // Maharashtra
        }
        else {
            $stamp_series = _env('STAMP_SERIES_DEL'); // Delhi
        }

        $stamp_series = 'DL-300-';

        $profileId = _env('LEEGALITY_PROFILE_ID');
        if ($this->entity == Vivriti::$lender_id) {
            $profileId = _env('VIVRITI_LEEGALITY_PROFILE_ID');
        }

        return [
            "profileId" => $profileId,
            "file" => [
                "name" => $this->request->get('name'),
                "file" => $this->getHypothecationAgreement($stamp_series)
            ],
            "invitees" => $this->getInvitees(),
            "irn" => $this->request->get('id'),
            "stampSeries" => $stamp_series
        ];
    }

    public function getInvitees()
    {
        $invitees = [];

        $application = $this->getData()['application'];

        $invitees[] = [
            "name" => $application->name,
            "email" => $application->email,
            "phone" => $application->mobile_number
        ];

        if (isset($application->co_applicant_name) && ($application->co_applicant_mobile_number || $application->co_applicant_email)) {
            $invitees[] = [
                "name" => $application->co_applicant_name,
                "email" => $application->co_applicant_email,
                "phone" => $application->co_applicant_mobile_number
            ];
        }
        else {
            $invitees[] = [
                "name" => '',
                "email" => '',
                "phone" => ''
            ];
        }

        //First Party Detail
        $invitees[] = [
            "name"  => 'Blacksoil Capital Private Limited',
            "email" => 'esign@creditfair.in',
            "phone" => 9912172244
        ];
        // $exceptional_ids = explode(',', _env('STAMP_SERIES_SPECIFIC_CASES'));
        // if ($this->entity != Vivriti::$lender_id) {
        //     if (isset($application->approved_amount) && $application->approved_amount <= 500000 && !in_array($this->request->get('id'), $exceptional_ids)) {
        //         $invitees[] = [
        //             "name" => _env('LEEGALITY_CF_PARTY_NAME'),
        //             "email" => _env('LEEGALITY_CF_PARTY_EMAIL'),
        //             "phone" => _env('LEEGALITY_CF_PARTY_PHONE')
        //         ];
        //     }
        //     else {
        //         $invitees[] = [
        //             "name" => _env('LEEGALITY_FIRST_PARTY_NAME'),
        //             "email" => _env('LEEGALITY_FIRST_PARTY_EMAIL'),
        //             "phone" => _env('LEEGALITY_FIRST_PARTY_PHONE')
        //         ];
        //     }
        // }

        return $invitees;
    }

    private function getData()
    {
        $data = [];
        if (!$this->request->has('application')) {
            $data['application'] = ConsumerApplication::where('id', $this->request->get('id'))->first([
                'name',
                'mobile_number',
                'email',
                'co_applicant_name',
                'co_applicant_mobile_number',
                'co_applicant_email',
                'approved_amount',
            ]);
        }
        else {
            $data['application'] = $this->request->get('application');
        }

        return $data;
    }

    public function internal_signee_for_footer($loanAmount, $lender_id)
    {
        $invitees = [];
        $exceptional_ids = explode(',', _env('STAMP_SERIES_SPECIFIC_CASES'));
        if ($lender_id == 2) {
            if (isset($loanAmount) && $loanAmount <= 500000 && !in_array($this->request->get('id'), $exceptional_ids)) {
                $invitees[] = [
                    "name" => _env('LEEGALITY_CF_PARTY_NAME'),
                    "email" => _env('LEEGALITY_CF_PARTY_EMAIL'),
                    "phone" => _env('LEEGALITY_CF_PARTY_PHONE')
                ];
            }
            else {
                $invitees[] = [
                    "name" => _env('LEEGALITY_FIRST_PARTY_NAME'),
                    "email" => _env('LEEGALITY_FIRST_PARTY_EMAIL'),
                    "phone" => _env('LEEGALITY_FIRST_PARTY_PHONE')
                ];
            }
        }
        return $invitees;
    }

    public function getHypothecationAgreement($stamp_series)
    {
        $type = "Loan Agreement Esign";
        $request = new Request();
        $request->request->add(['type' => $type]);
        $consumerDocument = new ConsumerDocument($request);
        $viewParameter = ($consumerDocument->getDocument($this->request->get('id'))); // 12337, 12489
        $pdf = App::make('snappy.pdf.wrapper');
        $save_agreement_document_details = ['isInsuranceTaken' => 1, 'user' => $viewParameter['user'], 'id' => $this->request->get('id'), 'data' => $viewParameter['data'], 'pdf' => 0, 'lender' => $viewParameter['lender'], 'combined_sl_la' => $viewParameter['combined_sl_la'], 'stampSeries' => $stamp_series];

        //OLD FOOTER CODE
        // $applicant_name = $save_agreement_document_details['user']['customer_name'] ?? 'NA';
        // $loanAmount = $save_agreement_document_details['user']['loan_amount'] ?? $save_agreement_document_details['user']['loan_details']['loan_amount'] ?? 'NA';
        // $coApplicantName = $save_agreement_document_details['user']['co_applicant_name'] ?? 'blank';
        // $lender_id = $save_agreement_document_details['user']['lender_id'] ?? 'blank';

        // $invitee_name = $this->internal_signee_for_footer($loanAmount, $lender_id)[0]['name'];

        if ($viewParameter['user']['lender_id'] == Vivriti::$lender_id) {
            $view = 'admin.documents.vivriti.loan_agreement_v2';
        // $pdf->setOption('header-html', (new ConsumerDocument(new Request()))->getPDFHeaderView());
        } elseif ($viewParameter['user']['lender_id'] == \App\BlackSoil::$lender_id) {
            $view = 'admin.documents.blacksoil.loan_agreement_v1';
            // Non-solar BlackSoil cases have their own agreement. This payload has no
            // 'application' key, so appliesTo() resolves from the id instead.
            if (NonSolarSanctionLetterData::appliesTo($this->request->get('id'))) {
                $view = NonSolarSanctionLetterData::LOAN_AGREEMENT_VIEW;
                $save_agreement_document_details['nonsolar_sanction_letter'] =
                    NonSolarSanctionLetterData::build($this->request->get('id'));
            }
        } else {
            $view = 'admin.documents.hypothecation_borrower_loan_agreement_esign_v_two_v1';
        }
        //OLD FOOTER CODE
        // $footerData = [
        //     'applicant_name' => $applicant_name,
        //     'co_applicant_name' => $coApplicantName,
        //     'invitee_name' => $invitee_name,
        // ];

        // // 2. Render the footer view into a string, passing the data to it [6].
        // $footerHtml = view('admin.documents.vivriti.pdf_footer', $footerData)->render();

        // $file = $pdf->loadView($view, $save_agreement_document_details)
        //     ->setOption('encoding', 'UTF-8')
        //     ->setPaper('a4')
        //     ->setOrientation('portrait')
        //     ->setOption('margin-bottom', '35mm')
        //     ->setOption('footer-html', $footerHtml)
        //     ->setOption('footer-spacing',28)
        //     ->output();

        $file = $pdf->loadView($view, $save_agreement_document_details)->setOption('encoding', 'UTF-8')->setPaper('a4')->setOrientation('portrait')->setOption('margin-bottom', 40)->output();

        // return view($view, $save_agreement_document_details);
        //return $pdf->inline();
        return base64_encode($file);
    }

    public function isSigningCompleted()
    {
        $application = ConsumerApplication::where('id', $this->request->get('id'))->first(['mobile_number', 'email', 'co_applicant_mobile_number', 'co_applicant_email']);
        $loanHypothecationModel = LoanHypothecationModel::where('application_id', $this->request->get('id'))->whereNull('deleted_at')->orderBy('created_at', 'desc')->first();
        if (isset($loanHypothecationModel->id)) {

            if ($loanHypothecationModel->status == 'success') {
                return true;
            }

            $data = json_decode($loanHypothecationModel->response);
            if (!$loanHypothecationModel->applicant_signing) {
                return $this->getHypothecationLink($data, $application->mobile_number, $application->email);
            }
            else if (!$loanHypothecationModel->co_applicant_signing) {
                return $this->getHypothecationLink($data, $application->co_applicant_mobile_number, $application->co_applicant_email);
            }
            return true;
        }

        return false;
    }

    public function getHypothecationLinks()
    {
        $appId = $this->request->get('id');
        $application = ConsumerApplication::where('id', $appId)->first(['mobile_number', 'email', 'co_applicant_name', 'co_applicant_mobile_number', 'co_applicant_email', 'lender_id']);
        $loanHypothecation = LoanHypothecationModel::where('application_id', $appId)->whereNull('deleted_at')->orderBy('created_at', 'desc')->first();
        $links_data = [
            'co_applicant_exists' => false,
            'signed_status' => null,
            'applicant_link' => '',
            'co_applicant_link' => ''
        ];
        if (!$loanHypothecation || $application->lender_id == Singularity::$lender_id) {
            return $links_data;
        }
        if (!empty($application->co_applicant_name) && (!empty($application->co_applicant_mobile_number) || !empty($application->co_applicant_email))) {
            $links_data['co_applicant_exists'] = true;
        }
        // If both have signed, return with signed status
        if ($loanHypothecation->applicant_signing && $loanHypothecation->co_applicant_signing) {
            $links_data['signed_status'] = true;
            return $links_data;
        }
        $response = json_decode($loanHypothecation->response);
        if (!$loanHypothecation->applicant_signing) {
            $links_data['signed_status'] = false;
            $links_data['applicant_link'] = $this->getHypothecationLink($response, $application->mobile_number, $application->email);
        }
        if ($links_data['co_applicant_exists'] && !$loanHypothecation->co_applicant_signing) {
            $links_data['signed_status'] = false;
            $links_data['co_applicant_link'] = $this->getHypothecationLink($response, $application->co_applicant_mobile_number, $application->co_applicant_email);
        }
        return $links_data;
    }

    private function getHypothecationLink($response, $phone, $email)
    {

        if(!isset($response->data->invitees) && isset($response->signing_parties)){
            foreach ($response->signing_parties as $item) {
                if ($item->identifier == $phone || $item->identifier == $email) {
                    return $item->authentication_url;
                }
            }

            return true;
        }

        foreach ($response->data->invitees as $item) {
            if ($item->phone == $phone || $item->email == $email) {
                return $item->signUrl;
            }
        }

        return true;
    }

    public function getStatus()
    {

        $loanHypothecationModel = LoanHypothecationModel::where('application_id', $this->request->get('id'))->whereNull('deleted_at')->orderBy('created_at', 'desc')->first(['id', 'documentId', 'applicant_signing', 'co_applicant_signing', 'first_party_signing', 'status', 'response']);
        $application = ConsumerApplication::where('id', $this->request->get('id'))->first([
            'id',
            'name',
            'mobile_number',
            'email',
            'co_applicant_name',
            'co_applicant_mobile_number',
            'co_applicant_email',
            'approved_amount',
        ]);

        $body = '<table style="font-family: sans-serif;" class="table">';
        $body .= '<tr><td colspan="2" style="text-align: center;font-weight: 700;">Agreement Signing Status</td></tr>';
        $hide = 0;
        if (isset($loanHypothecationModel->id)) {
            if (isset($loanHypothecationModel->documentId)) {
                $body .= '<tr><td colspan="2" style="text-align: center;font-weight: 500;">' . $loanHypothecationModel->documentId . '</td></tr>';
            }

            $exceptional_ids = explode(',', _env('STAMP_SERIES_SPECIFIC_CASES'));
            if (isset($application->approved_amount) && $application->approved_amount <= 500000 && !in_array($this->request->get('id'), $exceptional_ids)) {
                $first_party_email = _env('LEEGALITY_CF_PARTY_EMAIL');
                $first_party_phone = _env('LEEGALITY_CF_PARTY_PHONE');
            }
            else {
                $first_party_email = _env('LEEGALITY_FIRST_PARTY_EMAIL');
                $first_party_phone = _env('LEEGALITY_FIRST_PARTY_PHONE');
            }

            $data = json_decode($loanHypothecationModel->response);

            $applicant_link = $this->getHypothecationLink($data, $application->mobile_number, $application->email);
            $copy_url_applicant = '';
            if ($applicant_link) {
                $copy_url_applicant = ' <a href="javascript:void(0);" class="copy-data-url" data-copy-url="' . $applicant_link . '">Copy URL</a>';
            }

            $co_applicant_link = $this->getHypothecationLink($data, $application->co_applicant_mobile_number, $application->co_applicant_email);
            $copy_url_co_applicant = '';
            if ($co_applicant_link) {
                $copy_url_co_applicant = ' <a href="javascript:void(0);" class="copy-data-url" data-copy-url="' . $co_applicant_link . '">Copy URL</a>';
            }

            $first_party_link = $this->getHypothecationLink($data, $first_party_phone, $first_party_email);
            $copy_url_first_party = '';
            if ($first_party_link) {
                $copy_url_first_party = ' <a href="javascript:void(0);" class="copy-data-url" data-copy-url="' . $first_party_link . '">Copy URL</a>';
            }

            $body .= '<tr><td>Name</td><td>Status</td></tr>';

            $msg = $loanHypothecationModel->applicant_signing ? 'Signed' : 'Pending' . $copy_url_applicant;
            $msgCo = $loanHypothecationModel->co_applicant_signing ? 'Signed' : 'Pending' . $copy_url_co_applicant;
            $msgFP = $loanHypothecationModel->first_party_signing ? 'Signed' : 'Pending' . $copy_url_first_party;
            $body .= '<tr><td>' . $application->name . '</td><td>' . $msg . '</td></tr>';
            if ($application->co_applicant_name) {
                $body .= '<tr><td>' . $application->co_applicant_name . '</td><td>' . $msgCo . '</td></tr>';
            }
            $body .= '<tr><td>Final Signing</td><td>' . $msgFP . '</td></tr>';
            $body .= '<tr><td>Status</td><td>' . $loanHypothecationModel->status . '</td></tr>';
            $hide = isset($loanHypothecationModel->status) && $loanHypothecationModel->status == 'success' ? 1 : 0;
        }
        else {
            $body .= '<tr><td colspan="2">Not initiated Yet</td></tr>';
        }
        $body .= '</table>';
        if (isset($loanHypothecationModel->id) && !$hide) {
            $body .= '<div id="trigger-hypothecation" data-id="' . $this->request->get('id') . '" class="btn btn-primary">Re-Share Link</div>';
        }

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

    public function resendNotification()
    {
        $this->is_resend = true;
        $host = _env('LEEGALITY_HYPOTHECATION_URL');
        if ($this->request->get('id')) {
            $application = ConsumerApplication::where('id', $this->request->get('id'))->first(['id', 'lender_id']);
            if (isset($application->lender_id) && $application->lender_id == Vivriti::$lender_id) {
                $this->entity = Vivriti::$lender_id;
            }
        }
        $this->url = $host . _env('LEEGALITY_HYPOTHECATION_URL_RESEND');
        return $this->process();
    }

    public function updateHypothecation($application_id, $id = 0, $signer = '')
    {
        // if($id){
        //     $application = ConsumerApplication::where('id', $application_id)->first(['co_applicant_name']);
        //     $loanHypothecationModel = LoanHypothecationModel::where('id', $id)->first(['id','applicant_signing', 'co_applicant_signing', 'first_party_signing']);
        // }else{
        $application = ConsumerApplication::where('id', $application_id)->first(['co_applicant_name']);
        $loanHypothecationModel = LoanHypothecationModel::where('application_id', $application_id)->whereNull('deleted_at')->orderBy('created_at', 'desc')->first(['id', 'applicant_signing', 'co_applicant_signing', 'first_party_signing']);
        // }
        if ($signer == '') {
            if ($loanHypothecationModel->id) {
                return true;
            }
        // if(!$loanHypothecationModel->applicant_signing){
        //     LoanHypothecationModel::where('id', $loanHypothecationModel->id)->update(['applicant_signing' => 1]);
        //     $this->createDigitalSigned($application_id, 1);
        //     return true;
        // }else if($application->co_applicant_name && !$loanHypothecationModel->co_applicant_signing){
        //     LoanHypothecationModel::where('id', $loanHypothecationModel->id)->update(['co_applicant_signing' => 1]);
        //     $this->createDigitalSigned($application_id, 2);
        //     return true;
        // }else if(!$loanHypothecationModel->first_party_signing){
        //     LoanHypothecationModel::where('id', $loanHypothecationModel->id)->update(['first_party_signing' => 1, 'status' => 'success']);
        //     return true;
        // }
        }
        elseif ($signer == 'applicant' && $loanHypothecationModel->applicant_signing != 1) {
            LoanHypothecationModel::where('id', $loanHypothecationModel->id)->update(['applicant_signing' => 1]);
            $this->createDigitalSigned($application_id, 1);
            return true;
        }
        elseif ($signer == 'co_applicant' && $loanHypothecationModel->co_applicant_signing != 1) {
            LoanHypothecationModel::where('id', $loanHypothecationModel->id)->update(['co_applicant_signing' => 1]);
            $this->createDigitalSigned($application_id, 2);
            return true;
        }
        elseif ($signer == 'first_party' && $loanHypothecationModel->first_party_signing != 1) {
            LoanHypothecationModel::where('id', $loanHypothecationModel->id)->update(['first_party_signing' => 1, 'status' => 'success']);
            return true;
        }
        return false;
    }

    private function createDigitalSigned($application_id, $applicant_type)
    {
        $date = Carbon::now()->toDateTimeString();
        $application = DigitalSignDetails::where('application_id', $application_id)->where('applicant', $applicant_type)->first(['id']);
        if (!isset($application->id)) {
            $digitalSignDetails = new DigitalSignDetails();
            $digitalSignDetails->fill([
                'application_id' => $application_id,
                'applicant' => $applicant_type,
                'load_time' => $date,
                'click_time' => $date,
                'language' => 'ENGLISH',
                'isagreementsigned' => 1,
                'type' => 'consumer',
                'esign_vendor' => 'leegality',
                'created_at' => $date
            ]);

            $digitalSignDetails->save();
        }
    }

    public function simplifyThedataIfDigio()
    {
        $response = $this->request->all();
        if (isset($response['data']['payload'])) {

            $application = LoanHypothecationModel::where('documentId', $response['data']['payload']['document']['id'])->whereNull('deleted_at')->first(['application_id']);

            return [
                'data' => [
                    'request' => ['action' => $response['data']['event'] == 'doc.signed' ? 'Signed' : 'pending', 'error' => $response['data']['event'] == 'doc.signed' ? null : ($response['data']['error'] ?? ''), 'phone' => $response['data']['payload']['document']['signing_parties'], 'email' => ''],
                    'irn' => $application->application_id,
                    'has_all_signed' => $response['data']['payload']['document']['others']['has_all_signed'] ?? false,
                    'digio' => true
                ]
            ];
        }
        return $response;
    }

    public function updateHypothecationWebhook()
    {
        //$response = $this->request->all();

        $response = $this->simplifyThedataIfDigio();

        if (isset($response['data']['request'])) {
            $application = ConsumerApplication::where('id', $response['data']['irn'])->first([
                'id',
                'state',
                'lender_id',
                'name',
                'mobile_number',
                'email',
                'co_applicant_name',
                'co_applicant_mobile_number',
                'co_applicant_email',
                'approved_amount',
                'merchant_id',
                'created_by',
                'updated_by'
            ]);
            $digioVkycApp = DB::table('digio_vkyc')
                ->where('application_id', $application->id)
                ->where('applicant_type', 1)
                ->where('kyc_status', 'approved')
                ->first();
            $digioVkycCoApp = DB::table('digio_vkyc')
                ->where('application_id', $application->id)
                ->where('applicant_type', 2)
                ->where('kyc_status', 'approved')
                ->first();
            $is_action_signed = (isset($response['data']['request']['action']) && $response['data']['request']['action'] == "Signed") ? true : false;
            $is_error = (isset($response['data']['request']['error']) && $response['data']['request']['error'] != null) ? true : false;

            $loanHypothecationModel = LoanHypothecationModel::where('application_id', $application->id)->whereNull('deleted_at')->orderBy('created_at', 'desc')->first(['id', 'documentId', 'applicant_signing', 'co_applicant_signing']);

            if ($is_action_signed && !$is_error) {

                $signedApp = false;
                if (!isset($response['data']['digio'])) {
                    $signedApp = $loanHypothecationModel->applicant_signing != 1 && ($application->mobile_number && $application->mobile_number == $response['data']['request']['phone'] || (strlen($application->email) && $application->email == $response['data']['request']['email']));
                }
                if(!$signedApp){
                    $signedApp = $loanHypothecationModel->applicant_signing != 1 && $response['data']['request']['phone'][0]['status'] == 'signed' && ($application->mobile_number && $application->mobile_number == $response['data']['request']['phone'][0]['identifier'] || (strlen($application->email) && $application->email == $response['data']['request']['email']));
                    if(!$signedApp){
                        $signedApp = $loanHypothecationModel->applicant_signing != 1 && $response['data']['request']['phone'][1]['status'] == 'signed' &&  isset($response['data']['request']['phone'][1]['identifier']) && ($application->mobile_number && $application->mobile_number == $response['data']['request']['phone'][1]['identifier'] || (strlen($application->email) && $application->email == $response['data']['request']['email']));
                    }
                    if(!$signedApp){
                        $signedApp = $loanHypothecationModel->applicant_signing != 1 && $response['data']['request']['phone'][2]['status'] == 'signed' &&  isset($response['data']['request']['phone'][2]['identifier']) && ($application->mobile_number && $application->mobile_number == $response['data']['request']['phone'][2]['identifier'] || (strlen($application->email) && $application->email == $response['data']['request']['email']));
                    }
                }





                if ($signedApp) {
                    $this->updateHypothecation($application->id, $loanHypothecationModel->id, 'applicant');
                    if (!$application->co_applicant_name || $loanHypothecationModel->co_applicant_signing && empty($digioVkycApp)) {
                        $this->addVCComment($application);
                    }
                }


                $signedcoApp = false;
                if (!isset($response['data']['digio'])) {
                    $signedcoApp = $loanHypothecationModel->co_applicant_signing != 1 && ($application->co_applicant_mobile_number && $application->co_applicant_mobile_number == $response['data']['request']['phone']) || (strlen($application->co_applicant_email) && $application->co_applicant_email == $response['data']['request']['email']);
                }
                if(!$signedcoApp){
                    $signedcoApp = $loanHypothecationModel->co_applicant_signing != 1 && $response['data']['request']['phone'][0]['status'] == 'signed' &&  ($application->co_applicant_mobile_number && $application->co_applicant_mobile_number == $response['data']['request']['phone'][0]['identifier'] || (strlen($application->co_applicant_email) && $application->co_applicant_email == $response['data']['request']['email']));
                    if(!$signedcoApp){
                        $signedcoApp = $loanHypothecationModel->co_applicant_signing != 1 && isset($response['data']['request']['phone'][1]['identifier']) && $response['data']['request']['phone'][1]['status'] == 'signed' && ($application->co_applicant_mobile_number && $application->co_applicant_mobile_number == $response['data']['request']['phone'][1]['identifier'] || (strlen($application->co_applicant_email) && $application->co_applicant_email == $response['data']['request']['email']));
                    }
                    if(!$signedcoApp){
                        $signedcoApp = $loanHypothecationModel->co_applicant_signing != 1 && isset($response['data']['request']['phone'][2]['identifier']) && $response['data']['request']['phone'][2]['status'] == 'signed' && ($application->co_applicant_mobile_number && $application->co_applicant_mobile_number == $response['data']['request']['phone'][2]['identifier'] || (strlen($application->co_applicant_email) && $application->co_applicant_email == $response['data']['request']['email']));
                    }
                }


                $has_all_signed = true;
                if (isset($response['data']['digio'])) {
                    $has_all_signed = isset($response['data']['has_all_signed']) && $response['data']['has_all_signed'] == 1;
                }


                if ($signedcoApp) {
                    $this->updateHypothecation($application->id, $loanHypothecationModel->id, 'co_applicant');
                    if ($loanHypothecationModel->applicant_signing && empty($digioVkycCoApp)) {
                        $this->addVCComment($application);
                    }
                }


                if($has_all_signed){
                    // LoanHypothecationModel::where('id', $loanHypothecationModel->id)->update(['first_party_signing' => 1, 'status' => 'success']);
                    $this->updateHypothecation($application->id, $loanHypothecationModel->id, 'first_party');
                    $this->fetchDocuments($application->id, $application->lender_id, $loanHypothecationModel->documentId, $response);
                }
            }

            $loanHypothecationModel->refresh();

            $allowedStatuses = ['approved', 'disbursement query'];
            if (in_array($application->state, $allowedStatuses)) {
                if (($loanHypothecationModel->applicant_signing && !$application->co_applicant_name) || ($application->co_applicant_name && $loanHypothecationModel->co_applicant_signing && $loanHypothecationModel->applicant_signing)) {
                    if (!$has_all_signed) {
                        // Webhook for LA signing completed
                        (new ConsumerApplicationController())->webhook($application->id, ['type' => 'Loan-Agreement-Signing-Webhook', 'status' => 'completed', 'data' => []]);
                        AutoDCD::precheckAndCreateJob($application->id);
                    }
                }
            }
        }
    }

    public function fetchDocuments($id, $lender_id, $documentId, $response = [])
    {
        $host = _env('LEEGALITY_HYPOTHECATION_URL');
        if ($lender_id == Vivriti::$lender_id) {
            $this->entity = Vivriti::$lender_id;
        }
        $this->url = $host . _env('LEEGALITY_HYPOTHECATION_URL_DOCUMENT') . '?documentId=' . $documentId . '&file=1&auditTrail=1&attachments=1&failureReason=1&verificationResponse=1';
        $this->method = 'GET';
        $this->fetch = true;
        $this->application_id = $id;

        if (isset($response['data']['digio'])) {
            $host = rtrim(_env('DIGIO_BASE_URL', 'https://api.digio.in'), '/') . '/v2/client/document/download';
            $this->url = $host . '?document_id=' . $documentId;
            $this->digio = true;
        }

        $this->process();

        if (isset($response['data']['digio'])) {
            $host = rtrim(_env('DIGIO_BASE_URL', 'https://api.digio.in'), '/') . '/v2/client/document/'.$documentId.'/v2/audit_log';
            $this->url = $host . '?doc_id=' . $documentId;
            $this->digio_audit_trail = true;
            $this->process();
        }
    }

    public function triggerHypothecationCommunication($id)
    {

        $apiController = new ApiController();
        $isHypothecationActive = $apiController->canHypothecated($id);
        $applicant_link = "";
        $co_applicant_link = "";
        $first_party_link = "";

        if ($isHypothecationActive) {

            $consumer_details = ConsumerApplication::with('merchant', 'category')->where('id', $id)->first();


            $exceptional_ids = explode(',', _env('STAMP_SERIES_SPECIFIC_CASES'));
            if (isset($consumer_details->approved_amount) && $consumer_details->approved_amount <= 500000 && !in_array($this->request->get('id'), $exceptional_ids)) {
                $first_party_email = _env('LEEGALITY_CF_PARTY_EMAIL');
                $first_party_phone = _env('LEEGALITY_CF_PARTY_PHONE');
            }
            else {
                $first_party_email = _env('LEEGALITY_FIRST_PARTY_EMAIL');
                $first_party_phone = _env('LEEGALITY_FIRST_PARTY_PHONE');
            }


            $applicant_name = $consumer_details['name'];
            $co_applicant_name = $consumer_details['co_applicant_name'];
            $merchant_name = $consumer_details->merchant->merchant_name;
            $purpose_of_the_loan = $consumer_details->category->name;
            $applicant_email = (strlen($consumer_details->email) > 0) ? wall_decrypt($consumer_details->email) : "";
            $co_applicant_email = (strlen($consumer_details->co_applicant_email) > 0) ? wall_decrypt($consumer_details->co_applicant_email) : "";
            $subject = 'Signing of Loan Agreement';

            // Data to pass to the Blade view
            $user = [
                'customer_name' => $applicant_name,
                'co_applicant_name' => $co_applicant_name,
                'merchant_name' => $merchant_name,
                'purpose_of_the_loan' => $purpose_of_the_loan
            ];

            $loanHypothecationModel = LoanHypothecationModel::where('application_id', $id)->whereNull('deleted_at')->orderBy('created_at', 'desc')->first();
            if (isset($loanHypothecationModel->id)) {

                if ($loanHypothecationModel->status == 'success') {
                    return 2;
                }

                $data = json_decode($loanHypothecationModel->response);
                if (!$loanHypothecationModel->applicant_signing) {
                    $applicant_link = $this->getHypothecationLink($data, $consumer_details->mobile_number, $consumer_details->email);
                }
                else if (!$loanHypothecationModel->co_applicant_signing) {
                    $co_applicant_link = $this->getHypothecationLink($data, $consumer_details->co_applicant_mobile_number, $consumer_details->co_applicant_email);
                }
                else if (!$loanHypothecationModel->first_party_signing) {
                    $first_party_link = $this->getHypothecationLink($data, $first_party_phone, $first_party_email);
                }

            }
            else {
                return 1;
            }

            if ($applicant_link != "") {
                $user["esignlink"] = $applicant_link;
                // Capture the rendered content of the Blade view into a string variable
                $dataview['user'] = $user;
                $cc_emails = array();
                $body = View::make('emails.consumer_esign_mail', $dataview)->render();
                try {
                    if ($applicant_email != "") {
                        \Mail::send('emails.blank',
                        ['body' => $body]
                            , function ($message) use ($applicant_email, $subject) {
                            $message->to($applicant_email)->subject(($subject) ? $subject : '');
                        });
                    }
                }
                catch (\Exception $e) {
                    (new Slack(new Request(['title' => 'Email id exception', 'fields' => ['Message' => $e->getMessage(), 'Line' => $e->getLine(), 'File' => $e->getFile(), 'Trace' => $e->getTraceAsString()]])))->send();
                    return 3;
                }
            }
            if ($co_applicant_link != "") {
                $user["esignlink"] = $co_applicant_link;
                // Capture the rendered content of the Blade view into a string variable
                $dataview['user'] = $user;

                $body = View::make('emails.consumer_esign_mail', $dataview)->render();

                try {
                    if ($co_applicant_email != "") {
                        \Mail::send('emails.blank',
                        ['body' => $body]
                            , function ($message) use ($co_applicant_email, $subject) {
                            $message->to($co_applicant_email)->subject(($subject) ? $subject : '');
                        });
                    }
                }
                catch (\Exception $e) {
                    (new Slack(new Request(['title' => 'Email id exception', 'fields' => ['Message' => $e->getMessage(), 'Line' => $e->getLine(), 'File' => $e->getFile(), 'Trace' => $e->getTraceAsString()]])))->send();
                    return 3;
                }
            }
            if ($first_party_link != "") {
                $user["esignlink"] = $first_party_link;
                // Capture the rendered content of the Blade view into a string variable
                $dataview['user'] = $user;

                $body = View::make('emails.consumer_esign_mail', $dataview)->render();

                try {
                    if ($first_party_email != "") {
                        \Mail::send('emails.blank',
                        ['body' => $body]
                            , function ($message) use ($first_party_email, $subject) {
                            $message->to($first_party_email)->subject(($subject) ? $subject : '');
                        });
                    }
                }
                catch (\Exception $e) {
                    (new Slack(new Request(['title' => 'Email id exception', 'fields' => ['Message' => $e->getMessage(), 'Line' => $e->getLine(), 'File' => $e->getFile(), 'Trace' => $e->getTraceAsString()]])))->send();
                    return 3;
                }
            }
            return 0;
        }
        return 1;

    }

    public function moveToDCDStatus($application_id, $digioVkyc, $merchant_id){
        $consumerApplication = DB::selectOne("select aadhaar_card from consumer_application where id = ". $application_id);
        if (empty($consumerApplication->aadhaar_card)) {
            return false; // Aadhaar card missing — block auto DCD
        }
        $requiredDoc = DB::select("select consumer_application_id, file_type from consumer_application_files where file_type in ('proforma', 'tfr', 'TFR', 'advance_amount_receipt') and consumer_application_id = ". $application_id ." and deleted_at is null");
        $verificationCall = DB::Select("select id from consumer_application_files where file_path like '%verification_call%' and consumer_application_id = ". $application_id ." and deleted_at is null limit 1");
        $applicationElement = DB::selectOne("select type_of_customer_sub_category, reference_name_1, reference_name_2 from consumer_application_element where application_id = ". $application_id);
        
        $typeOfCustomerSubCategory = $applicationElement->type_of_customer_sub_category ?? '';
        $reference_name_1 = $applicationElement->reference_name_1 ?? '';
        $reference_name_2 = $applicationElement->reference_name_2 ?? '';

        foreach ($requiredDoc as $doc) {
            if ($doc->file_type == 'tfr' || $doc->file_type == 'TFR') {
                $hasTfr = true;
            }
            if ($doc->file_type == 'proforma') {
                $hasSolarQuotation = true;
            }
            if ($merchant_id == _env('SSE_MERCHANT_ID')) { // advance receipt check not needed for SSE
                $hasAdvanceAmountReceipt = true;
            }
            if ($doc->file_type == 'advance_amount_receipt') {
                $hasAdvanceAmountReceipt = true;
            }
        }
        if (isset($verificationCall) || $digioVkyc){
            $hasVerificationCall = true;
        }
        if (!(new PostApprovalController())->checkTFRCondition($application_id)) {
            $hasTfr = true; // Checking TFR only for ongrid-residential & housing society cases
        }
        if (((!isset($hasSolarQuotation) || !isset($hasTfr)) && ($typeOfCustomerSubCategory != 'Aatta Chakki')) || !isset($hasAdvanceAmountReceipt) || (empty($hasVerificationCall)) || (empty($reference_name_1) && empty($reference_name_2))) {
            return false;
        }
        return true;
    }

    public function updateStatus($application_id)
    {
        request()->merge(['state' => 'disbursement checklist done', 'source' => 'hypothecation']);
        ;
        $consumerApplicationController = new ConsumerApplicationController();
        $consumerApplicationController->updateStatus($application_id);
    }

    public function addVCComment($applicationDetails)
    {
        $webhkController = new WebhookController();
        $comment = 'VC call is required to be done, if done kindly ignore.';
        if ($applicationDetails->merchant_id == _env('SSE_MERCHANT_ID')) {
            $advisorTag = $this->getSSEAdvisorsTag();
        }
        else {
            $advisorTag = $webhkController->getCommentTag(isset($applicationDetails->created_by) ? [$applicationDetails->created_by] : null);
        }
        $comment = $advisorTag . ' ' . $comment;
        (new GradeController(new Request))->addComment($applicationDetails->id, 107, $comment);
    }

    public function getSSEAdvisorsTag()
    {
        $advisorIds = [111488, 160455, 224937, 256509]; // SSE Advisors
        $advisorTag = (new WebhookController())->getCommentTag($advisorIds);
        return $advisorTag; // SSE Advisors
    }
}