# Copyright (c) 2019, SolutionERP LLC and contributors
# For license information, please see license.txt


import xhiveframework
from xhiveframework.model.document import Document
from xhiveframework.utils import flt, get_datetime

from xhiveerp.loan_management.doctype.loan_security_unpledge.loan_security_unpledge import (
	get_pledged_security_qty,
)


class LoanSecurityShortfall(Document):
	pass


def update_shortfall_status(loan, security_value, on_cancel=0):
	loan_security_shortfall = xhiveframework.db.get_value(
		"Loan Security Shortfall",
		{"loan": loan, "status": "Pending"},
		["name", "shortfall_amount"],
		as_dict=1,
	)

	if not loan_security_shortfall:
		return

	if security_value >= loan_security_shortfall.shortfall_amount:
		xhiveframework.db.set_value(
			"Loan Security Shortfall",
			loan_security_shortfall.name,
			{
				"status": "Completed",
				"shortfall_amount": loan_security_shortfall.shortfall_amount,
				"shortfall_percentage": 0,
			},
		)
	else:
		xhiveframework.db.set_value(
			"Loan Security Shortfall",
			loan_security_shortfall.name,
			"shortfall_amount",
			loan_security_shortfall.shortfall_amount - security_value,
		)


@xhiveframework.whitelist()
def add_security(loan):
	loan_details = xhiveframework.db.get_value(
		"Loan", loan, ["applicant", "company", "applicant_type"], as_dict=1
	)

	loan_security_pledge = xhiveframework.new_doc("Loan Security Pledge")
	loan_security_pledge.loan = loan
	loan_security_pledge.company = loan_details.company
	loan_security_pledge.applicant_type = loan_details.applicant_type
	loan_security_pledge.applicant = loan_details.applicant

	return loan_security_pledge.as_dict()


def check_for_ltv_shortfall(process_loan_security_shortfall):

	update_time = get_datetime()

	loan_security_price_map = xhiveframework._dict(
		xhiveframework.get_all(
			"Loan Security Price",
			fields=["loan_security", "loan_security_price"],
			filters={"valid_from": ("<=", update_time), "valid_upto": (">=", update_time)},
			as_list=1,
		)
	)

	loans = xhiveframework.get_all(
		"Loan",
		fields=[
			"name",
			"loan_amount",
			"total_principal_paid",
			"total_payment",
			"total_interest_payable",
			"disbursed_amount",
			"status",
		],
		filters={"status": ("in", ["Disbursed", "Partially Disbursed"]), "is_secured_loan": 1},
	)

	loan_shortfall_map = xhiveframework._dict(
		xhiveframework.get_all(
			"Loan Security Shortfall", fields=["loan", "name"], filters={"status": "Pending"}, as_list=1
		)
	)

	loan_security_map = {}

	for loan in loans:
		if loan.status == "Disbursed":
			outstanding_amount = (
				flt(loan.total_payment) - flt(loan.total_interest_payable) - flt(loan.total_principal_paid)
			)
		else:
			outstanding_amount = (
				flt(loan.disbursed_amount) - flt(loan.total_interest_payable) - flt(loan.total_principal_paid)
			)

		pledged_securities = get_pledged_security_qty(loan.name)
		ltv_ratio = 0.0
		security_value = 0.0

		for security, qty in pledged_securities.items():
			if not ltv_ratio:
				ltv_ratio = get_ltv_ratio(security)
			security_value += flt(loan_security_price_map.get(security)) * flt(qty)

		current_ratio = (outstanding_amount / security_value) * 100 if security_value else 0

		if current_ratio > ltv_ratio:
			shortfall_amount = outstanding_amount - ((security_value * ltv_ratio) / 100)
			create_loan_security_shortfall(
				loan.name,
				outstanding_amount,
				security_value,
				shortfall_amount,
				current_ratio,
				process_loan_security_shortfall,
			)
		elif loan_shortfall_map.get(loan.name):
			shortfall_amount = outstanding_amount - ((security_value * ltv_ratio) / 100)
			if shortfall_amount <= 0:
				shortfall = loan_shortfall_map.get(loan.name)
				update_pending_shortfall(shortfall)


def create_loan_security_shortfall(
	loan,
	loan_amount,
	security_value,
	shortfall_amount,
	shortfall_ratio,
	process_loan_security_shortfall,
):
	existing_shortfall = xhiveframework.db.get_value(
		"Loan Security Shortfall", {"loan": loan, "status": "Pending"}, "name"
	)

	if existing_shortfall:
		ltv_shortfall = xhiveframework.get_doc("Loan Security Shortfall", existing_shortfall)
	else:
		ltv_shortfall = xhiveframework.new_doc("Loan Security Shortfall")
		ltv_shortfall.loan = loan

	ltv_shortfall.shortfall_time = get_datetime()
	ltv_shortfall.loan_amount = loan_amount
	ltv_shortfall.security_value = security_value
	ltv_shortfall.shortfall_amount = shortfall_amount
	ltv_shortfall.shortfall_percentage = shortfall_ratio
	ltv_shortfall.process_loan_security_shortfall = process_loan_security_shortfall
	ltv_shortfall.save()


def get_ltv_ratio(loan_security):
	loan_security_type = xhiveframework.db.get_value("Loan Security", loan_security, "loan_security_type")
	ltv_ratio = xhiveframework.db.get_value("Loan Security Type", loan_security_type, "loan_to_value_ratio")
	return ltv_ratio


def update_pending_shortfall(shortfall):
	# Get all pending loan security shortfall
	xhiveframework.db.set_value(
		"Loan Security Shortfall",
		shortfall,
		{"status": "Completed", "shortfall_amount": 0, "shortfall_percentage": 0},
	)
