<?php

namespace App\Http\Controllers\Admin;


use App\APIWrapper\Wrapper;
use App\ApplicationEMICalculation;
use App\ConsumerApplication;
use App\ConsumerApplicationFiles;
use App\DigitalSignDetails;
use App\HomevilleAssets;
use App\HomevilleDocument;
use App\HomevilleDocumentInfo;
use App\HomevilleLoans;
use App\HomevilleMandate;
use App\HomevilleTerms;
use App\Http\Controllers\Controller;
use App\Mandate;
use App\Method\Homeville\HomevilleMethods;
use App\Method\Homeville\Payload\Payload;
use Illuminate\Http\Request;
use App\StatusLogs;
use Illuminate\Support\Facades\Auth;

class HomevilleController extends Controller{

    private $request;
    public static $client_name = 'credit';
    private $token;

    public function __construct(Request $request){

        $this->request = $request;
    }

    public function checkWorthiness(){

        $wrapper = new Wrapper();
        $wrapperMethods = $wrapper->register(HomevilleMethods::class);
        $wrapper->payload->addPayload($this->request);
        $wrapperRes = $wrapperMethods->getToken($wrapper);
        if (isset($wrapperRes->response->token) && $wrapperRes->response->token){
            $this->token = $wrapperRes->response->token;
        }else{
            return response()->json(['status' => 'FAIL', 'data' => ['Message' => 'Auth token not received']]);
        }

        $wrapper->payload->addPayload(new Request(['id' => $this->request->get('id'), 'client_name' => self::$client_name, 'auth_token' => $this->token]));
        $wrapper->methods['headers']['Authorization'] = 'Bearer '.$this->token;
        $homevilleLoans = HomevilleLoans::where('application_id', $this->request->get('id'))->first(['id', 'status', 'case_id', 'response']);

        if (!isset($homevilleLoans->id)) {
            $wrapperRes = $wrapperMethods->createApplication($wrapper);
            if ($wrapperRes->errorBag) {
                return response()->json(['status' => 'FAIL', 'data' => array_filter($this->getErrors($wrapperRes->errorBag))]);
            }
        }else{
            $homevilleResponse = json_decode($homevilleLoans->response);
            $applicant_id = $homevilleResponse->data->applicants->applicant_id;
            $bank_detail_id = $homevilleResponse->data->bank_details->bank_detail_id[0] ?? 0;
            $wrapper->payload->addPayload(new Request(['id' => $this->request->get('id'), 'client_name' => self::$client_name, 'auth_token' => $this->token, 'case_id' => $homevilleLoans->case_id, 'applicant_id' => $applicant_id, 'bank_detail_id' => $bank_detail_id]));
            $wrapperRes = $wrapperMethods->updateApplication($wrapper);
            if ($wrapperRes->errorBag) {
                return response()->json(['status' => 'FAIL', 'data' => array_filter($this->getErrors($wrapperRes->errorBag))]);
            }
        }


        //Add Asset
        $homevilleAssets = HomevilleAssets::where('application_id', $this->request->get('id'))->first(['id', 'status']);
        if (!isset($homevilleAssets->id)) {

            /*$wrapperRes = $wrapperMethods->getSolarDetails($wrapper);
            if ($wrapperRes->errorBag) {
                return response()->json(['status' => 'FAIL', 'data' => array_filter($this->getErrors($wrapperRes->errorBag))]);
            }*/

            $wrapperRes = $wrapperMethods->addAsset($wrapper);
            if ($wrapperRes->errorBag) {
                return response()->json(['status' => 'FAIL', 'data' => array_filter($this->getErrors($wrapperRes->errorBag))]);
            }
        }
        //End


        $files = ConsumerApplicationFiles::where('consumer_application_id', $this->request->get('id'))
            ->whereNotIn('id', function ($query) {
                $query->select('consumer_application_file_id')
                    ->from('homeville_document');
            })
            ->whereIn('file_type', ['pan_card', 'aadhar_card_masked', 'aadhar_card', 'aadhar_card_back'])->get(['id', 'file_type', 'file_path', 'is_masked']);

        foreach($files as $file){
            if (!in_array($file->file_type, ['aadhar_card_back', 'aadhar_card_masked', 'aadhar_card']) || $file->is_masked) {
                $this->request->merge(['file_id' => $file->id, 'id' => $this->request->get('id')]);
                $uploadDocument = $this->sendDocument($this->request, $wrapper, $wrapperMethods, $file);
                $uploadDocumentArg = $uploadDocument->getData();

                if ($uploadDocumentArg->status == 'FAIL') {
                    return $uploadDocument;
                }
            }
        }
        //End


        //Loan terms
        $homevilleTerms = HomevilleTerms::where('application_id', $this->request->get('id'))->first(['id', 'status']);
        if(!isset($homevilleTerms->id)) {
            $wrapperRes = $wrapperMethods->loanTerms($wrapper);
            if ($wrapperRes->errorBag) {
                return response()->json(['status' => 'FAIL', 'data' => array_filter($this->getErrors($wrapperRes->errorBag))]);
            }
        }
        //End


        $status = StatusLogs::where('application_id', $this->request->get('id'))->where('status', 'disbursement checklist done')->first(['id']);
        if(isset($status->id)){
            return response()->json(['status' => 'OK', 'data' => array_filter(['Error'=>'After checklist process not enabled. Go-ahead'])]);
        }else{
            $application = ConsumerApplication::where('id', $this->request->get('id'))->first(['state']);
            if (isset($application->state) && $application->state == 'cf approved'){
                return response()->json(['status' => 'FAIL', 'data' => array_filter(['Error' => 'Case shared with Homeville, Waiting for Decision'])]);
            }else {
                return response()->json(['status' => 'FAIL', 'data' => array_filter(['Error' => 'Running Api on Wrong stage'])]);
            }
        }
    }

