from my_modules.app.constens import BLOCKED_IPS_ACCESSING_TIMES, BLOCKED_IPS_STORED_TIMEFRAME
from my_modules.app.setup import app, LIMITER
from my_modules.app.logger import logger

from quart import request, render_template, jsonify, current_app, make_response
from my_modules.functions import get_ip, enforce_custom_limit

@app.errorhandler(401)
async def handle_unauthorized(e):
  if request.path.startswith("/api"):
    return jsonify({"error": "Unauthorized Access", "message": "Gandalf has spoken: You shall not pass… until you log in."}), 401

  await logger.error(e)
  return await render_template('views/basics/error.htm',
    title='Unauthorized Access',
    header={'title': '401 - Unauthorized', 'message': "Gandalf has spoken: You shall not pass… until you log in."},
    file={'name': '401.gif', 'alt': "Gandalf blocking the bridge – You shall not pass!"},
  ), 401

@app.errorhandler(404)
async def not_found(e):
  try:
    enforce_custom_limit(LIMITER, "404")
  except LookupError as e:
    return await to_many_requests(e)

  if request.path.startswith("/api"):
    return jsonify({"error": "Page Not Found", "message": "Oops! The page you are looking for does not exist."}), 404

  await logger.error(f"[404] Page Not Found: {request.path}")
  await current_app.convex.increment_page_not_found_error(path=request.path, status=404)

  return await render_template('views/basics/error.htm',
    title='Page Not Found',
    header={'title': '404 - Page Not Found', 'message': "Oops! The page you are looking for does not exist."},
    file={'name': '404.webp', 'alt': "Matrix - Neo stoping the Bullets by holding his hand up"},
  ), 404

@app.errorhandler(418)
async def maybe_a_hacker(e=None):
  try:
    enforce_custom_limit(LIMITER, "BotScan", BLOCKED_IPS_ACCESSING_TIMES, BLOCKED_IPS_STORED_TIMEFRAME)
  except LookupError as e:
    client_ip=get_ip()
    await current_app.convex.increment_blocked_ip_address_access(
      ip_address=client_ip,
      method=request.method,
      path=request.path,
    )
    await logger.warning(f"[HONEYPOT] Blocked {client_ip} after accessing {request.path}")
    return await to_many_requests(e)

  rendered = await render_template('views/basics/error.htm',
    title='Oops! Something Went AWOL!',
    header={'title': "418 - I'm a Teapot", 'message': f"You don't say the Magic Word. By the way, we might have your IP now, but don’t worry, it's in safe hands (probably). Feel free to keep poking around, just maybe give us a sec to catch our breath."},
    file={'name': 'hacker_crap.webp', 'alt': "Someone got Hacked and he says I hate this Hacker crap - Jurassic Park Movie"},
  )

  response = await make_response((rendered, 418))
  response.headers['X-Honeypot-Triggered'] = 'true'
  response.headers['X-Reason'] = 'Unauthorized access attempt'

  return response

@app.errorhandler(429)
async def to_many_requests(e):
  message = "We love your enthusiasm, but our server thought it was being DDoSed… by you. The keyboard needs a new set of keys and we need a nap. Try again soon!"

  if request.path.startswith("/api") or request.path.endswith('/auth/userinfo') or request.path.endswith('/auth/refresh'):
    return jsonify({"error": "Too Many Requests - YOU SHALL NOT PASS (for now)", "message": message}), 429

  return await render_template('views/basics/error.htm',
    title='Too Many Requests',
    header={'title': '429 - YOU SHALL NOT PASS (for now)', 'message': message},
    file={'name': '429_JimCarrey.gif', 'alt': "Jim Carrey Tips very fast on a computer keyboard"},
  ), 429

@app.errorhandler(500)
async def internal_server_error(e):
  try:
    enforce_custom_limit(LIMITER, "500")
  except LookupError as e:
    return await to_many_requests(e)

  if request.path.startswith("/api"):
    return jsonify({"error": "Internal Server Error", "message": "It looks like you broke something... but don't worry, we're fixing it! In the meantime, we may or may not have logged your IP address (just kidding... or are we?). Either way, thanks for helping us find new ways to crash our system. Stay curious, hacker-friend!"}), 500

  await logger.error(e)
  return await render_template('views/basics/error.htm',
    title='Internal Server Error',
    header={'title': '500 - Internal Server Error', 'message': "It looks like you broke something... but don't worry, we're fixing it! In the meantime, we may or may not have logged your IP address (just kidding... or are we?). Either way, thanks for helping us find new ways to crash our system. Stay curious, hacker-friend!"},
    file={'name': '500.webp', 'alt': "Astronaut jumping and clicking on random Buttons as a red alert gone off - They is a Text on the Image saying: Why don't shit Work!?!"},
  ), 500

@app.errorhandler(504)
async def database_server_error(e):
  try:
    enforce_custom_limit(LIMITER, "504")
  except LookupError as e:
    return await to_many_requests(e)

  await logger.error(e)
  return await render_template('views/basics/error.htm',
    title='Database Error',
    header={'title': '504 - Database Error', 'message': "It looks like something is broke on our end... but don't worry, we're fixing it! Either way, thanks for helping us find new ways to crash our system. Stay curious, hacker-friend!"},
    file={'name': '504.gif', 'alt': "Hex Code running over a screen and ends with Error"},
  ), 504
