import json
import traceback
from datetime import datetime, timedelta
from flask import request, Flask
from flask_cors import CORS
import time

import config
from utils.aws_s3 import s3_upload, s3_read_file, s3_check_exists
from crud.crud_bureau import add_pan_details, save_equifax_bureau_data, \
    save_experian_bureau_data, check_credit_report
from crud.crud_pan import save_pan_data
from clients.bureau import send_equifax_bureau_request, send_experian_bureau_request, send_soft_experian_bureau_request, \
    check_experian_bureau_report, check_soft_experian_bureau_report
from clients.pan_card import send_equifax_pan_validation_request, send_decentro_pan_validation_request, \
    check_equifax_pan_report
from response_templates import failure_response, success_response, response_list
from middleware.middleware import Middleware
from middleware.jify_middleware import JifyMiddleware
from utils.hashing import hashids
from log_config.logger import print_log

app = Flask(__name__)
app.config['SECRET_KEY'] = config.SECRET_KEY  # str(uuid.uuid4())


@app.before_request
def custom_auth_middleware():
    if request.method != 'OPTIONS':
        if request.json.get('vendor') == 'jify':
            auth_value = JifyMiddleware().auth(request)
        else:
            auth_value = Middleware().auth(request)
        if not auth_value:
            return response_list.authorization_fail
        return None


