import json
import traceback
from flask import Blueprint, request
from dependency_injector.wiring import inject, Provide
import logging
import bugsnag
from emi_service import EMIService, validate_no_touch_product_details_request, validate_no_touch_electricity_bill_request
from emi_containers import EMIContainer
from response_templates.response_builders import (failure_response, custom_failure_response_solar, success_response_solar)
import accessor.creditfair as creditfair
import config
from authentication.no_touch import NoTouchMiddleware
import re

no_touch_api = Blueprint('no_touch_api', __name__, url_prefix='/V2')


@no_touch_api.route("/upload-presigned-url", methods=["POST"])
@inject
def fetch_presigned_document(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(request.get_json(force=True))
        body = request.get_json(force=True)
        workflow = body.get('workflow')
        file_path_key = body.get('FILE_PATH')
        content_type_key = body.get('CONTENT_TYPE')
        file_path, application_id = emi_service.file_path(file_path_key, body.get("s3_file_name"))
        status, code, presigned_url = emi_service.fetch_presigned_url(file_path, content_type_key,
                                                                      body.get("s3_file_name"), application_id)
        return success_response_solar(status_code=200, code=code, data={'url': presigned_url})
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return failure_response(status_code=400, message='Bad Request', code='CF10400')


@no_touch_api.route("/otp", methods=["POST"], endpoint='otp')
@inject
def generate_otp(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(request.headers.get('Origin'))
        logging.info(request.environ)
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        mobile = body['mobile_number']
        result, code, message = emi_service.send_otp(mobile)
        if result:
            return success_response_solar(status_code=200, code=code, message=message)
        if code == "CF15400":
            return custom_failure_response_solar(status_code=200, code=code, message="Please enter valid mobile number"
                                                 , statusCode="CF300")
        if code == "CF14401":
            return custom_failure_response_solar(status_code=200, code=code, message="Please wait for 1 Minute",
                                                 statusCode="CF300")
        return custom_failure_response_solar(status_code=200, code=code, message="error",
                                             statusCode="CF300")
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='CF10400',message="error",statusCode="CF300")


@no_touch_api.route("/verify-otp", methods=["POST"], endpoint='verify-otp')
@inject
def verify_otp(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        if body["mobile_number"] is None or body['otp'] is None:
            return custom_failure_response_solar(status_code=200, code="CF16400"
                                                 , message="Mobile number or otp can't be empty"
                                                 , statusCode="CF300")
        mobile = int(body.get('mobile_number'))
        otp = body.get('otp')
        consumer_app = body.get('consumer_app')
        result, code, data, message = emi_service.no_touch_confirm_otp(mobile, otp, consumer_app)
        if result:
            return success_response_solar(status_code=200, code=code, message=message, data=data)
        return custom_failure_response_solar(status_code=200, code=code, message=message, statusCode="CF300", data=data)
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='CF10400', message="error", statusCode="CF300")


@no_touch_api.route("/get-token", methods=["POST"], endpoint='get-token')
@inject
def get_token(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        if body.get("application_id") is None:
            return custom_failure_response_solar(status_code=200, code="CF16400"
                                                 , message="Please Provide Application Id"
                                                 , statusCode="CF300")
        application_id = int(body.get("application_id"))
        type = body.get("type")
        result, code, data, message = emi_service.get_token(application_id, type)
        if result:
            return success_response_solar(status_code=200, code=code, message=message, data=data)
        return custom_failure_response_solar(status_code=200, code=code, message=message, statusCode="CF300", data=data)
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='CF10400', message="error", statusCode="CF300")


@no_touch_api.route("/employement-details", methods=["POST"], endpoint='employement-details')
@NoTouchMiddleware.main
@inject
def employment_details(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        application_id = body.get("application_id")
        mobile = body.get("mobile_number")
        net_monthly_income = body.get("net_monthyl_income")
        employment_type = body.get("employement_type")
        company_name = body.get("company_name")
        gst_number = body.get("gst_number")
        result, code,msg = emi_service.no_touch_employment_details(application_id,mobile,employment_type,
                                                                   net_monthly_income,company_name,gst_number)
        if result:
            return success_response_solar(status_code=200, code=code, message=msg)
        return custom_failure_response_solar(status_code=200, code=code, message=msg, statusCode="CF300")
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='CF10400',message="error",statusCode="CF300")


@no_touch_api.route("/electricity-bill", methods=["POST"], endpoint='electricity-bill')
@NoTouchMiddleware.main
@inject
def process_electricity_bill(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        is_valid, code, message = validate_no_touch_electricity_bill_request(body)
        if is_valid:
            app_id = body['application_id']
            provider = body['provider']
            customer_id = body['customer_id']
            district = body['district'] if 'district' in body else ''
            monthly_bill_amount = body['monthly_bill_amount']
            mobile_number = body.get('mobile_number')
            other_provider = body.get("oth_provider")
            if provider == "OTH" and body.get("electricity_bill_photo") is None:
                return custom_failure_response_solar(status_code=200, code="SF10200",
                                                     message='Please upload Electricity Bill', statusCode="CF300")
            status, code = emi_service.get_electricity_bill_details(app_id, provider, customer_id, district,
                                                                    monthly_bill_amount, mobile_number, other_provider)
            if status:
                return success_response_solar(status_code=200, code=code, message='fetched')
        return custom_failure_response_solar(status_code=200, code=code, message='Failed to validate the details',statusCode="CF300")
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='CF10400',message="error",statusCode="CF300")


@no_touch_api.route("/product-details", methods=["POST"], endpoint='product-details')
@NoTouchMiddleware.main
@inject
def product_details(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        is_valid, code, message = validate_no_touch_product_details_request(body)
        if is_valid:
            app_id = body.get('application_id', None)
            project = body.get('project', None)
            project_sub_category = body.get('project_sub_category', None)
            loan_amount = body.get('loan_amount', None)
            kw_installation = body.get('kw_installation', None)
            inverter_to_be_installed = body.get('inverter_to_be_installed', None)
            other_inverter = body.get('other_inverter', None)
            panel_to_be_installed = body.get('panel_to_be_installed', None)
            other_panel = body.get('other_panel', None)
            solar_power_type = body.get('solar_power_type', None)
            if inverter_to_be_installed == 'Other':
                inverter_to_be_installed = other_inverter
            if panel_to_be_installed == 'Other':
                panel_to_be_installed = other_panel
            if panel_to_be_installed:
                panel_to_be_installed = panel_to_be_installed.lower()
            subsidy = body.get('subsidy_amount')
            status, code = emi_service.no_touch_process_product_details(app_id, project, project_sub_category,loan_amount, kw_installation, inverter_to_be_installed,panel_to_be_installed, subsidy ,solar_power_type)
            if status:
                data = []
                if 'data' in status:
                    data = status['data']
                message = status['message']
                # logging.info('response: ' + json.dumps(status['data']))
                if len(data) > 0:
                    return success_response_solar(status_code=200, code=code, data=data, message=message)
                if message == "Not Approved" or message == "Failed to run auto decision":
                    message = "Application submitted. Our team will reach out to you within 24 hrs"
                    return custom_failure_response_solar(status_code=200, code=code, message=message,statusCode="CF301")
                elif message == 'Bureau not generated':
                    message = "Bureau Fetch failed"
                    return custom_failure_response_solar(status_code=200, code=code, message=message,
                                                         statusCode="CF303")
                elif message == "Rejected":
                    return custom_failure_response_solar(status_code=200, code=code, message=message,statusCode="CF302")
        return custom_failure_response_solar(status_code=200, code=code, message=message,statusCode="CF300")
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='CF10400', message="error", statusCode="CF300")


@no_touch_api.route("/get-user-details", methods=["POST"], endpoint='get-user-details')
@NoTouchMiddleware.main
@inject
def get_user_details(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        mobile_number = body.get('mobile_number')
        application_id = body.get('application_id')
        status, response, code = emi_service.get_no_touch_user_journey_details(mobile_number, application_id)
        if status:
            return success_response_solar(status_code=200, code=code, data=response, message='User details')
        return success_response_solar(status_code=200, code=code, data=response,
                                             message='No existing application found. Please create the application')
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='SF10400', essage='error', statusCode='CF300')


@no_touch_api.route("/create-application", methods=["POST"], endpoint='create-application')
@NoTouchMiddleware.main
@inject
def create_application(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        mobile_number = body.get('mobile_number')
        pan_number = body.get('pan_number')
        date_of_birth = body.get('date_of_birth')
        unique_id = body.get('unique_id')
        loan_amount = body.get('loan_amount')
        merchant_id = body.get('merchant_id')
        center_id = body.get('center_id')
        source = body.get('source')
        origin = request.headers.get('Origin')
        if source =="No touch":
            if origin == config.SOLAR_URL:
                source = "Partner Link"
        product = body.get('product')
        product_name = body.get('product_name')
        product = product_name if product == 0 else product
        status, response, code, message = emi_service.create_application(mobile_number, pan_number, date_of_birth,
                                                                         unique_id, loan_amount, merchant_id,
                                                                         center_id, product, source, origin)
        if status:
            return success_response_solar(status_code=200, code=code, data=response, message=message)
        return custom_failure_response_solar(status_code=200, code=code, statusCode='CF300',
                                             message=message)
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='SF10400', essage='error', statusCode='CF300')


@no_touch_api.route("/update-application", methods=["POST"], endpoint='update-application')
@NoTouchMiddleware.main
@inject
def update_application(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        status, code, message = emi_service.update_application(body)
        if status:
            return success_response_solar(status_code=200, code=code, message=message)
        return custom_failure_response_solar(status_code=200, code=code, statusCode='CF300',
                                             message=message)
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='SF10400', essage='error', statusCode='CF300')


@no_touch_api.route("/generate-account-aggregator-link", methods=["POST"], endpoint='generate-account-aggregator-link')
@NoTouchMiddleware.main
@inject
def get_account_aggregator_link():
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        application_id = body.get('application_id')
        redirect_url = body.get('redirect_url')
        response_code, response_body = creditfair.account_aggregator(application_id, redirect_url)
        link = response_body.get('link')
        if response_body.get('re_share'):
            link = response_body.get('redirection_link')
        data = {'link': link}
        if response_code == 200:
            return success_response_solar(status_code=200, code='CF10200', message='Link successfully generated', data=data)
        return custom_failure_response_solar(status_code=200, code='CF10400', statusCode='CF300',
                                             message="Fail")

    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='SF10400', essage='error', statusCode='CF300')


