import jingrow
from jingrow.core.utils import find
from jingrow.utils import flt
from jingrow.utils.data import add_days, add_months, get_first_day, get_last_day, today

from jcloud.utils import get_current_team


@jingrow.whitelist()
def approve_partner_request(key):
	partner_request_pg = jingrow.get_pg("Partner Approval Request", {"key": key})
	if partner_request_pg and partner_request_pg.status == "Pending":
		if partner_request_pg.approved_by_partner:
			partner_request_pg.approved_by_jingrow = True
			partner_request_pg.status = "Approved"
			partner_request_pg.save(ignore_permissions=True)
			partner_request_pg.reload()

			partner_email = jingrow.db.get_value("Team", partner_request_pg.partner, "partner_email")
			jingrow.db.set_value(
				"Team",
				partner_request_pg.requested_by,
				{
					"partner_email": partner_email,
					"partnership_date": jingrow.utils.getdate(partner_request_pg.creation),
				},
			)

		jingrow.db.commit()

	jingrow.response.type = "redirect"
	jingrow.response.location = f"/app/partner-approval-request/{partner_request_pg.name}"


@jingrow.whitelist()
def get_partner_request_status(team):
	return jingrow.db.get_value("Partner Approval Request", {"requested_by": team}, "status")


@jingrow.whitelist()
def update_partnership_date(team, partnership_date):
	if team:
		team_pg = jingrow.get_pg("Team", team)
		team_pg.partnership_date = partnership_date
		team_pg.save()


@jingrow.whitelist()
def get_partner_details(partner_email):
	from jcloud.utils.billing import get_jingrow_io_connection

	client = get_jingrow_io_connection()
	data = client.get_pg(
		"Partner",
		filters={"email": partner_email, "enabled": 1},
		fields=[
			"email",
			"partner_type",
			"company_name",
			"custom_ongoing_period_fc_invoice_contribution",
			"custom_fc_invoice_contribution",
			"partner_name",
			"custom_number_of_certified_members",
			"end_date",
		],
	)
	if data:
		return data[0]
	jingrow.throw("Partner Details not found")
	return None


@jingrow.whitelist()
def get_partner_name(partner_email):
	return jingrow.db.get_value(
		"Team",
		{"partner_email": partner_email, "enabled": 1, "jerp_partner": 1},
		"billing_name",
	)


@jingrow.whitelist()
def transfer_credits(amount, customer, partner):
	# partner discount map
	DISCOUNT_MAP = {"Entry": 0, "Bronze": 0.05, "Silver": 0.1, "Gold": 0.15}

	amt = jingrow.utils.flt(amount)
	partner_pg = jingrow.get_pg("Team", partner)
	credits_available = partner_pg.get_balance()
	partner_level, certificates = partner_pg.get_partner_level()
	discount_percent = DISCOUNT_MAP.get(partner_level)

	if credits_available < amt:
		jingrow.throw(f"Insufficient Credits to transfer. Credits Available: {credits_available}")

	customer_pg = jingrow.get_pg("Team", customer)
	credits_to_transfer = amt
	amt -= amt * discount_percent
	if customer_pg.currency != partner_pg.currency:
		if partner_pg.currency == "USD":
			credits_to_transfer = credits_to_transfer * 83
		else:
			credits_to_transfer = credits_to_transfer / 83

	try:
		customer_pg.allocate_credit_amount(
			credits_to_transfer,
			"Transferred Credits",
			f"Transferred Credits from {partner_pg.name}",
		)
		partner_pg.allocate_credit_amount(
			amt * -1, "Transferred Credits", f"Transferred Credits to {customer_pg.name}"
		)
		jingrow.db.commit()
		return amt
	except Exception:
		jingrow.throw("Error in transferring credits")
		jingrow.db.rollback()


@jingrow.whitelist()
def get_partner_contribution_list(partner_email):
	partner_currency = jingrow.db.get_value(
		"Team", {"jerp_partner": 1, "partner_email": partner_email}, "currency"
	)
	month_end = jingrow.utils.get_last_day(today())
	invoices = jingrow.get_all(
		"Invoice",
		{"partner_email": partner_email, "due_date": month_end, "type": "Subscription"},
		["due_date", "customer_name", "total", "currency", "status"],
	)
	for d in invoices:
		if partner_currency != d.currency:
			if partner_currency == "USD":
				d.update({"partner_total": flt(d.total / 83, 2)})
			else:
				d.update({"partner_total": flt(d.total * 83)})
		else:
			d.update({"partner_total": d.total})
	return invoices


@jingrow.whitelist()
def get_total_partner_contribution(partner_email):
	return


