from __future__ import annotations

from datetime import datetime
from pathlib import Path
import logging
import shutil
import uuid

from fastapi import FastAPI, UploadFile, Form
from fastapi.responses import JSONResponse
import uvicorn

from .config import TEMP_DIR, LOG_DIR, SimpleConfig


for folder in [TEMP_DIR, LOG_DIR]:
    folder.mkdir(parents=True, exist_ok=True)

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[
        logging.FileHandler(LOG_DIR / "server.log"),
        logging.StreamHandler()
    ]
)


def save_temp_audio(audio: UploadFile) -> Path:
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    unique_id = uuid.uuid4().hex
    temp_path = TEMP_DIR / f"audio_{timestamp}_{unique_id}.webm"

    with temp_path.open("wb") as f:
        shutil.copyfileobj(audio.file, f)

    logging.info(f"Zapisano tymczasowy plik audio: {temp_path.resolve()}")
    return temp_path


def create_app(manager):
    app = FastAPI()

    # Ostatni segment to PIN wpisywany w przeglądarce (www/pin-gate.js), brany
    # z sekretów jak klucz OpenAI. Żądanie ze złym PIN-em trafia w nieistniejący
    # adres, więc nikt bez PIN-u nie wyśle tu nagrania.
    pin = SimpleConfig.get_string("access-pin")

    @app.post(f"/backendSrv02/{pin}")
    async def upload_backend_srv02(
        audio: UploadFile,
        xpath: list[str] = Form(None),        # jedno pole na każde kliknięcie
        xpath_hash: list[str] = Form(None),   # ekran tego kliknięcia, równolegle do xpath
        xpath_time: list[str] = Form(None),   # sekundy od startu nagrania, równolegle do xpath
        hash: str = Form(None)                # ekran widoczny przy wysyłce (gdy nic nie zaznaczono)
    ):
        logging.info("Odebrano POST /backendSrv02")
        try:
            temp_audio = save_temp_audio(audio)
            manager.submit_audio(temp_audio, xpath, hash, xpath_hash, xpath_time)

            return JSONResponse(
                status_code=200,
                content={
                    "status": "ok",
                    "detail": "Audio dodane do przetworzenia"
                }
            )
        except Exception as e:
            logging.error(f"Upload zakończony błędem: {e}")
            return JSONResponse(
                status_code=500,
                content={
                    "status": "error",
                    "detail": str(e)
                }
            )

    return app


def start_server(manager) -> None:
    host = "0.0.0.0"
    port = 8084
    logging.info(f"Serwer startuje na http://{host}:{port}")
    uvicorn.run(create_app(manager), host=host, port=port, reload=False)