@no_touch_api.route("/upload-solar-docs", methods=["POST"], endpoint='upload-solar-docs')
@NoTouchMiddleware.main
@inject
def upload_solar_docs(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)

        status, code = emi_service.upload_document_entry(body)
        if status:
            return success_response_solar(status_code=200, code=code, message="Success")
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='SF10400', message='error', statusCode='CF300')


@no_touch_api.route("/store-installation-address", methods=["POST"], endpoint='store-installation-address')
@NoTouchMiddleware.main
@inject
def store_installation_address(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        status, code, message = emi_service.store_installation_address(body)
        if status:
            return success_response_solar(status_code=200, code=code, message=message)
        return custom_failure_response_solar(status_code=200, code=code, statusCode='CF300',
                                             message=message)
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='SF10400', essage='error', statusCode='CF300')


@no_touch_api.route("/get-available-offers", methods=["POST"], endpoint='get-available-offers')
@NoTouchMiddleware.main
@inject
def get_available_offers(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        application_id = body.get('application_id')
        status, code, data = emi_service.get_available_offers(application_id)
        if status:
            return success_response_solar(status_code=200, code=code, data=data, message='Offers fetched')
        return custom_failure_response_solar(status_code=200, code=code, statusCode='CF300',
                                             message='Offers not fetched')
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='SF10400', essage='error', statusCode='CF300')