@jingrow.whitelist()
def get_current_month_partner_contribution(partner_email):
	partner_currency = jingrow.db.get_value(
		"Team", {"jerp_partner": 1, "partner_email": partner_email}, "currency"
	)
	month_end = jingrow.utils.get_last_day(today())

	invoice = jingrow.qb.PageType("Invoice")
	query = (
		jingrow.qb.from_(invoice)
		.select(invoice.total, invoice.currency, invoice.total_before_discount)
		.where(
			(invoice.partner_email == partner_email)
			& (invoice.due_date == month_end)
			& (invoice.type == "Subscription")
			& (invoice.status == "Draft")
		)
	)
	invoices = query.run(as_dict=True)
	total = 0
	for d in invoices:
		if partner_currency != d.currency:
			if partner_currency == "USD":
				total += flt(d.total_before_discount / 83, 2)
			else:
				total += flt(d.total_before_discount * 83, 2)
		else:
			total += d.total_before_discount

	return total


@jingrow.whitelist()
def get_prev_month_partner_contribution(partner_email):
	partner_currency = jingrow.db.get_value(
		"Team", {"jerp_partner": 1, "partner_email": partner_email}, "currency"
	)
	first_day = get_first_day(today())
	two_weeks = add_days(first_day, 14)  # 15th day of the month
	last_month_end = get_last_day(add_months(today(), -1))

	invoice = jingrow.qb.PageType("Invoice")
	query = (
		jingrow.qb.from_(invoice)
		.select(invoice.total, invoice.currency, invoice.total_before_discount)
		.where(
			(invoice.partner_email == partner_email)
			& (invoice.due_date == last_month_end)
			& (invoice.type == "Subscription")
		)
	)

	if today() >= first_day and jingrow.utils.getdate() <= jingrow.utils.getdate(two_weeks):
		# till 15th of the current month unpaid invoices can also be counted in contribution
		query = query.where((invoice.status).isin(["Unpaid", "Paid"]))
	else:
		query = query.where(invoice.status == "Paid")

	invoices = query.run(as_dict=True)

	total = 0
	for d in invoices:
		total = 0
		if partner_currency != d.currency:
			if partner_currency == "USD":
				total += flt(d.total / 83, 2)
			else:
				total += flt(d.total * 83, 2)
		else:
			total += d.total
	return total


@jingrow.whitelist()
def calculate_partner_tier(contribution, currency):
	partner_tier = jingrow.qb.PageType("Partner Tier")
	query = jingrow.qb.from_(partner_tier).select(partner_tier.name)
	if currency == "CNY":
		query = query.where(partner_tier.target_in_cny <= contribution).orderby(
			partner_tier.target_in_cny, order=jingrow.qb.desc
		)
	else:
		query = query.where(partner_tier.target_in_usd <= contribution).orderby(
			partner_tier.target_in_usd, order=jingrow.qb.desc
		)

	tier = query.run(as_dict=True)
	return tier[0]


@jingrow.whitelist()
def add_partner(referral_code: str):
	team = get_current_team(get_pg=True)
	partner = jingrow.get_pg("Team", {"partner_referral_code": referral_code}).name
	if jingrow.db.exists(
		"Partner Approval Request",
		{"partner": partner, "requested_by": team.name, "status": "Pending"},
	):
		return "Request already sent"

	pg = jingrow.get_pg(
		{
			"pagetype": "Partner Approval Request",
			"partner": partner,
			"requested_by": team.name,
			"status": "Pending",
			"send_mail": True,
		}
	)
	pg.insert(ignore_permissions=True)
	return None


@jingrow.whitelist()
def validate_partner_code(code):
	partner = jingrow.db.get_value(
		"Team",
		{"enabled": 1, "jerp_partner": 1, "partner_referral_code": code},
		"billing_name",
	)
	if partner:
		return True, partner
	return False, None


@jingrow.whitelist()
def get_partner_customers():
	team = get_current_team(get_pg=True)
	customers = jingrow.get_all(
		"Team",
		{"enabled": 1, "jerp_partner": 0, "partner_email": team.partner_email},
		["name", "user", "payment_mode", "billing_name", "currency"],
	)
	return customers  # noqa: RET504


@jingrow.whitelist()
def get_partner_members(partner):
	from jcloud.utils.billing import get_jingrow_io_connection

	client = get_jingrow_io_connection()
	return client.get_list(
		"LMS Certificate",
		filters={"partner": partner},
		fields=["member_name", "member_email"],
	)


@jingrow.whitelist()
def remove_partner():
	team = get_current_team(get_pg=True)
	if team.payment_mode == "Paid By Partner":
		jingrow.throw(
			"Cannot remove partner from the team. Please change the payment mode to Prepaid Credits or Card"
		)

	partner_user = jingrow.get_value(
		"Team", {"partner_email": team.partner_email, "jerp_partner": 1}, "user"
	)
	member_to_remove = find(team.team_members, lambda x: x.user == partner_user)
	if member_to_remove:
		team.remove(member_to_remove)
	team.partner_email = ""
	team.save(ignore_permissions=True)


@jingrow.whitelist()
def get_local_payment_setup():
	team = get_current_team()
	data = jingrow._dict()
	data.mpesa_setup = jingrow.db.get_value("Mpesa Setup", {"team": team}, "mpesa_setup_id") or None
	data.payment_gateway = jingrow.db.get_value("Payment Gateway", {"team": team}, "name") or None
	return data