    public function getErrors($errors){
        $messages = [];
        if (is_object($errors['Error'])) {
            foreach ($errors['Error'] as $error) {
                $messages[] = $error[0];
            }
            return $messages;
        }
        $messages[] = $errors['Error'];
        return $messages;
    }

    public function getDocument(){
        $file_id = $this->request->get('file_id');
        $file = ConsumerApplicationFiles::where('id', $file_id)->first(['id','file_type', 'file_path']);
        $wrapper = new Wrapper();
        $wrapperMethods = $wrapper->register(HomevilleMethods::class);
        $wrapper->payload->addPayload($this->request);

        $wrapperRes = $wrapperMethods->getToken($wrapper);
        if (isset($wrapperRes->response->token) && $wrapperRes->response->token){
            $this->token = $wrapperRes->response->token;
        }else{
            return response()->json(['status' => 'FAIL', 'data' => ['Message' => 'Auth token not received']]);
        }

        return $this->sendDocument($this->request, $wrapper, $wrapperMethods, $file);
    }

    public function sendDocument($request, $wrapper, $wrapperMethods, $file){
        $documentsCount = HomevilleDocument::where('consumer_application_file_id', $file->id)->first(['id']);
        if (!isset($documentsCount->id)) {
            request()->merge(['consumer_application_file_id' => $file->id]);
            $filePath = storage_path($file->id . '_' . time()).'.'.$this->getFileExtension($file);
            $request->merge(['file_id' => $file->id, 'document_id' => $file->id, 'file_path' => $filePath, 'auth_token' => $this->token]);
            $wrapper->payload->addPayload($request);
            $wrapper->methods['headers']['Authorization'] = 'Bearer '.$this->token;
            $wrapperRes = $wrapperMethods->uploadDocument($wrapper);
            if (file_exists($filePath)) {
                unlink($filePath);
            }
            if ($wrapperRes->errorBag)
                return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag), 'message' => array_filter($wrapperRes->errorBag)]);
        }

        return response()->json(['status' => 'OK', 'data' => [], 'message' => 'Document Uploaded Successfully']);
    }

    public function generateDocument(){
        $wrapper = new Wrapper();
        $wrapperMethods = $wrapper->register(HomevilleMethods::class);
        $wrapper->payload->addPayload($this->request);

        $wrapperRes = $wrapperMethods->getToken($wrapper);
        if (isset($wrapperRes->response->token) && $wrapperRes->response->token){
            $this->token = $wrapperRes->response->token;
        }else{
            return response()->json(['status' => 'FAIL', 'data' => ['Message' => 'Auth token not received']]);
        }

        $wrapper->payload->addPayload(new Request(['id' => $this->request->get('id'), 'client_name' => self::$client_name, 'auth_token' => $this->token]));
        $wrapper->methods['headers']['Authorization'] = 'Bearer '.$this->token;

        $homevilleLoans = HomevilleLoans::where('application_id', $this->request->get('id'))->first(['id', 'case_id', 'response']);

        if (isset($homevilleLoans->id)) {
            $this->request->merge(['case_id' => $homevilleLoans->case_id]);

            $wrapper->payload->addPayload($this->request);
            $wrapperRes = $wrapperMethods->getFormFields($wrapper);

            if (isset($wrapperRes->response->status) && $wrapperRes->response->status == 'success') {
                foreach ($wrapperRes->response->data as $document) {

                    $homevilleDocumentInfo = HomevilleDocumentInfo::where('application_id', $this->request->get('id'))->where('doc_type', $document->document_type)->first(['id']);

                    if (!isset($homevilleDocumentInfo->id) && $wrapperRes) {

                        $emiCalculation = ApplicationEMICalculation::where('application_id', $this->request->get('id'))->first(['id', 'emi_date']);

                        $this->request->merge(['first_emi_date' => $emiCalculation->emi_date, 'doc_type' => $document->document_type]);

                        $wrapper->payload->addPayload($this->request);
                        $wrapperRes = $wrapperMethods->generateDocument($wrapper);

                        if ($wrapperRes->errorBag) {
                            $error =  response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag), 'message' => array_filter($wrapperRes->errorBag)]);
                        }
                    }

                }
            }

            if(isset($error)){
                return $error;
            }

            $wrapper->payload->addPayload($this->request);
            $wrapperRes = $wrapperMethods->masterDocumentAPI($wrapper);

            if ($wrapperRes->errorBag)
                return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag), 'message' => array_filter($wrapperRes->errorBag)]);


            $homevilleDocumentInfo = HomevilleDocumentInfo::where('application_id', $this->request->get('id'))->whereIn('doc_type', ['signed_document', 'sign_request'])->first(['id']);

            if (!isset($homevilleDocumentInfo->id)) {
                $document_lists = [];
                foreach ($wrapperRes->response->data as $docs) {
                    if (in_array($docs->file_type, ['hypothecation_letter', 'supplementary_loan_agreement_solar', 'key_fact_statement'])) {
                        $this->request->merge(['type_of_doc' => $docs->file_type]);
                        $wrapper->payload->addPayload($this->request);
                        $data = $wrapperMethods->getDocumentId($wrapper);

                        $document_lists[] = ['id' => $data->response->data->id, 'file_category' => $data->response->data->file_category];
                    }
                }

                if (empty($document_lists)) {
                    return response()->json(['status' => 'FAIL', 'data' => ['Message' => 'Document List to merge the signRequest is empty'], 'message' => 'Document List to merge the signRequest is empty']);
                }

                $wrapperRes = $wrapperMethods->getListOfESign($wrapper);

                if ($wrapperRes->errorBag)
                    return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag), 'message' => array_filter($wrapperRes->errorBag)]);

                $homevilleLoansResponse = json_decode($homevilleLoans->response);

                if (!isset($homevilleLoansResponse->data->platform_reference_id)) {
                    return response()->json(['status' => 'FAIL', 'data' => ['Message' => 'Platform Reference ID not found'], 'message' => 'Platform Reference ID not found']);
                }

                $this->request->merge(['signatories' => $wrapperRes->response->data->esign_signatories, 'document_lists' => $document_lists, 'platform_reference_id' => str_replace('BHN000', '', $homevilleLoansResponse->data->platform_reference_id)]);

                $wrapper->payload->addPayload($this->request);
                $wrapperRes = $wrapperMethods->signRequestMergeDocument($wrapper);
                if ($wrapperRes->errorBag)
                    return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag), 'message' => array_filter($wrapperRes->errorBag)]);
            }
        }

        return response()->json(['status' => 'OK', 'data' => [], 'message' => 'Document Generated Successfully']);
    }

    public function generateNACHMandate(){


        $homevilleMandate = HomevilleMandate::where('application_id', $this->request->get('id'))->first(['id', 'case_id', 'mandate_link']);
        if (isset($homevilleMandate->mandate_link)) {
            return response()->json(['status' => 'OK', 'data' => [], 'message' => 'Mandate Created Successfully', 'url' => $homevilleMandate->mandate_link]);
        }


        $wrapper = new Wrapper();
        $wrapperMethods = $wrapper->register(HomevilleMethods::class);
        $wrapper->payload->addPayload($this->request);

        $wrapperRes = $wrapperMethods->getToken($wrapper);
        if (isset($wrapperRes->response->token) && $wrapperRes->response->token){
            $this->token = $wrapperRes->response->token;
        }else{
            return response()->json(['status' => 'FAIL', 'data' => ['Message' => 'Auth token not received']]);
        }

        $wrapper->payload->addPayload(new Request(['id' => $this->request->get('id'), 'client_name' => self::$client_name, 'auth_token' => $this->token]));
        $wrapper->methods['headers']['Authorization'] = 'Bearer '.$this->token;

        $homevilleLoans = HomevilleLoans::where('application_id', $this->request->get('id'))->first(['case_id']);
        if (isset($homevilleLoans->case_id)) {
            $homevilleMandate = HomevilleMandate::where('application_id', $this->request->get('id'))->first(['id', 'case_id', 'mandate_link']);
            if (!isset($homevilleMandate->id)) {

                $application = ConsumerApplication::where('id', $this->request->get('id'))->first(['mobile_number', 'email']);

                $this->request->merge(['case_id' => $homevilleLoans->case_id, 'mobile_no' => $application->mobile_number, 'email_id' => $application->email]);

                $wrapper->payload->addPayload($this->request);
                $wrapperRes = $wrapperMethods->getApplicantBankDetails($wrapper);
                if (isset($wrapperRes->response->data[0]->id) && $wrapperRes->response->data[0]->id){

                    $this->request->merge(['id' => $this->request->get('id'), 'case_id' => $homevilleLoans->case_id, 'bank_id' => $wrapperRes->response->data[0]->id]);
                    $wrapper->payload->addPayload($this->request);
                    $wrapperRes = $wrapperMethods->generateNACHMandate($wrapper);

                    if ($wrapperRes->errorBag)
                        return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag), 'message' => array_filter($wrapperRes->errorBag)]);
                }else{
                    return response()->json(['status' => 'FAIL', 'data' => ['Message' => 'Auth token not received']]);
                }
            }
            $link = $homevilleMandate->mandate_link ?? ($wrapperRes->response->data->nach_url ? $wrapperRes->response->data->nach_url : '');
            if ($link) {
                return response()->json(['status' => 'OK', 'data' => [], 'message' => 'Mandate Created Successfully', 'url' => $link]);
            }
        }

        return response()->json(['status' => 'FAIL', 'data' => [], 'message' => 'Loan does not exists']);
    }

    private function getFileExtension($file){
        $getExtension = explode('.', $file->file_path);
        return $getExtension[count($getExtension) - 1] ?? 'pdf';
    }

    public function sendDocumentV1(){

        $application_id = $this->request->get('id');
        $file_id = $this->request->get('file_id');
        $uid = Auth::check() ? Auth::user()->id : 107;
        $application_files = ConsumerApplicationFiles::where('id', $file_id)->first(['file_type', 'file_path']);
        $wrapper = new Wrapper();
        $wrapperMethods = $wrapper->register(HomevilleMethods::class);
        $key = $application_files->file_type;
        if ($key == 'pan_card'){
            $param = "pancard";
        }
        if ($key == 'votar_id_front_masked' || $key == 'votar_id_back_masked' || $key == 'votar_id_front' || $key == 'votar_id_back'){
            $param = "VOTER_ID";
        }
        if ($key == 'passport_front_masked' || $key == 'passport_back_masked' || $key == 'passport_front' || $key == 'passport_back'){
            $param = "PASSPORT";
        }
        if ($key == 'aadhar_card_masked' || $key == 'aadhar_card_back_masked' || $key == 'aadhar_card' || $key == 'aadhar_card_back'){
            $param = "aadhar";
        }
        if ($key == 'driving_license_masked' || $key == 'driving_license'){
            $param = "OTHER";
        }
        if ($key == 'loan_agreement_esign'){
            $param = "LOAN_AGREEMENT";
        }
        if ($key == 'pro_forma_invoice'){
            $param = "OTHER";
        }
        if ($key == 'nach'){
            $param = "OTHER";
        }
        if (strpos($key, 'bank_statement') !== false){
            $param = "bank_statement_doc";
        }
        if ($key == 'security_cheques'){
            $param = "CHEQUE";
        }
        request()->merge(['id' => $application_id,'file_path' => $application_files->file_path, 'param' =>$param, 'file_id'=>$file_id, 'user_id'=>$uid]);
        $wrapper->payload->addPayload(new Request(['id' => $application_id,'file_path' => $application_files->file_path, 'param' =>$param, 'file_id'=>$file_id, 'user_id'=>$uid, 'auth_token' => $this->token]));
        $wrapper->methods['headers']['Authorization'] = 'Bearer '.$this->token;
        $wrapperRes = $wrapperMethods->uploadDocument($wrapper);
        if (isset($wrapperRes->success) && $wrapperRes->success == true) {
            $fileArray = explode("/", $application_files->file_path);
            $file_name = end($fileArray);
            $file_tmp_path = storage_path().'/'.$file_name;
            return response()->json(['status' => 'OK', 'message' => 'Upload Document Triggered.']);
        }
        return response()->json(['status' => 'FAIL', 'message' => $wrapperRes->errorBag]);
    }

    public function getDocumentMapping(){
        $mappedDocumentExists = [];
        $payload = new Payload();
        $file_types = $payload->getFileType();
        if(!$this->request->has('file_type')) {
            $files = ConsumerApplicationFiles::where('consumer_application_id', $this->request->get('id'))->orderBy('created_at', 'DESC')->get(['id', 'file_type']);
            foreach ($files as $file) {
                if (!is_array($payload->getDocumentName($file_types, $file->file_type))) {
                    $filesExistIds[$file->file_type][] = $file->id;
                    $mappedDocumentExists[$file->file_type] = $file->file_type;
                }
            }
        }else{
            if (!is_array($payload->getDocumentName($file_types, $this->request->get('file_type')))) {
                $filesExistIds[$this->request->get('file_type')][] = $this->request->get('file_id');
                $mappedDocumentExists[$this->request->get('file_type')] = $this->request->get('file_id');
            }
        }

        $mappedDocumentAvExists = [];
        if (isset($filesExistIds) && $filesExistIds) {
            foreach ($filesExistIds as $mainKey => $filesExistId) {
                $avansePushed = HomevilleDocument::where('application_id', $this->request->get('id'))->whereIn('consumer_application_file_id', $filesExistId)->first();
                if (isset($avansePushed->id)) {
                    $mappedDocumentAvExists[$mainKey] = $mainKey;
                }
            }
        }

        return [$mappedDocumentExists, $mappedDocumentAvExists];
    }
}
