import xmltodict
import requests
import json
import traceback
import sys

from utils.aws_s3 import s3_upload
from log_config.logger import print_log
from crud.crud_bureau import get_state_code_equifax
import config
from clients.set_request_parameters import get_request_params


def send_experian_bureau_request(capital, raw_xml, vendor=None):
    try:
        request_params = get_request_params('Experian')

        sm_template = """<?xml version="1.0" encoding="UTF-8"?>
        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:cbv2">
            <soapenv:Header/>
            <soapenv:Body>
                <urn:process>
                    <urn:in>
                        <INProfileRequest>
                            <Identification>
                                <XMLUser>%s</XMLUser>
                                <XMLPassword>%s</XMLPassword>
                            </Identification>
                            <Application>
                                <FTReferenceNumber/>
                                <CustomerReferenceID/>
                                <EnquiryReason>%s</EnquiryReason>
                                <FinancePurpose>%s</FinancePurpose>
                                <AmountFinanced>%s</AmountFinanced>
                                <DurationOfAgreement>0</DurationOfAgreement>
                                <ScoreFlag>%s</ScoreFlag>
                                <PSVFlag>0</PSVFlag>
                            </Application>
                            <Applicant>
                                <Surname>%s</Surname>
                                <FirstName>%s</FirstName>
                                <MiddleName1/>
                                <MiddleName2/>
                                <MiddleName3/>
                                <GenderCode>%s</GenderCode>
                                <IncomeTaxPAN>%s</IncomeTaxPAN>
                                <PANIssueDate/>
                                <PANExpirationDate/>
                                <PassportNumber/>
                                <PassportIssueDate/>
                                <PassportExpirationDate/>
                                <VoterIdentityCard/>
                                <VoterIDIssueDate/>
                                <VoterIDExpirationDate/>
                                <DriverLicenseNumber/>
                                <DriverLicenseIssueDate/>
                                <DriverLicenseExpirationDate/>
                                <RationCardNumber/>
                                <RationCardIssueDate/>
                                <RationCardExpirationDate/>
                                <UniversalIDNumber/>
                                <UniversalIDIssueDate/>
                                <UniversalIDExpirationDate/>
                                <DateOfBirth>%s</DateOfBirth>
                                <STDPhoneNumber/>
                                <PhoneNumber>%s</PhoneNumber>
                                <TelephoneExtension/>
                                <TelephoneType/>
                                <MobilePhone>%s</MobilePhone>
                                <EMailId/>
                            </Applicant>
                            <Details>
                                <Income/>
                                <MaritalStatus/>
                                <EmployStatus/>
                                <TimeWithEmploy/>
                                <NumberOfMajorCreditCardHeld/>
                            </Details>
                            <Address>
                                <FlatNoPlotNoHouseNo>%s</FlatNoPlotNoHouseNo>
                                <BldgNoSocietyName/>
                                <RoadNoNameAreaLocality/>
                                <City>%s</City>
                                <Landmark/>
                                <State>%s</State>
                                <PinCode>%s</PinCode>
                            </Address>
                            <AdditionalAddressFlag>
                                <Flag>N</Flag>
                            </AdditionalAddressFlag>
                        </INProfileRequest>
                    </urn:in>
                </urn:process>
            </soapenv:Body>
        </soapenv:Envelope>
        """

        soap_message = sm_template % (
            request_params["UserId"], request_params["Password"], request_params["InquiryReason"],
            request_params["Purpose"],
            request_params["LoanAmount"], request_params["Score"], request_params["LastName"], request_params["FirstName"],
            request_params["Gender"], request_params["PanCard"], request_params["DOB"], request_params["PhoneNumber"],
            request_params["MobileNumber"],
            request_params["Address"], request_params["City"], request_params["State"], request_params["PostalCode"])
        url = config.EXPERIAN_URL
        print_log('Experian Bureau Pull Request created', vendor)
        s3_state = s3_upload(capital, capital + '_request_experian.xml', soap_message)
        response = requests.post(url, data=soap_message, verify=False)
        print_log('Experian Bureau Pull response received', vendor)
        temp = xmltodict.parse(response.content)
        # with open('/Users/abhishek/Downloads/5099_response_raw_customer_experian.json', 'r') as f:
        #     temp = json.load(f)
        raw_xml = raw_xml.split('.')[0] + '_experian.' + raw_xml.split('.')[1]
        if response.status_code == 500:
            raw_xml = raw_xml.split('.')[0] + '_exception.' + raw_xml.split('.')[1]
            s3_state = s3_upload(capital, raw_xml, temp)
            return None, {'SOAP-ENV:Envelope': {'SOAP-ENV:Body': {"cbv2:processResponse": {'cbv2:out': {'INProfileResponse': {'UserMessage': {'UserMessageText': 'Internal Server Error'}}}}}}}
        s3_state = s3_upload(capital, raw_xml, temp)
        s3_format = xmltodict.parse(temp['SOAP-ENV:Envelope']['SOAP-ENV:Body']['ns2:processResponse']['ns2:out'])
        s3_format = {'Body': {'ProcessResponse': {'Out': s3_format}}}
        return s3_format, temp
    except Exception as ex:
        print_log(ex, vendor)
        return None, None