@no_touch_api.route("/get-consumer-app-config", methods=["POST"], endpoint='get-consumer-app-config')
@inject
def get_consumer_app_config(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        data = emi_service.get_consumer_app_schema_file()
        return data, 200
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return failure_response(status_code=400, code='CF10400')


@no_touch_api.route("/get-config", methods=["POST"], endpoint='get-config')
@inject
def get_config(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        data = emi_service.get_no_touch_config()
        return data, 200
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return failure_response(status_code=400, code='CF10400')


@no_touch_api.route("/get-merchant-category", methods=["POST"], endpoint='get-merchant-category')
@NoTouchMiddleware.main
@inject
def get_merchant_details(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        body = request.get_json(force=True)
        merchant_id = body.get('merchant_id')
        service_result, code, data = emi_service.display_merchant_category(merchant_id)
        merchants = {'category_id': data}
        if service_result:
            return success_response_solar(status_code=200, code=code, data=merchants, message='merchant lists')
        return custom_failure_response_solar(status_code=200, code=code, message='merchant fetch failed',statusCode="CF300")
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return failure_response(status_code=400, code='CF10400')


@no_touch_api.route("/check-bureau", methods=["POST"], endpoint='check-bureau')
@NoTouchMiddleware.main
@inject
def check_bureau(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        app_id = body['application_id']
        first_name = body['first_name']
        last_name = body['last_name']
        mobile_number = body['mobile_number']
        address_line_1 = body['address_line_1']
        address_line_2 = body['address_line_2'] if body['address_line_2'] else ''
        address_line_3 = body['address_line_3'] if body['address_line_3'] in body else ''
        city = body['city']
        state = body['state']
        pincode = body['pincode']
        dob = body['dob']
        pan_card = body['pan_card']
        url = body.get('url')
        queue = body.get('queue')
        loan_amt = body.get('loan_amount', 100000)
        status, code = emi_service.no_touch_get_bureau(app_id, first_name, last_name, pan_card, mobile_number, address_line_1,
                                              address_line_2, address_line_3, pincode, city, state, dob, url, queue,
                                              loan_amt)
        if status:
            return success_response_solar(status_code=200, message='Bureau Fetched', code=code)
        return custom_failure_response_solar(status_code=200, code=code, message='Bureau not pulled',
                                             statusCode='CF400')
    except Exception as ex:
        bugsnag.notify(ex)
        return custom_failure_response_solar(status_code=400, code='SF10400', essage='error', statusCode='CF300')


@no_touch_api.route("/get-merchant-center-name", methods=["POST"], endpoint='get-merchant-center-name')
@inject
def get_merchant(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        merchant_center_slug = body.get('merchant_center_slug')
        status, code, data = emi_service.display_merchant_center_name(merchant_center_slug)
        dict_data = {}
        if status:
            for item in data:
                dict_data['id'] = item.get('id')
                dict_data['name'] = item.get('name')
            return success_response_solar(status_code=200, message='Merchant Center Name', code=code, data=dict_data)
        return custom_failure_response_solar(status_code=200, code=code, message='Merchant center not found',
                                             statusCode='CF400')
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='SF10400', essage='error', statusCode='CF300')


@no_touch_api.route("/get-merchant-name", methods=["POST"], endpoint='get-merchant-name')
@inject
def get_merchant(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        merchant_slug = body.get('merchant_slug')
        status, code, data = emi_service.display_merchant_name(merchant_slug)
        dict_data = {}
        if status:
            for item in data:
                dict_data['id'] = item.get('id')
                dict_data['name'] = item.get('merchant_name')
            return success_response_solar(status_code=200, message='Merchant Name', code=code, data=dict_data)
        return custom_failure_response_solar(status_code=200, code=code, message='Merchant not found',
                                             statusCode='CF400')
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='SF10400', essage='error', statusCode='CF300')


@no_touch_api.route("/save-offer", methods=["POST"], endpoint='save-offer')
@NoTouchMiddleware.main
@inject
def save_offer(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        offer_id = body['offer_id']
        application_id = body['application_id']
        status, code = emi_service.save_offer(application_id, offer_id)
        if status:
            return success_response_solar(status_code=200, message='Loan offer updated', code=code)
        return custom_failure_response_solar(status_code=200, code=code, message='Something went wrong', statusCode='CF400')
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='SF10400',essage='error', statusCode='CF300')


@no_touch_api.route("/get-serviceprovider-list", methods=["POST"], endpoint='get-serviceprovider-list')
@inject
def get_serviceprovider_list():
    try:
        district = request.args.get('district')
        code = "CF10200"
        if district:
            message = "List of districts of uttar pradesh"
            district_list = config.KARZA_UP_DISTRICT
            district_obj_list = []
            for elem in district_list:
                district_obj_list.append({"id": elem, "name": elem})
            data = {"service": district_obj_list}
        else:
            dict = config.KARZA_ELECTRICTY_PROVIDER
            service = []
            for i, j in dict.items():
                service.append({"id": j, "name": i})
            data = {"service": service}
            message = "List of service provider"
        return success_response_solar(status_code=200, data=data, message=message, code=code)
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='CF10400', message="error", statusCode="CF300")


@no_touch_api.route("/get-inverters-list", methods=["POST"], endpoint='get-inverters-list')
@inject
def get_inverters_list(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        body = request.get_json(force=True)
        if body.get('panel') is not None:
            data = emi_service.get_panel_list()
        else :
            data = emi_service.get_inverters_list()
        service = []
        id = 0
        for i in data:
            id = id + 1
            service.append({"id": id, "name": i})
        code = "CF10200"
        data = {"service": service}
        message = "List of inverters"

        return success_response_solar(status_code=200, data=data, message=message, code=code)
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='CF10400', message="error", statusCode="CF300")

@no_touch_api.route("/ckyc", methods=["POST"], endpoint='ckyc')
@NoTouchMiddleware.main
@inject
def ckyc(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        pan_number = body['pan_number'] if 'pan_number' in body else None
        dob = body['date_of_birth'] if 'date_of_birth' in body else None
        application_id = body.get("application_id")
        updated_by = 'Solar form via Merchant admin panel' if body.get('source') == 'map' else 'Partner Link'

        if dob and pan_number:
            code, response = emi_service.no_touch_ckyc(pan_number=pan_number, dob=dob, updated_by=updated_by,
                                                       application_id=application_id)
            logging.info('response: ' + json.dumps(response))
            if code == 'SF10400':
                return custom_failure_response_solar(status_code=200, code=code, message=response['message'],
                                                     statusCode="CF-300")
            elif code == 'CF10200':
                message = response['message']
                if message == "error":
                    message = "Data Not Fetched"
                del response["message"]
                data = response
                return success_response_solar(status_code=200, code=code, message=message, data=data)
            elif code == 'CF12409':
                return custom_failure_response_solar(status_code=200, code=code, message='Customer already exist',
                                                     statusCode="CF300")
        else:
            if not dob:
                message = "Please provide valid DOB"
            elif not pan_number:
                message = "Please enter a Valid PAN Number"
            else:
                message = "error"
            return custom_failure_response_solar(status_code=200, code="CF10400", message=message,statusCode="CF300")
        return custom_failure_response_solar(status_code=200, code=code, message='error',statusCode="CF300")

    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=200, code='CF10400',message="error",statusCode="CF300")


@no_touch_api.route("/get-merchant-details", methods=["POST"], endpoint='get-merchant-details')
@NoTouchMiddleware.main
@inject
def get_merchant_details(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        body = request.get_json(force=True)
        category_id = body.get('category_id')
        service_result, code, data = emi_service.display_merchants(category_id)
        merchants = {'merchants': data}
        if service_result:
            return success_response_solar(status_code=200, code=code, data=merchants, message='merchant lists')
        return custom_failure_response_solar(status_code=200, code=code, message='merchant fetch failed',statusCode="CF300")
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return failure_response(status_code=400, code='CF10400')


@no_touch_api.route("/sign-agreement", methods=["POST"], endpoint='sign-agreement')
@NoTouchMiddleware.main
def sign_agreement():
    try:
        body = request.get_json(force=True)
        application_id = body.get('application_id')
        load_time = body.get('load_time')
        click_time = body.get('click_time')
        response_code, response = creditfair.cf_sign_agreement(application_id, load_time, click_time)
        if response.get('message') in ['Agreement Signed Successfully', 'Agreement Already Signed']:
            return success_response_solar(status_code=200, code='CF10200', message='Loan Agreement Signed')
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return failure_response(status_code=400, code='CF10400')


@no_touch_api.route("/consent-document", methods=["POST"], endpoint='consent-document')
@NoTouchMiddleware.main
@inject
def consent_document(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        body = request.get_json(force=True)
        application_id = body.get('application_id')
        status = emi_service.generate_consent_document(application_id)
        if status:
            return success_response_solar(status_code=200, code='CF10200', message='Consent Document Generated')
        return custom_failure_response_solar(status_code=200, code='SF10400', message='error',statusCode="CF300")
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return failure_response(status_code=400, code='CF10400')


@no_touch_api.route("/save-consent", methods=["POST"], endpoint='save-consent')
@NoTouchMiddleware.main
@inject
def save_consent(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        body = request.get_json(force=True)
        application_id = body.get('application_id')
        latitude = body.get('latitude') if body.get('latitude') else ''
        longitude = body.get('longitude') if body.get('longitude') else ''
        status = body.get('status')
        function_status = emi_service.update_consent(application_id, latitude, longitude, status, request)
        if function_status:
            return success_response_solar(status_code=200, code='CF10200', message='Consent Saved')
        return custom_failure_response_solar(status_code=200, code='SF10400', message='error',statusCode="CF300")
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return failure_response(status_code=400, code='CF10400')


@no_touch_api.route("/loan_offer_update", methods=["POST"], endpoint='loan_offer_update')
@NoTouchMiddleware.main
@inject
def update_offer_details(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        loan_offer_id = body.get('offer_id')
        loan_application_id = body.get('application_id')
        if not (loan_offer_id and loan_application_id):
            return custom_failure_response_solar(status_code=200, code='CF10400',
                                                 message='Please pass all the required parameter', statusCode='CF300')
        origin = request.headers.get('Origin')
        status, code = emi_service.update_loan_offer(loan_application_id, loan_offer_id, origin)
        if status:
            return success_response_solar(status_code=200, code=code, message='Loan offer updated')
        return custom_failure_response_solar(status_code=200, code=code,
                                             message='Please pass all the required parameter', statusCode='CF300')
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='CF10400', message='error', statusCode='CF300')


@no_touch_api.route("/consent-otp", methods=["POST"], endpoint='consent-otp')
@inject
def consent_otp(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        mobile = body.get('mobile_number')
        merchant_id = body.get('merchant_id')
        email = body.get('email')
        initiated_from = body.get('loan_initiated_mobile_number')
        if initiated_from:
            initiated_from = re.sub(r"^91", "", initiated_from)
        result, code, message, application_id = emi_service.send_consent_otp(mobile, merchant_id, initiated_from, email)
        if result:
            return success_response_solar(status_code=200, code=code, message=message, data={"application_id": application_id})
        if code == "CF10400":
            return custom_failure_response_solar(status_code=200, code=code, message=message, statusCode="CF300")
        if code == "CF14401":
            return custom_failure_response_solar(status_code=200, code=code, message="Please wait for 1 Minute",
                                                statusCode="CF300")
        return custom_failure_response_solar(status_code=200, code=code, message="error", statusCode="CF300")
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='CF10400', message='error', statusCode='CF300')


@no_touch_api.route("/verify-consent-otp", methods=["POST"], endpoint='verify-consent-otp')
@inject
def verify_consent_otp(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(f"""INFO - {request.url} | Request - {request.json}""")
        body = request.get_json(force=True)
        application_id = body.get("application_id")
        mobile_number = body.get("mobile_number")
        latitude = body.get('latitude') if body.get('latitude') else ''
        longitude = body.get('longitude') if body.get('longitude') else ''
        otp = body.get("otp")
        consent = body.get("consent")
        if body.get("mobile_number") is None or body.get("otp") is None:
            return custom_failure_response_solar(status_code=200, code="CF16400"
                                                 , message="Mobile number or otp can't be empty"
                                                 , statusCode="CF300")
        result, code, message = emi_service.verify_consent_otp(mobile_number, otp, application_id, latitude, longitude, consent)
        if result:
            return success_response_solar(status_code=200, code=code, message=message)
        return custom_failure_response_solar(status_code=200, code=code, message=message, statusCode="CF300")
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return custom_failure_response_solar(status_code=400, code='CF10400', message='error', statusCode='CF300')


@no_touch_api.route("/get-pincode-details", methods=["POST"], endpoint='get-pincode-details')
@inject
def get_pincode_details(emi_service: EMIService = Provide[EMIContainer.emi_service]):
    try:
        logging.info(request)
        pincode = request.args.get('pincode')
        if not pincode:
            body = request.get_json(silent=True) or {}
            pincode = body.get('pincode')
        result, code, data = emi_service.get_pincode_details(pincode)
        if result:
            logging.info('response: ' + json.dumps(data))
            return {
                "status-code": 1,
                "status-message": "Pincode details",
                "data": data
            }, 200
        return {
            "status-code": 305,
            "status-message": "Pincode not found",
            "data": {}
        }, 200
    except Exception as ex:
        bugsnag.notify(ex)
        logging.exception(traceback.print_exc())
        return failure_response(status_code=400, code='CF10400')
