from aiohttp import web
import aiohttp_security
import datetime
import aiomysql

import security

def logevent(request, query):
	real_ip = request.headers.get('X-Real-IP', 'unknown')
	print(f"IP: {real_ip} - Request: {query}")

def datetime_format(postdata):
	formatted = {}
	for s in ("timefrom", "timeto"):
		formatted[s] = datetime.datetime.strptime(postdata[s], '%H:%M').strftime('%H:%M:%S')
	return formatted

def init_app(app):
	async def db_query(query, params=()):
		cursor = await app['con'].cursor(aiomysql.DictCursor)
		await cursor.execute(query, params)
		q = cursor.mogrify(query, params)
		r = await cursor.fetchall()
		result = [{k: (str(v) if isinstance(v, datetime.date) or isinstance(v, datetime.timedelta) else v) for k, v in row.items()} for row in r]
		return (q, result)

	routes = web.RouteTableDef()

	@routes.get('')
	async def bare_redirect(request):
		raise web.HTTPFound(app['prefix'])

	@routes.get('/')
	async def home(request):
		await aiohttp_security.check_permission(request, 'user')
		response = request.app['templates']["index.html"].safe_substitute({'disabled': '', 'user': 'user'})
		return web.Response(text=response, content_type="text/html")

	@routes.get('/admin')
	async def admin(request):
		await aiohttp_security.check_permission(request, 'admin')
		response = request.app['templates']["index.html"].safe_substitute({'disabled': 'disabled', 'user': 'admin'})
		return web.Response(text=response, content_type="text/html")

	@routes.get('/events/day/{day}')
	async def get_events_daily(request):
		await aiohttp_security.check_permission(request, 'user')
		querystring = "SELECT * FROM events WHERE deleted=false AND %s BETWEEN datefrom AND dateto;"
		if request.match_info['day']:
			query, response = await db_query(querystring, (request.match_info['day'],))
		else:
			query, response = await db_query(querystring.replace("%s", "CURDATE()"))
		return web.json_response(response)

	@routes.get('/events/month/{month}')
	async def get_events_monthly(request):
		await aiohttp_security.check_permission(request, 'user')
		querystring = "SELECT * FROM events WHERE deleted=false AND %s BETWEEN DATE_FORMAT(datefrom, '%%Y-%%m') AND DATE_FORMAT(dateto, '%%Y-%%m');"
		if request.match_info['month']:
			query, response = await db_query(querystring, (request.match_info['month'],))
		else:
			query, response = await db_query(querystring.replace("%s", "DATE_FORMAT(CURDATE(), '%%Y-%%m')"))
		return web.json_response(response)

	@routes.get('/admin/day/{day}')
	async def get_events_daily(request):
		await aiohttp_security.check_permission(request, 'admin')
		querystring = "SELECT * FROM events WHERE %s BETWEEN datefrom AND dateto;"
		if request.match_info['day']:
			query, response = await db_query(querystring, (request.match_info['day'],))
		else:
			query, response = await db_query(querystring.replace("%s", "CURDATE()"))
		return web.json_response(response)

	@routes.get('/admin/month/{month}')
	async def get_events_monthly(request):
		await aiohttp_security.check_permission(request, 'admin')
		querystring = "SELECT * FROM events WHERE %s BETWEEN DATE_FORMAT(datefrom, '%%Y-%%m') AND DATE_FORMAT(dateto, '%%Y-%%m');"
		if request.match_info['month']:
			query, response = await db_query(querystring, (request.match_info['month'],))
		else:
			query, response = await db_query(querystring.replace("%s", "DATE_FORMAT(CURDATE(), '%%Y-%%m')"))
		return web.json_response(response)

	@routes.post('/event/add')
	async def event_add(request):
		await aiohttp_security.check_permission(request, 'user')
		postdata = await request.post()
		formatted = datetime_format(postdata)
		querystring = "INSERT INTO events(name, message, timefrom, timeto, timetbd, datefrom, dateto, datetbd) VALUES(%s,%s,%s,%s,%s,%s,%s,%s);"
		params = (postdata["name"], postdata["message"], formatted["timefrom"], formatted["timeto"], "timetbd" in postdata, postdata["datefrom"], postdata["dateto"], "datetbd" in postdata)
		query, response = await db_query(querystring, params)
		# await update(request)
		logevent(request, query)
		raise web.HTTPFound(app['prefix'])

	@routes.post('/event/{id}/edit')
	async def event_edit(request):
		await aiohttp_security.check_permission(request, 'user')
		postdata = await request.post()
		formatted = datetime_format(postdata)
		querystring = "UPDATE events SET name=%s, message=%s, timefrom=%s, timeto=%s, timetbd=%s, datefrom=%s, dateto=%s, datetbd=%s WHERE id=%s;"
		params = (postdata["name"], postdata["message"], formatted["timefrom"], formatted["timeto"], "timetbd" in postdata,
				postdata["datefrom"], postdata["dateto"], "datetbd" in postdata, request.match_info['id'])
		query, response = await db_query(querystring, params)
		# await update(request)
		logevent(request, query)
		raise web.HTTPFound(app['prefix'])

	@routes.post('/event/{id}/delete')
	async def event_delete(request):
		await aiohttp_security.check_permission(request, 'user')
		postdata = await request.post()
		querystring = "UPDATE events SET deleted=true WHERE id=%s;"
		query, response = await db_query(querystring, (request.match_info['id'],))
		# await update(request)
		logevent(request, query)
		raise web.HTTPFound(app['prefix'])
	
	app.add_routes(routes)