def send_soft_experian_bureau_request(first_name, last_name, mobile_number, capital, raw_xml, vendor, pan_card):
    try:
        user_id = config.EXPERIAN_SOFT_PULL_USER
        password = config.EXPERIAN_SOFT_PULL_PASS
        sm_template = """<?xml version="1.0" encoding="UTF-8"?>
        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:nex="http://nextgenws.ngwsconnect.experian.com">
            <soapenv:Header />
            <soapenv:Body>
                <nex:process>
                <nex:cbv2String>
                    <![CDATA[<INProfileRequest>
                    <Identification>
                        <XMLUser>%s</XMLUser>
                        <XMLPassword>%s</XMLPassword>
                    </Identification>
                    <Applicant>
                        <Surname>%s</Surname>
                        <FirstName>%s</FirstName>
                        <MobilePhone>%s</MobilePhone>
                    </Applicant>
                    </INProfileRequest>]]>
                    </nex:cbv2String>
                </nex:process>
            </soapenv:Body>
            </soapenv:Envelope>
        """
        sm_template_pan = """<?xml version="1.0" encoding="UTF-8"?>
            <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:nex="http://nextgenws.ngwsconnect.experian.com">
                <soapenv:Header />
                <soapenv:Body>
                    <nex:process>
                    <nex:cbv2String>
                        <![CDATA[<INProfileRequest>
                        <Identification>
                            <XMLUser>%s</XMLUser>
                            <XMLPassword>%s</XMLPassword>
                        </Identification>
                        <Applicant>
                            <Surname>%s</Surname>
                            <FirstName>%s</FirstName>
                            <MobilePhone>%s</MobilePhone>
                            <IncomeTaxPAN>%s</IncomeTaxPAN>
                        </Applicant>
                        </INProfileRequest>]]>
                        </nex:cbv2String>
                    </nex:process>
                </soapenv:Body>
                </soapenv:Envelope>
            """
        soap_message = sm_template_pan % (user_id, password, last_name, first_name, mobile_number, pan_card) if pan_card else sm_template % (user_id, password, last_name, first_name, mobile_number)
        url = config.EXPERIAN_SOFT_PULL_URL
        s3_state = s3_upload(capital, capital + '_request_soft_experian.xml', soap_message)
        response = requests.post(url, data=soap_message, verify=False)
        # return xmltodict.parse(response.content)
        print_log('Experian Bureau Pull response received', vendor)
        temp = xmltodict.parse(response.content)
        if response.status_code == 500:
            raw_xml = raw_xml.split('.')[0] + '_exception.' + raw_xml.split('.')[1]
            s3_state = s3_upload(capital, raw_xml, temp)
            return None, {'SOAP-ENV:Envelope': {'SOAP-ENV:Body': {"cbv2:processResponse": {'cbv2:out': {'INProfileResponse': {'UserMessage': {'UserMessageText': 'Internal Server Error'}}}}}}}
        else:
            s3_state = s3_upload(capital, raw_xml, temp)
        s3_format = xmltodict.parse(temp['soapenv:Envelope']['soapenv:Body']['processResponse']['processReturn'])
        s3_format = {'Body': {'ProcessResponse': {'Out': s3_format}}}
        return s3_format, temp
    except Exception as ex:
        print_log(traceback.print_exc(), vendor)
        return None, ex


