from fastapi import APIRouter, Depends, HTTPException, UploadFile, File
from fastapi.responses import FileResponse, HTMLResponse
from sqlalchemy.ext.asyncio import AsyncSession
import logging

from app.core.config import settings
from app.core.dependencies import get_current_actor
from app.core.responses import api_response
from app.db.database import get_async_session
from app.services.fichier_service import FichierService

router = APIRouter(prefix="/fichiers", tags=["Fichiers"])

_fichier_service = FichierService()
_MAX_BYTES = settings.max_file_size_mb * 1024 * 1024
logger = logging.getLogger(__name__)


@router.post("/upload", status_code=201)
async def upload_fichier(
    file: UploadFile = File(...),
    _current_actor=Depends(get_current_actor),
):
    logger.info("Received upload request: filename=%s, content_type=%s, size=%s",
                file.filename, file.content_type, file.size)

    content = await file.read()
    logger.info("File read: filename=%s, bytes_read=%d", file.filename, len(content))

    if len(content) > _MAX_BYTES:
        logger.warning("File too large: filename=%s, size=%d, max=%d",
                       file.filename, len(content), _MAX_BYTES)
        raise HTTPException(
            status_code=413,
            detail=f"Fichier trop volumineux (max {settings.max_file_size_mb} Mo)",
        )

    data = await _fichier_service.upload(
        filename=file.filename or "file",
        content=content,
        content_type=file.content_type or "application/octet-stream",
    )

    logger.info("Upload success: fileId=%s, url=%s, original_name=%s",
                data.get("fileId"), data.get("url"), data.get("nom"))
    return api_response(data, message="Fichier uploadé", status_code=201)


@router.get("/{file_id}")
async def get_fichier_url(
    file_id: str,
    _current_actor=Depends(get_current_actor),
):
    url = await _fichier_service.get_url(file_id)
    return api_response({"url": url, "fileId": file_id}, message="URL récupérée")


@router.get("/download/{file_id}")
async def download_fichier(
    file_id: str,
    _current_actor=Depends(get_current_actor),
):
    try:
        file_path = _fichier_service.get_path(file_id)
    except ValueError as exc:
        raise HTTPException(status_code=400, detail=str(exc))

    if not file_path.exists():
        raise HTTPException(status_code=404, detail="Fichier introuvable")
    return FileResponse(
        path=str(file_path),
        filename=file_path.name,
        media_type="application/octet-stream",
    )


@router.get("/preview/{file_id}", response_class=HTMLResponse)
async def preview_fichier(
    file_id: str,
    _current_actor=Depends(get_current_actor),
):
    try:
        file_path = _fichier_service.get_path(file_id)
    except ValueError as exc:
        raise HTTPException(status_code=400, detail=str(exc))

    if not file_path.exists():
        raise HTTPException(status_code=404, detail="Fichier introuvable")

    content_type = "application/octet-stream"
    if file_path.suffix.lower() in {".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"}:
        content_type = f"image/{file_path.suffix.lower().lstrip('.')}"
    elif file_path.suffix.lower() == ".pdf":
        content_type = "application/pdf"

    return FileResponse(
        path=str(file_path),
        media_type=content_type,
        filename=file_path.name,
    )


@router.delete("/{file_id}", status_code=204)
async def delete_fichier(
    file_id: str,
    _current_actor=Depends(get_current_actor),
    db: AsyncSession = Depends(get_async_session),
):
    try:
        await _fichier_service.delete(file_id)
    except ValueError as exc:
        raise HTTPException(status_code=400, detail=str(exc))