@app.route("/api/get-bureau-response", methods=["POST"])
def fetch_hard_bureau():
    try:
        vendor = request.json['vendor']
        print_log('Entered Bureau Pull', vendor)
        print_log(request.json, vendor)
        pull_type = request.json['pull_type'] if 'pull_type' in request.json else 'hard'
        request_application_id = request.json['application_id']
        if not request_application_id.isnumeric():
            application_id = str(hashids.decode(request_application_id)[0])
        else:
            application_id = request_application_id
        applicant_type = request.json['applicant_type']
        request_type = request.json['request_type']
        skip_pan_validation = True if request.json.get("skip_pan_validation") else False
        path = 'emp-application/jiffy/' if request.json['vendor'] == 'jify' else ''
        timestamp = datetime.now()
        if 'only_pan' in request.json:
            only_pan = False if request.json['only_pan'] == 0 else True
        else:
            only_pan = False
        generate_experian, generate_equifax = False, False
        file_name_pan, bureau_name_pan = '_response_pan_valid', '_response'
        raw_xml_name = '_response_raw_' + request_type
        pan_data = {}
        pan_vendor_name = 'Decentro'
        if request_type != 'customer':
            file_name_pan = '_response_pan_valid_' + request_type
            bureau_name_pan = '_response'
        if applicant_type == "2":
            file_name_pan = '_response_pan_valid_' + applicant_type
            bureau_name_pan = '_response_' + applicant_type
        capital = 'capital/' + application_id if only_pan else path + application_id
        fnp_name = application_id + file_name_pan + '.json'
        bnp_name = application_id + bureau_name_pan + '.json'
        raw_xml = application_id + raw_xml_name + '.xml'

        s3_file_check = s3_check_exists(capital + '/' + fnp_name)
        print_log('Application ID: ' + str(application_id), vendor)
        if request.json['vendor'] != 'jify' and pull_type == 'soft':
            response = fetch_soft_bureau()
            if response[1] == 200:
                return success_response(status_code=200, status='OK', message='Fetched Bureau Successfully',
                                        data={})
        if s3_file_check and s3_file_check['ContentLength']:
            pan_data = json.loads(s3_read_file(capital + '/' + fnp_name))
            generate_experian = True
            print_log('PAN fetched from S3', vendor)
        else:
            print_log('PAN not available in S3', vendor)
            if not skip_pan_validation:
                decentro_pan_data = send_decentro_pan_validation_request(vendor)  # Decentro PAN data validation API
                decentro_pan_data = json.loads(json.dumps(decentro_pan_data))
                decentro_pan_data.update({"panVendor": pan_vendor_name})
                if "status" in decentro_pan_data and decentro_pan_data["status"] == "SUCCESS" and decentro_pan_data[
                        "kycStatus"] == "SUCCESS":
                    pan_data = decentro_pan_data
                    print_log('Decentro PAN Uploading to S3', vendor)
                    s3_upload(capital, fnp_name, pan_data,)
                    generate_experian = True
                    print_log('Decentro PAN S3 upload complete', vendor)
                elif "status" in decentro_pan_data and (
                        decentro_pan_data["status"] == "FAILURE" or decentro_pan_data["kycStatus"] == "FAILURE"):
                    print_log('Decentro PAN failed, moving to Equifax', vendor)
                    equifax_pan_data = send_equifax_pan_validation_request(vendor)  # Equifax PAN data validation API
                    equifax_pan_data = json.loads(json.dumps(equifax_pan_data))
                    pan_vendor_name = 'Equifax'
                    equifax_pan_data.update({"panVendor": pan_vendor_name})
                    pan_data = equifax_pan_data
                    equifax_report, error = check_equifax_pan_report(pan_data, vendor)
                    if equifax_report:
                        print_log('Equifax: No error, S3 upload started', vendor)
                        s3_upload(capital, fnp_name, pan_data)
                        generate_experian = True
                        print_log('Equifax S3 upload complete', vendor)
                    else:
                        print_log('PAN failed exiting', vendor)
                        return failure_response(status_code=400, error=decentro_pan_data['error']['responseCode'], status='FAIL')
                elif only_pan:
                    add_pan_details(timestamp, pan_data)
                    return pan_data
            else:
                generate_experian = True

        if generate_experian:
            print_log('Entered Experian Bureau Fetching', vendor)
            bureau_name = 'Experian'
            experian_error = None
            exists = s3_check_exists(capital + '/' + bnp_name)
            if exists and exists['ContentLength']:
                print_log('Bureau found in S3', vendor)
                experian_bureau_data = json.loads(s3_read_file(capital + '/' + bnp_name))
                experian_bureau_data.update({"panVendor": pan_vendor_name, "bureauName": bureau_name})
                if not check_credit_report(application_id, applicant_type):
                    print_log('Not found in database, saving to database', vendor)
                    save_experian_bureau_data(pull_type, experian_bureau_data, application_id, applicant_type, timestamp
                                              , pan_data, vendor)
                    time.sleep(2)
                # with open('/Users/abhishek/Downloads/453_response_bureau_valid_hardQH.json', 'r') as f:
                #     experian_json = json.load(f)
                #     save_experian_bureau_data(pull_type, experian_json, application_id, applicant_type, timestamp
                #                               , pan_data, vendor)  # added for testing, remove before deploy
                return success_response(status_code=200, data={}, status='OK', message='Fetched Bureau Successfully')

            else:
                print_log('Bureau not found in S3', vendor)
                if pull_type == 'hard' or experian_error:
                    s3_data, experian_bureau_data = send_experian_bureau_request(capital, raw_xml, vendor)  # Experian bureau data fetching API
                    soap_env = "SOAP-ENV"
                    experian_error = check_experian_bureau_report(experian_bureau_data, soap_env, vendor)
                    if experian_error:
                        print_log('Experian Bureau Pull error', vendor)
                        generate_equifax = True
                        # experian_bureau_data.update({"panVendor": pan_vendor_name, "bureauName": bureau_name})

                    else:
                        print_log('Experian Bureau Pull Success, starting S3 upload', vendor)
                        # s3_state = s3_upload(capital, raw_xml, experian_bureau_data)
                        s3_state = s3_upload(capital, bnp_name, s3_data)
                        if s3_state:
                            print_log('S3 upload success', vendor)
                            save_experian_bureau_data(pull_type, s3_data, application_id, applicant_type, timestamp
                                                      , pan_data, vendor)  # Experian bureau data saving API
                            print_log('Database operation complete', vendor)
                            time.sleep(2)
                            return success_response(status_code=200, status='OK', message='Fetched Bureau Successfully', data={})

        if generate_equifax:
            print_log('Equifax Bureau Pull entered', vendor)
            bureau_name = 'Equifax'
            exists = s3_check_exists(capital + '/' + bnp_name)
            if exists and exists['ContentLength']:
                print_log('Bureau Found in S3', vendor)
                equifax_bureau_data = json.loads(s3_read_file(capital + '/' + bnp_name))
                equifax_bureau_data.update({"panVendor": pan_vendor_name, "bureauName": bureau_name})
                if not check_credit_report(application_id, applicant_type):
                    print_log('Not found in database, saving to database', vendor)
                    save_equifax_bureau_data(equifax_bureau_data, application_id,
                                             applicant_type, timestamp, pan_data, vendor)
                    time.sleep(2)
                # with open('/Users/abhishek/Downloads/165.json', 'r') as f:
                #     equifax_json = json.load(f)
                #     save_equifax_bureau_data(equifax_json, application_id,
                #                              applicant_type, timestamp, pan_data)  # for testing, remove before deploy
                return success_response(status_code=200, message='Fetched Bureau Successfully', status='OK', data={})

            else:
                equifax_bureau_data = send_equifax_bureau_request(capital, raw_xml, vendor)  # Equifax bureau data fetching API
                equifax_bureau_data.update({"panVendor": pan_vendor_name, "bureauName": bureau_name})
                equifax_bureau_data_report = []
                print_log('Checking Equifax Bureau Pull response', vendor)
                response_equifax_bureau = equifax_bureau_data["soapenv:Envelope"]["soapenv:Body"]["sch:InquiryResponse"]
                print_log(response_equifax_bureau, vendor)
                if "sch:ReportData" in response_equifax_bureau:
                    if "sch:VerifyIDResponse" in response_equifax_bureau["sch:ReportData"]:
                        if "sch:vidNsdlResponses" in response_equifax_bureau["sch:ReportData"]["sch:VerifyIDResponse"]:
                            if "sch:nsdlResponse" in response_equifax_bureau["sch:ReportData"]["sch:VerifyIDResponse"]["sch:vidNsdlResponses"]:
                                equifax_bureau_data_report = response_equifax_bureau["sch:ReportData"]["sch:VerifyIDResponse"]["sch:vidNsdlResponses"][
                                    "sch:nsdlResponse"]

                    if "sch:returnCode" in equifax_bureau_data_report and "E" in equifax_bureau_data_report["sch:returnCode"]:
                        return json.dumps(equifax_bureau_data_report)
                    if "sch:Error" in response_equifax_bureau["sch:ReportData"]:
                        if "sch:ErrorCode" in response_equifax_bureau["sch:ReportData"]["sch:Error"] and \
                                response_equifax_bureau["sch:ReportData"]["sch:Error"]["sch:ErrorMsg"] is not None:
                            # NTC case handling
                            if (response_equifax_bureau["sch:ReportData"]["sch:Error"]["sch:ErrorMsg"] == 'Consumer record not found'
                                    and response_equifax_bureau["sch:ReportData"]["sch:Error"]["sch:ErrorCode"] == '00'):
                                s3_state = s3_upload(capital, bnp_name, equifax_bureau_data)
                                save_equifax_bureau_data(equifax_bureau_data, application_id,
                                                         applicant_type, timestamp, pan_data, vendor)
                                return success_response(status_code=200, data={}, message='Consumer record not found',status='OK')
                            else:
                                equifax_error = json.dumps(response_equifax_bureau["sch:ReportData"]["sch:Error"])
                                return failure_response(status_code=400, error=experian_error, status='FAIL')
                    else:
                        print_log('Equifax Bureau pull check success', vendor)
                        s3_state = s3_upload(capital, bnp_name, equifax_bureau_data)
                        if s3_state:
                            print_log('Equifax S3 upload complete', vendor)
                            save_equifax_bureau_data(equifax_bureau_data, application_id,
                                                     applicant_type, timestamp, pan_data, vendor)  # Equifax bureau saving API
                            print_log('Equifax database save complete', vendor)
                            time.sleep(2)
                            return success_response(status_code=200, data={}, message='Fetched Bureau Successfully', status='OK')
                else:
                    print_log('Error in response received', vendor)
                    return failure_response(status_code=400, error='Bad request', status='FAIL')

    except Exception as ex:
        vendor = request.json['vendor']
        print_log(traceback.print_exc(), vendor)
        return failure_response(status_code=400, error='Bad Request', status='FAIL')


