# Copyright (c) 2021, JINGROW and Contributors
# License: MIT. See LICENSE

import jingrow
from jingrow import _


def load_address_and_contact(pg, key=None) -> None:
	"""Loads address list and contact list in `__onload`"""
	from jingrow.contacts.pagetype.address.address import get_address_display_list
	from jingrow.contacts.pagetype.contact.contact import get_contact_display_list

	pg.set_onload("addr_list", get_address_display_list(pg.pagetype, pg.name))
	pg.set_onload("contact_list", get_contact_display_list(pg.pagetype, pg.name))


def has_permission(pg, ptype, user):
	links = get_permitted_and_not_permitted_links(pg.pagetype)
	if not links.get("not_permitted_links"):
		# optimization: don't determine permissions based on link fields
		return True

	# True if any one is True or all are empty
	names = []
	for df in links.get("permitted_links") + links.get("not_permitted_links"):
		pagetype = df.options
		name = pg.get(df.fieldname)
		names.append(name)

		if name and jingrow.has_permission(pagetype, ptype, pg=name):
			return True

	if not any(names):
		return True
	return False


def get_permission_query_conditions_for_contact(user):
	return get_permission_query_conditions("Contact")


def get_permission_query_conditions_for_address(user):
	return get_permission_query_conditions("Address")


def get_permission_query_conditions(pagetype):
	links = get_permitted_and_not_permitted_links(pagetype)

	if not links.get("not_permitted_links"):
		# when everything is permitted, don't add additional condition
		return ""

	elif not links.get("permitted_links"):
		# when everything is not permitted
		conditions = [
			f"ifnull(`tab{pagetype}`.`{df.fieldname}`, '')=''" for df in links.get("not_permitted_links")
		]

		return "( " + " and ".join(conditions) + " )"

	else:
		conditions = [
			f"ifnull(`tab{pagetype}`.`{df.fieldname}`, '')!=''" for df in links.get("permitted_links")
		]

		return "( " + " or ".join(conditions) + " )"


def get_permitted_and_not_permitted_links(pagetype):
	permitted_links = []
	not_permitted_links = []

	meta = jingrow.get_meta(pagetype)
	allowed_pagetypes = jingrow.permissions.get_pagetypes_with_read()

	for df in meta.get_link_fields():
		if df.options not in ("Customer", "Supplier", "Company", "Sales Partner"):
			continue

		if df.options in allowed_pagetypes:
			permitted_links.append(df)
		else:
			not_permitted_links.append(df)

	return {"permitted_links": permitted_links, "not_permitted_links": not_permitted_links}


def delete_contact_and_address(pagetype: str, pagename: str) -> None:
	for parenttype in ("Contact", "Address"):
		for name in jingrow.get_all(
			"Dynamic Link",
			filters={
				"parenttype": parenttype,
				"link_pagetype": pagetype,
				"link_name": pagename,
			},
			pluck="parent",
		):
			pg = jingrow.get_pg(parenttype, name)
			if len(pg.links) == 1:
				pg.delete()
			else:
				for link in pg.links:
					if link.link_pagetype == pagetype and link.link_name == pagename:
						pg.remove(link)
						pg.save()
						break


@jingrow.whitelist()
@jingrow.validate_and_sanitize_search_inputs
def filter_dynamic_link_pagetypes(
	pagetype, txt: str, searchfield, start, page_len, filters: dict
) -> list[list[str]]:
	from jingrow.permissions import get_pagetypes_with_read

	txt = txt or ""
	filters = filters or {}

	_pagetypes_from_df = jingrow.get_all(
		"PageField",
		filters=filters,
		pluck="parent",
		distinct=True,
		order_by=None,
	)
	pagetypes_from_df = {d for d in _pagetypes_from_df if txt.lower() in _(d).lower()}

	filters.update({"dt": ("not in", pagetypes_from_df)})
	_pagetypes_from_cdf = jingrow.get_all(
		"Custom Field", filters=filters, pluck="dt", distinct=True, order_by=None
	)
	pagetypes_from_cdf = {d for d in _pagetypes_from_cdf if txt.lower() in _(d).lower()}

	all_pagetypes = pagetypes_from_df.union(pagetypes_from_cdf)
	allowed_pagetypes = set(get_pagetypes_with_read())

	valid_pagetypes = sorted(all_pagetypes.intersection(allowed_pagetypes))

	return [[pagetype] for pagetype in valid_pagetypes]


def set_link_title(pg):
	if not pg.links:
		return
	for link in pg.links:
		linked_pg = jingrow.get_pg(link.link_pagetype, link.link_name)
		pg_title = linked_pg.get_title()
		if link.link_title != pg_title:
			link.link_title = pg_title or link.link_name
