from pathlib import Path
import uuid

from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile
from fastapi.responses import FileResponse

from app.deps import get_current_user, user_permissions
from app.models import User

router = APIRouter(tags=["media"])

UPLOAD_ROOT = Path(__file__).resolve().parents[1] / "uploads"
PRODUCT_DIR = UPLOAD_ROOT / "products"
GALLERY_DIR = UPLOAD_ROOT / "gallery"

IMAGE_TYPES = {
    "image/jpeg": ".jpg",
    "image/jpg": ".jpg",
    "image/png": ".png",
    "image/webp": ".webp",
    "image/gif": ".gif",
}
VIDEO_TYPES = {
    "video/mp4": ".mp4",
    "video/quicktime": ".mov",
    "video/x-msvideo": ".avi",
    "video/webm": ".webm",
    "video/3gpp": ".3gp",
}


def ensure_upload_dirs() -> None:
    PRODUCT_DIR.mkdir(parents=True, exist_ok=True)
    GALLERY_DIR.mkdir(parents=True, exist_ok=True)


def _extension_for(kind: str, content_type: str, filename: str | None) -> str:
    name = (filename or "").lower()
    if kind == "image":
        ext = IMAGE_TYPES.get(content_type)
        if ext:
            return ext
        if name.endswith((".jpg", ".jpeg")):
            return ".jpg"
        if name.endswith(".png"):
            return ".png"
        if name.endswith(".webp"):
            return ".webp"
        if name.endswith(".gif"):
            return ".gif"
        raise HTTPException(status_code=400, detail="Unsupported image type")
    ext = VIDEO_TYPES.get(content_type)
    if ext:
        return ext
    if name.endswith(".mp4"):
        return ".mp4"
    if name.endswith(".mov"):
        return ".mov"
    if name.endswith(".webm"):
        return ".webm"
    if name.endswith((".avi", ".3gp")):
        return Path(name).suffix
    raise HTTPException(status_code=400, detail="Unsupported video type")


@router.post("/uploads/products")
async def upload_product_media(
    file: UploadFile = File(...),
    kind: str = Form("image"),
    user: User = Depends(get_current_user),
):
    perms = user_permissions(user)
    if "product.create" not in perms and "product.edit" not in perms:
        raise HTTPException(status_code=403, detail="Missing permission: product.create or product.edit")
    ensure_upload_dirs()
    media_kind = (kind or "image").strip().lower()
    if media_kind not in {"image", "video"}:
        raise HTTPException(status_code=400, detail="kind must be image or video")
    content_type = (file.content_type or "").lower()
    ext = _extension_for(media_kind, content_type, file.filename)
    filename = f"{uuid.uuid4().hex}{ext}"
    dest = PRODUCT_DIR / filename
    data = await file.read()
    if not data:
        raise HTTPException(status_code=400, detail="Empty file")
    if len(data) > 25 * 1024 * 1024:
        raise HTTPException(status_code=400, detail="File too large (max 25 MB)")
    dest.write_bytes(data)
    return {
        "url": f"/api/v1/media/products/{filename}",
        "kind": media_kind,
        "filename": filename,
        "content_type": content_type or None,
    }


@router.post("/uploads/gallery")
async def upload_gallery_media(
    file: UploadFile = File(...),
    user: User = Depends(get_current_user),
):
    perms = user_permissions(user)
    if "gallery.create" not in perms and "gallery.edit" not in perms:
        raise HTTPException(status_code=403, detail="Missing permission: gallery.create or gallery.edit")
    ensure_upload_dirs()
    content_type = (file.content_type or "").lower()
    ext = _extension_for("image", content_type, file.filename)
    filename = f"{uuid.uuid4().hex}{ext}"
    dest = GALLERY_DIR / filename
    data = await file.read()
    if not data:
        raise HTTPException(status_code=400, detail="Empty file")
    if len(data) > 25 * 1024 * 1024:
        raise HTTPException(status_code=400, detail="File too large (max 25 MB)")
    dest.write_bytes(data)
    return {
        "url": f"/api/v1/media/gallery/{filename}",
        "kind": "image",
        "filename": filename,
        "content_type": content_type or None,
    }


@router.get("/media/gallery/{filename}")
def get_gallery_media(filename: str):
    safe = Path(filename).name
    path = GALLERY_DIR / safe
    if not path.exists() or not path.is_file():
        raise HTTPException(status_code=404, detail="File not found")
    return FileResponse(path)


@router.get("/media/products/{filename}")
def get_product_media(filename: str):
    safe = Path(filename).name
    path = PRODUCT_DIR / safe
    if not path.exists() or not path.is_file():
        raise HTTPException(status_code=404, detail="File not found")
    return FileResponse(path)