@app.route("/api/get-soft-bureau-response", methods=["POST"])
def fetch_soft_bureau():
    try:
        pull_type = 'soft'
        vendor = request.json['vendor']
        print_log(request.json, vendor)
        request_application_id = request.json['application_id']
        if not request_application_id.isnumeric():
            application_id = str(hashids.decode(request_application_id)[0])
        else:
            application_id = request_application_id
        applicant_type = request.json['applicant_type']
        request_type = request.json['request_type']
        last_name = request.json['last_name'].replace("+", " ").replace("%20", " ")
        first_name = request.json['first_name'].replace("+", " ").replace("%20", " ")
        mobile_number = request.json['mobile_number']
        pan_card = request.json['pan_card'] if 'pan_card' in request.json else None
        pre_eligibility = True if request.json.get("pre_eligibility") else False
        timestamp = datetime.now()

        pan_data = {}
        bureau_name_pan = '_response_experian_' + pull_type + '_' + str(applicant_type)
        raw_xml_name = '_response_raw_' + request_type + '_' + pull_type
        file_name_pan = '_response_pan_valid_' + str(applicant_type)

        bnp_name = application_id + bureau_name_pan + '.json'
        raw_xml = application_id + raw_xml_name + '.xml'
        fnp_name = application_id + file_name_pan + '.json'

        skip_pan_validation = True if request.json.get("skip_pan_validation") else False
        s3_prefix = 'pre_eligibility/' + application_id if pre_eligibility else application_id

        s3_file_check = s3_check_exists(s3_prefix + '/' + fnp_name)
        print_log('Application ID: ' + str(application_id), vendor)
        if s3_file_check and s3_file_check['ContentLength']:
            pan_data = json.loads(s3_read_file(s3_prefix + '/' + fnp_name))
            print_log('PAN fetched from S3', vendor)
        else:
            print_log('PAN not available in S3', vendor)
            pan_vendor_name = 'Decentro'
            if pan_card and not skip_pan_validation:
                decentro_pan_data = send_decentro_pan_validation_request(vendor)  # Decentro PAN data validation API
                decentro_pan_data = json.loads(json.dumps(decentro_pan_data))
                decentro_pan_data.update({"panVendor": pan_vendor_name})
                if "status" in decentro_pan_data and decentro_pan_data["status"] == "SUCCESS" and decentro_pan_data["kycStatus"] == "SUCCESS":
                    pan_data = decentro_pan_data
                    print_log('Decentro PAN Uploading to S3', vendor)
                    s3_upload(s3_prefix, fnp_name, pan_data)
                    print_log('Decentro PAN S3 upload complete', vendor)
                elif "status" in decentro_pan_data and (
                        decentro_pan_data["status"] == "FAILURE" or decentro_pan_data["kycStatus"] == "FAILURE"):
                    print_log('Decentro PAN failed, moving to Equifax', vendor)
                    equifax_pan_data = send_equifax_pan_validation_request(vendor)  # Equifax PAN data validation API
                    equifax_pan_data = json.loads(json.dumps(equifax_pan_data))
                    pan_vendor_name = 'Equifax'
                    equifax_pan_data.update({"panVendor": pan_vendor_name})
                    pan_data = equifax_pan_data
                    equifax_report, error = check_equifax_pan_report(pan_data, vendor)
                    if equifax_report:
                        print_log('Equifax: No error, S3 upload started', vendor)
                        s3_upload(s3_prefix, fnp_name, pan_data)
                        print_log('Equifax S3 upload complete', vendor)
                    else:
                        print_log('PAN failed exiting '+decentro_pan_data['error']['responseCode'], vendor)
                        return failure_response(status_code=400, error=decentro_pan_data['error']['responseCode'], status='FAIL')

        bureau_name = 'Experian'
        print_log('Checking in S3.....', vendor)
        exists = s3_check_exists(s3_prefix + '/' + bnp_name)
        if exists and exists['ContentLength']:
            print_log('File found in S3', vendor)
            experian_bureau_data = json.loads(s3_read_file(s3_prefix + '/' + bnp_name))
            experian_bureau_data.update({"bureauName": bureau_name})
            if not check_credit_report(application_id, applicant_type, pre_eligibility):
                print_log('Not found in database, saving to database', vendor)
                save_experian_bureau_data(pull_type, experian_bureau_data, application_id, applicant_type, timestamp, pan_data, vendor, pre_eligibility)
            return success_response(status_code=200, data={}, status='OK', message='Fetched Bureau Successfully')
        else:
            print_log('File not found in S3', vendor)
            soft_s3_data, experian_bureau_data = send_soft_experian_bureau_request(first_name, last_name, mobile_number, application_id, raw_xml, vendor, pan_card)
            soap_env = "soapenv"
            experian_error = check_soft_experian_bureau_report(experian_bureau_data, soap_env)

            if experian_error and experian_error != 'SYS100004 (No record found)':
                print_log('Error in experian soft pull: ' + experian_error, vendor)
                experian_bureau_data.update({"bureauName": bureau_name})
                return success_response(status_code=400, message=experian_error, status='FAIL', data={})
            else:
                print_log('Experian soft pull success, saving to S3 & database', vendor)
                s3_upload(s3_prefix, bnp_name, soft_s3_data)
                save_experian_bureau_data(pull_type, soft_s3_data, application_id, applicant_type, timestamp, pan_data, vendor, pre_eligibility)
                return success_response(status_code=200, status='OK', message='Bureau Fetched Successfully', data={})

    except Exception as ex:
        vendor = request.json['vendor']
        print_log(traceback.print_exc())
        return success_response(status_code=400, message='Bad Request', status='FAIL', data={})


