from datetime import datetime

from discord import Embed
from kekmonitors.utils import shoe_stuff
from kekmonitors.utils.shoe_stuff import Shoe


def get_empty_embed() -> Embed:
	'''Get an almost empty embed (only set color and timestamp)'''
	empty_embed = Embed()
	empty_embed.timestamp = datetime.utcnow()
	return empty_embed


def add_link(s: str, link: str) -> str:
	'''Add a link to the string s in markdown format'''
	return "[" + s + "](" + link + ")"


def get_default_embed(shoe: Shoe, allow_unavailable_sizes=False, show_website=False):
	'''Do you really need help to understand this?'''
	embed = get_empty_embed()

	embed.title = shoe.name
	embed.url = shoe.link
	embed.set_thumbnail(url=shoe.img_link)

	if show_website:
		if not isinstance(embed.description, str):
			embed.description = ""
		embed.description += "\n" + \
			shoe.link[shoe.link.find("/") + 2:shoe.link.find("/", 8)]

	if shoe.reason == shoe_stuff.NEW_RELEASE:
		embed.add_field(name="Notification type", value="New item", inline=False)
	if shoe.reason == shoe_stuff.RESTOCK:
		embed.add_field(name="Notification type", value="Restock", inline=False)

	if shoe.price != "Not available":
		embed.add_field(name="Price", value=shoe.price, inline=False)

	if shoe.release_date != "":
		if shoe.release_method != "":
			embed.add_field(name="Release date", value=shoe.release_date)
			embed.add_field(name="Release method", value=shoe.release_method)
		else:
			embed.add_field(name="Release date", value=shoe.release_date)

	# Add sizes to the embed
	sizes = []
	total_chars = 0
	for size in shoe.sizes:
		available = shoe.sizes[size]["available"]
		# Only add sizes under these conditions
		if available or (not available and allow_unavailable_sizes):
			size_str = size
			# Add the stock number if available
			if "stock" in shoe.sizes[size]:
				size_str += " (" + str(shoe.sizes[size]["stock"]) + ")"
			# Add atc if available
			if "atc" in shoe.sizes[size] and shoe.sizes[size]["atc"] != "":
				atc = shoe.sizes[size]["atc"]
				atc_str = add_link("[ATC]", atc)
				size_str += " - " + atc_str
			# Add quick tasks if available
			if "quick_tasks" in shoe.sizes[size]:
				qts = []
				for key, value in zip(shoe.sizes[size]["quick_tasks"].keys(), shoe.sizes[size]["quick_tasks"].values()):
					qts.append(add_link(key, value))
				qts_str = " - ".join(qts)
				size_str += " - " + qts_str
			# Add anything else
			if "other" in shoe.sizes[size]:
				others_list = []
				for other in shoe.sizes[size]["other"]:
					other_str = ""
					if "link" in other:
						other_str = add_link(other["name"], other["link"])
					else:
						other_str = other["name"]
					others_list.append(other_str)
				others_str = " - ".join(others_list)
				size_str += " - " + others_str
			sizes.append(size_str)
			total_chars += len(size_str)

	# get well formatted sizes.
	values = get_valid_values(sizes, 6)

	for index, value in enumerate(values):
		if index == 0:
			inline = True if len(values) > 0 else False
			embed.add_field(name="Sizes", value=value, inline=inline)
		else:
			embed.add_field(name="\u200b", value=value, inline=True)

	return embed


def get_valid_values(values_list, max_elements):
	'''This function tries to format a list splitting it in max_elements and keeping count of discord's max chars limit.\n
		See comments for more insight.'''
	if len(values_list) == 0:
		return []
	# not perfect. if many small values and very close to 1023 chars it might truncate the lasts of them.
	# also, this requires too much fucking math.
	tmp = ""
	done = False
	valid_values = []
	count = 0
	for value in values_list:
		done = False
		if len(tmp) + len("\n") + len(value) > 1023 or (count != 0 and count % max_elements == 0):
			if tmp == "":
				# first cycle / 1 item
				tmp = value
			done = True
			valid_values.append(tmp)
			tmp = ""
			count = 0
		tmp += value + "\n"
		count += 1
	if not done:
		valid_values.append(tmp)
	return valid_values


def website_specific_embed(shoe: Shoe) -> Embed:
	'''What a website-specific embed function might look like.'''
	fd_embed = get_default_embed(shoe)
	if shoe.reason == shoe_stuff.NEW_RELEASE:
		if shoe.sizes == {}:
			fd_embed.add_field(
				name="Info", value="If sizes are not displayed check manually!", inline=False)
	if "alternative_url" in shoe.tags:
		fd_embed.description = f"\n\n[Alternative link]({shoe.tags['alternative_url']})"
	return fd_embed