def send_equifax_bureau_request(capital, raw_xml, vendor=None):
    request_params = get_request_params('Equifax')

    sm_template = """<?xml version="1.0" encoding="UTF-8"?>
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://services.equifax.com/eport/ws/schemas/1.0">
        <soapenv:Header/>
        <soapenv:Body>
            <ns:InquiryRequest>
                <ns:RequestHeader>
                    <ns:CustomerId>%s</ns:CustomerId>
                    <ns:UserId>%s</ns:UserId>
                    <ns:Password>%s</ns:Password>
                    <ns:MemberNumber>%s</ns:MemberNumber>
                    <ns:SecurityCode>%s</ns:SecurityCode>
                    <ns:ProductCode>%s</ns:ProductCode>
                    <ns:ProductVersion>%s</ns:ProductVersion>
                    <ns:ReportFormat>%s</ns:ReportFormat>
                    <!--Optional:-->
                    <ns:CustRefField></ns:CustRefField>
                </ns:RequestHeader>
                <!--start Added addtion account new slot:-->
                <ns:InquiryCommonAccountDetails>
                    <ns:InquiryAccount seq="1">
                    <ns:AccountNumber></ns:AccountNumber>
                    </ns:InquiryAccount>
                </ns:InquiryCommonAccountDetails>
                <!--end Added addtion account new slot:-->
                <ns:RequestBody>
                    <ns:InquiryPurpose>%s</ns:InquiryPurpose>
                    <!--Optional:-->
                    <ns:FirstName>%s</ns:FirstName>
                    <!--Optional:-->
                    <ns:LastName>%s</ns:LastName>
                    <ns:DOB>%s</ns:DOB>
                    <!--Optional:-->
                    <ns:PANId>%s</ns:PANId>
                    <ns:NationalIdCard></ns:NationalIdCard>
                    <ns:PassportId></ns:PassportId>
                    <!--Optional:-->
                    <ns:MobilePhone></ns:MobilePhone>
                    <ns:InquiryAddresses>
                    <ns:InquiryAddress seq="1">
                        <ns:AddressLine>%s</ns:AddressLine>
                        <ns:State>%s</ns:State>
                        <ns:Postal>%s</ns:Postal>
                    </ns:InquiryAddress>
                    </ns:InquiryAddresses>
                    <ns:InquiryPhones>
                    <ns:InquiryPhone seq="1">
                        <ns:Number>%s</ns:Number>
                    </ns:InquiryPhone>
                    </ns:InquiryPhones>
                </ns:RequestBody>
            </ns:InquiryRequest>
        </soapenv:Body>
    </soapenv:Envelope>
    """

    soap_message = sm_template % (
        request_params["CustomerId"], request_params["UserId"], request_params["Password"],
        request_params["MemberNumber"],
        request_params["SecurityCode"], request_params["ProductCode"],
        request_params["ProductVersion"],
        request_params["ReportFormat"],
        request_params["Purpose"], request_params["FirstName"], request_params["LastName"],
        request_params["DOB"],
        request_params["PanCard"],
        request_params["Address"], get_state_code_equifax(request_params["State"], vendor),
        request_params["PostalCode"],
        request_params["MobileNumber"])
    url = config.EQUIFAX_URL
    print_log('Equifax Bureau Pull request created', vendor)
    response = requests.post(url, data=soap_message)
    # with open('/Users/abhishek/Downloads/165.json', 'r') as f:
    #     response = f.read()
    print_log('Equifax Bureau Pull response received', vendor)
    raw_xml = raw_xml.split('.')[0] + '_equifax.' + raw_xml.split('.')[1]
    s3_upload(capital, raw_xml, xmltodict.parse(response.content))
    return xmltodict.parse(response.content)
    # return xmltodict.parse(response)


def check_experian_bureau_report(experian_bureau_data, soap_env, vendor=None):
    try:
        print_log('Entered Experian Bureau Checking', vendor)
        experian_data_report = response_header_experian = []
        if "cbv2:processResponse" in experian_bureau_data[soap_env + ":Envelope"][
            soap_env + ":Body"]:  # if login credentials are invalid
            response_header_experian = \
                experian_bureau_data[soap_env + ":Envelope"][soap_env + ":Body"]["cbv2:processResponse"]["cbv2:out"]
        elif "ns2:processResponse" in experian_bureau_data[soap_env + ":Envelope"][soap_env + ":Body"]:
            response_header_experian = \
                experian_bureau_data[soap_env + ":Envelope"][soap_env + ":Body"]["ns2:processResponse"]["ns2:out"]
            response_header_experian = xmltodict.parse(response_header_experian)

        if "INProfileResponse" in response_header_experian:
            experian_data_report = response_header_experian["INProfileResponse"]

        if "UserMessage" in experian_data_report and experian_data_report["UserMessage"][
            "UserMessageText"] is not None and experian_data_report["UserMessage"][
            "UserMessageText"] != 'Normal Response':
            experian_error = experian_data_report["UserMessage"]["UserMessageText"]
            return experian_error
        elif "Header" in experian_data_report and experian_data_report["Header"]["MessageText"] is not None:
            experian_error = json.dumps(experian_data_report["Header"]["MessageText"])
            return experian_error
        return None
    except Exception as ex:
        return ex



def check_soft_experian_bureau_report(experian_bureau_data, soap_env):
    try:
        experian_data_report = response_header_experian = []
        if 'SOAP-ENV:Envelope' in experian_bureau_data:
            soap_env = 'SOAP-ENV'
        if "cbv2:processResponse" in experian_bureau_data.get(soap_env + ":Envelope")[
            soap_env + ":Body"]:  # if login credentials are invalid
            response_header_experian = \
            experian_bureau_data[soap_env + ":Envelope"][soap_env + ":Body"]["cbv2:processResponse"]["cbv2:out"]

        elif "processResponse" in experian_bureau_data[soap_env + ":Envelope"][soap_env + ":Body"]:
            response_header_experian = \
                experian_bureau_data[soap_env + ":Envelope"][soap_env + ":Body"]["processResponse"]["processReturn"]
            response_header_experian = xmltodict.parse(response_header_experian)

        if "INProfileResponse" in response_header_experian:
            experian_data_report = response_header_experian["INProfileResponse"]

        if "UserMessage" in experian_data_report and experian_data_report["UserMessage"][
            "UserMessageText"] is not None and experian_data_report["UserMessage"][
            "UserMessageText"] != 'Normal Response':
            experian_error = experian_data_report["UserMessage"]["UserMessageText"]
            return experian_error
        elif "Header" in experian_data_report and experian_data_report["Header"]["MessageText"] is not None:
            experian_error = json.dumps(experian_data_report["Header"]["MessageText"])
            return experian_error
        return None
    except TypeError as ex:
        return 'Internal Server Error from Experian'