@app.route("/api/get-credit-response", methods=["POST"])
def fetch_credit_report():
    pull_type = 'soft'
    vendor = request.json['vendor']
    print_log(request.json, vendor)
    request_application_id = request.json['application_id']
    if not str(request_application_id).isnumeric():
        application_id = str(hashids.decode(request_application_id)[0])
    else:
        application_id = str(request_application_id)
    applicant_type = request.json['applicant_type']
    request_type = request.json['request_type']
    last_name = request.json['last_name'].replace("+", " ").replace("%20", " ")
    first_name = request.json['first_name'].replace("+", " ").replace("%20", " ")
    mobile_number = request.json['mobile_number']
    pan_card = request.json['pan_card'] if 'pan_card' in request.json else None
    timestamp = datetime.now() + timedelta(hours=5, minutes=30) if request.json['vendor'] == 'admin' else datetime.now()

    bureau_name_pan = '_response_experian_' + pull_type + '_' + str(applicant_type)
    raw_xml_name = '_response_raw_' + request_type + '_' + pull_type

    bnp_name = application_id + bureau_name_pan + '.json'
    raw_xml = application_id + raw_xml_name + '.xml'

    bureau_name = 'Experian'
    print_log('Checking in S3.....', vendor)
    exists = s3_check_exists(application_id + '/' + bnp_name)
    if exists and exists['ContentLength']:
        print_log('File found in S3', vendor)
        experian_bureau_data = json.loads(s3_read_file(application_id + '/' + bnp_name))
        experian_bureau_data.update({"bureauName": bureau_name})
        if not check_credit_report(application_id, applicant_type):
            print_log('Not found in database, saving to database', vendor)
            save_experian_bureau_data(pull_type, experian_bureau_data, application_id, applicant_type, timestamp,
                                      {}, vendor)
        return success_response(status_code=200, data={}, status='OK', message='Fetched Bureau Successfully')
    else:
        print_log('File not found in S3', vendor)
        soft_s3_data, experian_bureau_data = send_soft_experian_bureau_request(first_name, last_name, mobile_number,
                                                                               application_id, raw_xml, vendor,
                                                                               pan_card)
        soap_env = "soapenv"
        soft_experian_error = check_soft_experian_bureau_report(experian_bureau_data, soap_env)

    if not soft_experian_error:
        print_log('Experian soft pull success, saving to S3 & database', vendor)
        s3_upload(application_id, bnp_name, soft_s3_data)
        save_experian_bureau_data(pull_type, soft_s3_data, application_id, applicant_type, timestamp, {}, vendor)
        return success_response(status_code=200, status='OK', message='Fetched Bureau Successfully', data={})
    else:
        pull_type = 'hard'
        bureau_name_pan = '_response'
        raw_xml_name = '_response_raw_' + request_type
        if request_type != 'customer':
            bureau_name_pan = '_response'
        if applicant_type == "2":
            bureau_name_pan = '_response_' + applicant_type
        capital = application_id
        bnp_name = application_id + bureau_name_pan + '.json'
        raw_xml = application_id + raw_xml_name + '.xml'
        generate_equifax = False
        bureau_name = 'Experian'
        exists = s3_check_exists(capital + '/' + bnp_name)
        if exists and exists['ContentLength']:
            print_log('Bureau found in S3', vendor)
            experian_bureau_data = json.loads(s3_read_file(capital + '/' + bnp_name))
            experian_bureau_data.update({"panVendor": None, "bureauName": bureau_name})
            if not check_credit_report(application_id, applicant_type):
                print_log('Not found in database, saving to database', vendor)
                save_experian_bureau_data(pull_type, experian_bureau_data, application_id, applicant_type, timestamp
                                          , {}, vendor)
            return success_response(status_code=200, data={}, status='OK', message='Fetched Bureau Successfully')
        else:
            print_log('Bureau not found in S3', vendor)
            if soft_experian_error:
                s3_data, experian_bureau_data = send_experian_bureau_request(capital, raw_xml,
                                                                             vendor)  # Experian bureau data fetching API
                soap_env = "SOAP-ENV"
                hard_experian_error = check_experian_bureau_report(experian_bureau_data, soap_env, vendor)
                if hard_experian_error:
                    print_log('Experian Bureau Pull error', vendor)
                    generate_equifax = True
                else:
                    print_log('Experian Bureau Pull Success, starting S3 upload', vendor)
                    s3_state = s3_upload(capital, bnp_name, s3_data)
                    if s3_state:
                        print_log('S3 upload success', vendor)
                        save_experian_bureau_data(pull_type, s3_data, application_id, applicant_type, timestamp
                                                  , {}, vendor)  # Experian bureau data saving API
                        print_log('Database operation complete', vendor)
                        return success_response(status_code=200, status='OK', message='Fetched Bureau Successfully',
                                                data={})
        if generate_equifax:
            print_log('Equifax Bureau Pull entered', vendor)
            bureau_name = 'Equifax'
            exists = s3_check_exists(capital + '/' + bnp_name)
            if exists and exists['ContentLength']:
                print_log('Bureau Found in S3', vendor)
                equifax_bureau_data = json.loads(s3_read_file(capital + '/' + bnp_name))
                equifax_bureau_data.update({"panVendor": None, "bureauName": bureau_name})
                if not check_credit_report(application_id, applicant_type):
                    print_log('Not found in database, saving to database', vendor)
                    save_equifax_bureau_data(equifax_bureau_data, application_id,
                                             applicant_type, timestamp, {}, vendor)
                return success_response(status_code=200, message='Fetched Bureau Successfully', status='OK', data={})

            else:
                equifax_bureau_data = send_equifax_bureau_request(capital, raw_xml, vendor)  # Equifax bureau data fetching API
                equifax_bureau_data.update({"panVendor": None, "bureauName": bureau_name})
                equifax_bureau_data_report = {}
                print_log('Checking Equifax Bureau Pull response', vendor)
                response_equifax_bureau = equifax_bureau_data["soapenv:Envelope"]["soapenv:Body"]["sch:InquiryResponse"]
                print_log(response_equifax_bureau, vendor)
                if "sch:ReportData" in response_equifax_bureau:
                    if "sch:VerifyIDResponse" in response_equifax_bureau["sch:ReportData"]:
                        if "sch:vidNsdlResponses" in response_equifax_bureau["sch:ReportData"]["sch:VerifyIDResponse"]:
                            if "sch:nsdlResponse" in response_equifax_bureau["sch:ReportData"]["sch:VerifyIDResponse"]["sch:vidNsdlResponses"]:
                                equifax_bureau_data_report = response_equifax_bureau["sch:ReportData"]["sch:VerifyIDResponse"]["sch:vidNsdlResponses"][
                                    "sch:nsdlResponse"]

                    if "sch:returnCode" in equifax_bureau_data_report and "E" in equifax_bureau_data_report.get(
                        "sch:returnCode"):
                        return json.dumps(equifax_bureau_data_report)
                    if "sch:Error" in response_equifax_bureau["sch:ReportData"]:
                        if "sch:ErrorCode" in response_equifax_bureau["sch:ReportData"]["sch:Error"] and \
                                response_equifax_bureau["sch:ReportData"]["sch:Error"]["sch:ErrorMsg"] is not None:
                            # NTC case handling
                            if (response_equifax_bureau["sch:ReportData"]["sch:Error"][
                                "sch:ErrorMsg"] == 'Consumer record not found'
                                    and response_equifax_bureau["sch:ReportData"]["sch:Error"][
                                        "sch:ErrorCode"] == '00'):
                                s3_state = s3_upload(capital, bnp_name, equifax_bureau_data)
                                save_equifax_bureau_data(equifax_bureau_data, application_id,
                                                         applicant_type, timestamp, {}, vendor)
                                return success_response(status_code=200, data={}, message='Consumer record not found',
                                                        status='OK')
                            else:
                                equifax_error = json.dumps(response_equifax_bureau["sch:ReportData"]["sch:Error"])
                                return failure_response(status_code=400, error=equifax_error, status='FAIL')
                    else:
                        print_log('Equifax Bureau pull check success', vendor)
                        s3_state = s3_upload(capital, bnp_name, equifax_bureau_data)
                        if s3_state:
                            print_log('Equifax S3 upload complete', vendor)
                            save_equifax_bureau_data(equifax_bureau_data, application_id,
                                                     applicant_type, timestamp, {}, vendor)  # Equifax bureau saving API
                            print_log('Equifax database save complete', vendor)
                            return success_response(status_code=200, data={}, message='Fetched Bureau Successfully', status='OK')
                else:
                    print_log('Error in response received', vendor)
                    return failure_response(status_code=400, error='Bad request', status='FAIL')


