from email import message
import aiohttp, os
from datetime import datetime
from discord import Embed
from exceptions import *

class Player:
	original_request = ""
	requester_steam64 = ""
	current = {}
	steamid = {}
	play_on = {}
	def __init__(self, profile, requester_steam64, stats):
		self.requester_steam64 = requester_steam64
		self.original_request = profile
		self.stats = stats
		#потом надо будет сделать что профиль принимает все, а не только стим ид
		#api/profile/steam, ток там буква Z поэтому стоит поменять на секрет кей
		pass			
		
	async def GetSteamID(self):
		self.steamid = await self.GetSteamIDOfProfile(self.original_request)

	async def LoadProfile(self):
		self.current = await self.GetProfile(self.steam64)

	@property
	def steam64(self):
		return self.steamid.get('steam64', 0)

	@property
	def embed(self) -> Embed:
		if not self.current:
			raise NotLoadProfile
		# build header
		prepare_description = ""
		if self.current.get("play_on", {}):
			prepare_description = f"Сейчас играет на {self.stats['servers'][self.current['play_on']['server_id']]['name']}\n"
		elif self.current.get("lastplay", {}):
			selected_srv = "srv1"
			selected_timestamp = 0
			for srv, maps in self.current["lastplay"].items():
				for last_play in maps.values():
					if last_play > selected_timestamp:
						selected_srv = srv
						selected_timestamp = last_play
			prepare_description = f"Последняя игра на {self.stats['servers'][selected_srv]['name']}\nв {utime2human(selected_timestamp)}"
		else:
			prepare_description = "Не играл на фактах13"

		embed = Embed(
			title=self.current["steam_data"]["nickname"], 
			description=prepare_description, 
			url=self.current["steamids"]["community_url"])
		# set image
		embed.set_thumbnail(url = self.current["steam_data"]["avatar"])
		# Последняя игра на сервере
		if self.current.get("lastplay", {}):
			message = ""
			for maps in self.current["lastplay"].values():
				for map_name, last_play in maps.items():
					message += f"{workshopmap2bsp(map_name)} - {utime2human(last_play)}\n"
			embed.add_field(name="Последняя игра на серверах", value=message, inline=False)
		# Игрокое время
		if self.current.get("gametime", {}):
			message = ""
			for maps in self.current["gametime"].values():
				for map_name, play_time in maps.items():
					message += f"{workshopmap2bsp(map_name)} - {human_TIME(play_time)}\n"
			embed.add_field(name="Статистика по картам", value=message, inline=False)
		# Права
		if self.current.get("permition", {}):
			message = f"{self.current['permition']['status']} назначен {utime2human(self.current['permition']['u_timestamp']) if self.current['permition']['u_timestamp'] != 0 else 'с момента создания'}\n"
			if self.current['permition'].get('amount', 0) and self.current['permition'].get("u_timestamp", 0):
				message += f"окончание после {utime2human(self.current['permition']['u_timestamp'] + self.current['permition']['amount'])}\n"
			embed.add_field(name="Права на серверах", value=message, inline=False)
		# Бан
		if self.current.get("ban", {}):
			message = f"Ник: {self.current['ban']['player_name']}\n"
			message += f"Причина: {self.current['ban']['ban_reason']}\n"
			message += f"Время: {utime2human(self.current['ban']['ban_utime'])}\n"
			message += f"Кто забанил: {self.current['ban']['banned_by']} | <@{self.current['ban']['admin_info']['discord_id']}>\n"
			if self.current['ban']['active'] == True:
				if self.current['ban']['ban_length'] == 0:
					message += "Данный бан навсегда!\n"
				else:
					message += f"Дата разбана: {utime2human(self.current['ban']['ban_utime'] + self.current['ban']['ban_length_seconds'])}\n"
			embed.add_field(name="Имеется бан на сервере", value=message, inline=False)
			
		return embed

	def __str__(self):
		if not self.current:
			raise NotLoadProfile

		message = self.current["steamids"]["community_url"] + "\n"
		if "play_on" in self.current and self.current["play_on"]:
			message += f"Сейчас играет на {self.stats['servers'][self.current['play_on']['server_id']]['name']}\n"
		message += "\n"
		#тут должна быть последняя причина выхода с сервера, но она не релизована в бекенде
		message += "Последняя игра на серверах:\n"
		if "lastplay" in self.current and self.current["lastplay"]:
			for maps in self.current["lastplay"].values():
				for map_name, last_play in maps.items():
					message += f"{workshopmap2bsp(map_name)} - {utime2human(last_play)}\n"
		else:
			message += "Не играл у нас\n"
		message += "\n"
		#Далее игровое время бро
		if "gametime" in self.current and self.current["gametime"]:
			message += "Статистика по картам:\n"
			for maps in self.current["gametime"].values():
				for map_name, play_time in maps.items():
					message += f"{workshopmap2bsp(map_name)} - {human_TIME(play_time)}\n"
		message += "\n"
		#Далее идут проверка прав
		if "permition" in self.current and self.current["permition"]:
			message += f"Права: {self.current['permition']['status']} назначены {utime2human(self.current['permition']['u_timestamp']) if self.current['permition']['u_timestamp'] != 0 else 'с момента создания'}\n"
			if self.current['permition'].get('amount', 0) and self.current['permition'].get("u_timestamp", 0):
				message += f"Кончаются: {utime2human(self.current['permition']['u_timestamp'] + self.current['permition']['amount'])}\n"
			message += "\n"
		#Далее проверка бана
		if "ban" in self.current and self.current["ban"]:
			message += "ИМЕЕТСЯ БАН\n"
			message += f"Ник: {self.current['ban']['player_name']}\n"
			message += f"Причина: {self.current['ban']['ban_reason']}\n"
			message += f"Время: {utime2human(self.current['ban']['ban_utime'])}\n"
			message += f"Кто забанил: {self.current['ban']['banned_by']} | <@{self.current['ban']['admin_info']['discord_id']}>\n"
			if self.current['ban']['active'] == True:
				if self.current['ban']['ban_length'] == 0:
					message += "Данный бан навсегда!\n"
				else:
					message += f"Дата разбана: {utime2human(self.current['ban']['ban_utime'] + self.current['ban']['ban_length_seconds'])}\n"
			else:
				message += f"Кто разбанил: {'бан снялся со временем' if self.current['ban']['unbanned_by_id'] == 'STEAM_0:0:0' else self.current['ban']['unbanned_by_id']}\n"
		#Не реализованное получение числа скок был в бане
		return message

	async def GetSteamIDOfProfile(self, any:str):
		async with aiohttp.ClientSession(cookies={"secretkey":os.getenv("BACKEND_SECRETKEY")}) as session:
			async with session.get(f"{os.getenv('BACKEND_URL')}/api/profile/steam?any={any}", ssl=False) as response:
				try:
					response = await response.json()
				except:
					response = None
		if response == None:
			raise CannotCastToSteamID
		return response

	async def GetProfile(self, steam64):
		async with aiohttp.ClientSession(cookies={"secretkey":os.getenv("BACKEND_SECRETKEY")}) as session:
			async with session.get(f"{os.getenv('BACKEND_URL')}/api/profile?steam64={steam64}", ssl=False) as response:
				return await response.json()

	###############
	#admin commands
	###############
	async def kick(self, reason):
		async with aiohttp.ClientSession(cookies={
			"secretkey":os.getenv("BACKEND_SECRETKEY"),
			"steam64": self.requester_steam64}) as session:
			async with session.post(f"{os.getenv('BACKEND_URL')}/api/admin/kick?steam64={self.steam64}", ssl=False) as response:
				result = await response.text()
				if response.status == 200:
					return "Кикнут с серверов"
				if response.status == 404:
					raise NotFoundPlayerOnServer
				if response.status == 403:
					raise LowPermition
		raise UnknownBackendResponse

	async def rcon(self, command, args):
		if not self.current:
			return "добродей дурачек забыл прогрузить профиль"

		if self.current.get("play_on", {}):
			server = self.current['play_on']['server_id']
			player_id = self.current['play_on']['player_id']
			final_command = f"{command} #{player_id} {args}"
			async with aiohttp.ClientSession(cookies={
				"secretkey":os.getenv("BACKEND_SECRETKEY"),
				"steam64": self.requester_steam64}) as session:
				async with session.post(f"{os.getenv('BACKEND_URL')}/api/admin/rcon?srv={server}&command={final_command}", ssl=False) as response:
					return await response.text()
		else:
			raise NotFoundPlayerOnServer

	async def ban(self, reason, minutes):
		async with aiohttp.ClientSession(cookies={
			"secretkey":os.getenv("BACKEND_SECRETKEY"),
			"steam64": self.requester_steam64}) as session:
			async with session.post(f"{os.getenv('BACKEND_URL')}/api/admin/ban?steam64={self.steam64}&ban_reason={reason}&ban_length={minutes}", ssl=False) as response:
				await response.text()
				if response.status == 200:
					return "Игрок забанен или уже был в бане"
				if response.status == 404:
					raise NotFoundPlayerOnServer
				if response.status == 403:
					raise LowPermition
		raise UnknownBackendResponse

	###############
	#user command
	###############
	async def report(self, reason):
		async with aiohttp.ClientSession(cookies={
			"secretkey":os.getenv("BACKEND_SECRETKEY"),
			"steam64": self.requester_steam64}) as session:
			async with session.post(f"{os.getenv('BACKEND_URL')}/api/profile/current/report?steam64={self.steam64}&text={reason}", ssl=False) as response:
				result = int(await response.text())
				if result == 0:
					return "Игрок с таким именем не играет на серверах в данный момент..."
				elif result < 0:
					return f"Падажди, следующий репорт можно отправить только после: {-1 * result} секунд"
				else:
					return f"Репорт отправлен!"


def workshopmap2bsp(map_name):
	return map_name.split('/')[-1:][0].split('.ugc')[0]

def utime2human(utime):
	return datetime.fromtimestamp(utime).strftime('%H:%M:%S %d.%m.%Y')

def human_TIME(seconds):
	m, s = divmod(int(seconds), 60)
	h, m = divmod(m, 60)
	d, h = divmod(h, 24)
	if not d:
		return "%d:%02d:%02d" % (h, m, s)
	elif d < 2:
		return "%d день %d:%02d:%02d" % (d ,h, m, s)
	else:
		return "%d дней %d:%02d:%02d" % (d ,h, m, s)