import uuid
import logging
from pathlib import Path
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request, status
from fastapi.responses import FileResponse, JSONResponse, RedirectResponse
from fastapi.middleware.cors import CORSMiddleware
from slowapi.errors import RateLimitExceeded
from slowapi import _rate_limit_exceeded_handler
from app.config import settings
from app.security.rate_limit import limiter
from app.models.database import create_tables
from app.routers import health, auth, convert, admin, contact, account

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

FRONTEND_DIR = Path(__file__).resolve().parent.parent / "frontend"


@asynccontextmanager
async def lifespan(app: FastAPI):
    create_tables()
    logger.info("Tablas de base de datos creadas/verificadas")
    yield


app = FastAPI(
    title="Swift Converter API",
    description="Convierte mensajes SWIFT MT940/MT950 a formato ISO 20022 camt.053",
    version="1.0.0",
    lifespan=lifespan,
)

app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)

_legacy_hosts = {h.strip().lower() for h in settings.REDIRECT_LEGACY_HOSTS.split(",") if h.strip()}

if settings.PRIMARY_HOST and _legacy_hosts:
    @app.middleware("http")
    async def redirect_legacy_domain(request: Request, call_next):
        host = request.headers.get("host", "").split(":")[0].lower()
        if host in _legacy_hosts and not request.url.path.startswith("/api/"):
            target = request.url.replace(scheme="https", netloc=settings.PRIMARY_HOST)
            return RedirectResponse(url=str(target), status_code=status.HTTP_301_MOVED_PERMANENTLY)
        return await call_next(request)

# CORS
origins = ["*"] if settings.ENVIRONMENT == "development" else []
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

PREFIX = f"/api/{settings.API_VERSION}"
app.include_router(health.router, prefix=PREFIX)
app.include_router(auth.router, prefix=PREFIX)
app.include_router(convert.router, prefix=PREFIX)
app.include_router(admin.router, prefix=PREFIX)
app.include_router(contact.router, prefix=PREFIX)
app.include_router(account.router, prefix=PREFIX)


@app.get("/", include_in_schema=False)
async def landing():
    return FileResponse(FRONTEND_DIR / "landing.html")


@app.get("/console", include_in_schema=False)
async def console():
    return FileResponse(FRONTEND_DIR / "index.html")


@app.get("/prueba", include_in_schema=False)
async def prueba():
    return FileResponse(FRONTEND_DIR / "prueba.html")


@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    request_id = request.headers.get("X-Request-ID", str(uuid.uuid4()))
    logger.error(f"[{request_id}] Unhandled error: {exc}", exc_info=True)
    return JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content={
            "error": "Internal Server Error",
            "detail": str(exc),
            "request_id": request_id,
        },
    )