@app.route("/api/validate-pan", methods=["POST"])
def pan_validation():
    vendor = request.json['vendor']
    print_log(request.json, vendor)
    request_application_id = request.json['application_id']
    applicant_type = request.json.get('applicant_type', '1')
    if not str(request_application_id).isnumeric():
        application_id = str(hashids.decode(request_application_id)[0])
    else:
        application_id = request_application_id
    fnp_name = str(application_id) + '_response_pan_valid_' + str(applicant_type) + '.json'
    s3_file_check = s3_check_exists(str(application_id) + '/' + fnp_name)
    if s3_file_check and s3_file_check['ContentLength']:
        print_log('PAN fetched from S3', vendor)
    else:
        print_log('PAN not available in S3', vendor)
        decentro_pan_data = send_decentro_pan_validation_request(vendor)  # Decentro PAN data validation API
        decentro_pan_data = json.loads(json.dumps(decentro_pan_data))
        decentro_pan_data.update({"panVendor": 'Decentro'})
        if decentro_pan_data.get("status") == "SUCCESS" and decentro_pan_data.get("kycStatus") == "SUCCESS":
            pan_data = decentro_pan_data
            s3_upload(str(application_id), fnp_name, pan_data, )
            print_log('Decentro PAN S3 upload complete', vendor)
            save_pan_data(application_id, pan_data)
        elif decentro_pan_data.get("status") == "FAILURE" or decentro_pan_data.get("kycStatus") == "FAILURE":
            print_log('Decentro PAN failed, moving to Equifax', vendor)
            equifax_pan_data = send_equifax_pan_validation_request(vendor)  # Equifax PAN data validation API
            equifax_pan_data = json.loads(json.dumps(equifax_pan_data))
            equifax_pan_data.update({"panVendor": 'Equifax'})
            pan_data = equifax_pan_data
            equifax_report, error = check_equifax_pan_report(pan_data, vendor)
            if not equifax_report:
                s3_upload(str(application_id), fnp_name, pan_data)
                print_log('Equifax S3 upload complete', vendor)
                save_pan_data(application_id, pan_data)
            else:
                print_log('PAN failed exiting', vendor)
                return failure_response(status_code=400, error=decentro_pan_data['error']['responseCode'],
                                        status='FAIL')
    return success_response(status_code=200, status='OK', message='PAN Validation Success', data={})


@app.route("/api/get-jiffy-response", methods=["POST"])
def print_jiffy_response():
    application_id = request.json['applicationNo']
    print(request.json)
    print('Success python')
    s3_upload(str(application_id), 'JIFFY_WEBHOOK_RESPONSE_'+str(application_id), request.json)
    return 'Success python'


@app.route("/api/webhook", methods=["POST"])
def webhook():
    print_log(request.json, 'admin')
    return '200'


CORS(app, supports_credentials=True, origins=config.ORIGINS)

if __name__ == "__main__":
    app.run(host=config.host, port=config.port,)
