from app.api import api
from app.credit_fair.credit_fair import CreditFair
from app.decentro.decentro import Decentro
from app.encryption.aes128 import AES128
from app.encryption.hashid import CFHashIds
from app.karza.karza import Karza
from app.user.accessor.user_accessor import UserAccessor
from app.user.custom_refresh_token import CustomRefreshToken
from app.util import util


class User:
    LOAN_AMOUNT_UPPER_LIMIT = 20_00_000
    LOAN_AMOUNT_LOWER_LIMIT = 10_000

    VALID_GENDERS = ["Male", "Female", "Others"]
    GENDER_MAPPING = {
        "male": "1",
        "female": "2",
        "others": "3"
    }

    def __init__(self, user):
        self.user = user

    @classmethod
    def get_user(cls, user_id):
        return UserAccessor.get_user(user_id=user_id)

    @classmethod
    def create(cls, phone_number, email, first_name, last_name, merchant_id, center_id, product_id, loan_amount,
               gender, pincode):
        if cls.LOAN_AMOUNT_LOWER_LIMIT > int(loan_amount) or int(loan_amount) > cls.LOAN_AMOUNT_UPPER_LIMIT:
            return api.OUTSIDE_LOAN_LIMIT, None

        status, application_id = CreditFair.create_customer(
            phone_number, email, first_name, last_name, merchant_id, center_id, product_id, loan_amount,
            cls.GENDER_MAPPING[gender.lower()], pincode)

        return status, application_id

    def get_serialized(self):
        return {
            'phone_number': self.get_phone_number(),
            'name': self.get_name(),
            'email': self.get_email(),
        }

    @classmethod
    def validate_pan(cls, pan):
        status, response = Decentro.validate_pan(pan)
        if util.is_status_failed(status):
            return status, None

        return 1, response

    @classmethod
    def decrypt(cls, data):
        return AES128.aes_cbc_decrypt(data)

    def get_user_details(self):
        return {
            'email': self.decrypt(self.get_email()),
            'phone_number': self.decrypt(self.get_phone_number()),
            'dob': self.get_dob(),
        }

    def get_phone_number(self):
        return self.user.mobile_number

    def get_name(self):
        return self.user.name

    def get_dob(self):
        return self.user.dob

    def get_email(self):
        return self.user.email

    def get_plaintext_email(self):
        return self.decrypt(self.get_email())

    def get_plaintext_phone(self):
        return self.decrypt(self.get_phone_number())

    def get_jwt_token_for_onboarding(self, loan_application):
        return CustomRefreshToken.for_user(self.user, loan_application)

    def get_hashed_user_id(self):
        return CFHashIds().encode(self.user.id)

    @classmethod
    def get_user_id_from_hash(cls, hashed_user_id):
        return CFHashIds().decode(hashed_user_id)

    def get_user_id(self):
        return self.user.id

    def get_first_name(self):
        if self.get_name():
            return self.get_name().split(" ")[0]

        return ""

    def get_last_name(self):
        if self.get_name():
            return " ".join(self.get_name().split(" ")[1:])

        return ""

    def get_pan(self):
        return self.user.pan

    @classmethod
    def generate_aadhar_otp(cls, aadhar):
        return Karza.generate_aadhar_otp(aadhar)

    @classmethod
    def verify_aadhar_otp(cls, aadhar, otp, access_key):
        return Karza.verify_aadhar_otp(aadhar, otp, access_key)
