"""
main.py
Main API file used for handling Prestonet API reqs
Author: Vojtech Pokorny, vojtech.pokorny@prestonet.cz
Date (last edit): 6.2.2025
Note: Using framework FastAPI
"""

# Importing FastAPI libraries
from fastapi import FastAPI, Depends, HTTPException, status, Request
from fastapi.security import APIKeyHeader
from fastapi.responses import FileResponse

# Importing classic Python libraries
import os
from dotenv import load_dotenv
from fastapi import FastAPI, Request, Depends
import json
import logging
from datetime import datetime
from db import get_db_pool

# Importing scripts
from scripts import *

# FastAPI instance
app = FastAPI()

# Get API KEY value
load_dotenv()
API_KEY = os.getenv("API_KEY")

# API Key Configuration
API_KEY_NAME = "x-api-key" # Header name
api_key_header = APIKeyHeader(name=API_KEY_NAME)

# Získáme pool při startu serveru
@app.on_event("startup")
async def startup():
    app.state.db_pool = await get_db_pool()

# Zavřeme pool při vypnutí
@app.on_event("shutdown")
async def shutdown():
    await app.state.db_pool.close()

# Dependency to authenticate API key
async def authenticate(api_key: str = Depends(api_key_header)):
	if api_key != API_KEY:
		raise HTTPException(
			status_code=status.HTTP_403_FORBIDDEN,
			detail="Invalid API key",
		)

# Default route
@app.get("/", dependencies=[Depends(authenticate)])
async def read_root():
	return {
		"message": "Welcome to the Prestonet API server!",
		"auth": 1
	}

# Test route
@app.get("/test", dependencies=[Depends(authenticate)])
async def get_test():
	try:
		return get_test_json()
	except Exception as e:
		raise HTTPException(
			status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
			detail=f"An error occurred: {str(e)}",
		)

# QRcode route
@app.get("/qrcode", dependencies=[Depends(authenticate)])
async def get_qrcode(ssid, password, output_file):
	try:
		return generate_qrcode(ssid, password, output_file)
	except ValueError as ve:
		raise HTTPException(
			status_code=status.HTTP_400_BAD_REQUEST,
		    	detail=str(ve)
		)
	except Exception as err:
		raise HTTPException(
            		status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
		    	detail=f"An error occurred: {str(err)}"
		)

# Prestonet Webhooks Log
LOG_FILE = "logs/prestonet_webhooks.log"
logging.basicConfig(filename=LOG_FILE, level=logging.INFO, format="%(asctime)s - %(message)s")

@app.post("/log/prestonet-webhooks", dependencies=[Depends(authenticate)])
async def add_log(request: Request):
	try:
		# body = await request.json()
		# log_entry = json.dumps(body, separators=(',', ':'))
		# logging.info(log_entry)
		body = await request.json()

        	# příklad extrakce z payloadu
        	user = body.get("user")
        	source = body.get("source")
        	button = body.get("button")
        	webhook_url = body.get("webhook_url")
        	run_id = body.get("run_id")
        	status = body.get("status")

        	await add_log_to_db(
            		app.state.db_pool,
            		user=user,
            		source=source,
            		button=button,
            		webhook_url=webhook_url,
            		run_id=run_id,
            		status=status
        	)
		return {"message": "Log saved", "status": "success"}
	except Exception as e:
		logging.error(f"Error saving log: {str(e)}")
		return {"message": "Failed to save log", "status": "error"}

@app.get("/log/prestonet-webhooks", dependencies=[Depends(authenticate)])
async def get_logs(button_name):
	try:
		return get_button_logs("/var/www/api/logs/prestonet_webhooks.log", button_name)
	except ValueError as ve:
		raise HTTPException(
			status_code=status.HTTP_400_BAD_REQUEST,
			detail=str(ve)
		)
	except Exception as err:
		raise HTTPException(
			status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
			detail=f"An error occurred: {str(err)}"
		)

# Prestonet Webhooks admin users
@app.get("/prestonet-webhooks/admin", dependencies=[Depends(authenticate)])
async def get_admin_prestonet_webhooks():
	try:
		return get_admin_list()
	except ValueError as ve:
		raise HTTPException(
			status_code=status.HTTP_400_BAD_REQUEST,
			detail=str(ve)
		)
	except Exception as err:
		raise HTTPException(
			status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
			detail=f"An error occurred: {str(err)}"
		)

@app.get("/prestonet-webhooks/groups", dependencies=[Depends(authenticate)])
async def get_groups_prestonet_webhooks(email):
	try:
		return get_user_group_list(email)
	except ValueError as ve:
		raise HTTPException(
			status_code=status.HTTP_400_BAD_REQUEST,
			detail=str(ve)
		)
	except Exception as err:
		raise HTTPException(
			status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
			detail=f"An error occurred: {str(err)}"
		)

# Set the directory where your images are stored.
# If the images folder is at an absolute path like '/images', use that instead.
IMAGES_DIR = os.path.join(os.path.dirname(__file__), "images")

@app.get("/download/{filename}")
async def download_file(filename: str):
    return
	# Construct the full file path
	#file_path = os.path.join(IMAGES_DIR, filename)

	# Check if the file exists; if not, raise a 404 error.
	#if not os.path.isfile(file_path):
		#raise HTTPException(status_code=404, detail="File not found")

	# Return the file as a downloadable response.
	# 'application/octet-stream' signals a binary file download.
	#return FileResponse(
		#path=file_path,
		#media_type='application/octet-stream',
		#filename=filename  # This will set the 'Content-Disposition' header to trigger a download.
	#)

@app.get("/gpt-tokens", dependencies=[Depends(authenticate)])
async def get_gpt_count(prompt, model="gpt-4o-mini"):
    try:
        return {"number_of_tokens" : count_tokens(prompt, model)}
    except ValueError as ve:
        raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=str(ve)
                )
    except Exception as err:
        raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=f"An error occured {str(err)}"
                )
