import os
import uuid
import hashlib
from pathlib import Path
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Query
from sqlalchemy.orm import Session
from sqlalchemy import func
from typing import List, Optional

from ..database import get_db
from ..models import MediaAsset
from ..schemas import MediaAssetCreate, MediaAssetUpdate, MediaAssetResponse
from .auth import get_current_user

router = APIRouter(prefix="/api/assets", tags=["assets"])

PROJECT_ROOT = Path(__file__).resolve().parents[4]
if os.getenv('PROJECT_ROOT'):
    PROJECT_ROOT = Path(os.getenv('PROJECT_ROOT'))
UPLOAD_DIR = PROJECT_ROOT / "content" / "images"
ALLOWED_IMAGE_TYPES = {"image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"}


@router.get("", response_model=List[MediaAssetResponse])
def list_assets(
    file_type: Optional[str] = None,
    tag: Optional[str] = None,
    topic_id: Optional[str] = None,
    search: Optional[str] = None,
    limit: int = Query(50, le=200),
    offset: int = Query(0, ge=0),
    db: Session = Depends(get_db),
    current_user=Depends(get_current_user)
):
    query = db.query(MediaAsset)

    if file_type:
        query = query.filter(MediaAsset.file_type == file_type)
    if tag:
        query = query.filter(MediaAsset.tags.contains([tag]))
    if topic_id:
        query = query.filter(MediaAsset.topic_ids.contains([topic_id]))
    if search:
        query = query.filter(
            (MediaAsset.filename.contains(search)) |
            (MediaAsset.alt_text.contains(search))
        )

    return query.order_by(MediaAsset.created_at.desc()).offset(offset).limit(limit).all()


@router.get("/tags")
def list_tags(
    db: Session = Depends(get_db),
    current_user=Depends(get_current_user)
):
    assets = db.query(MediaAsset.tags).all()
    all_tags = set()
    for a in assets:
        if a[0]:
            all_tags.update(a[0])
    return sorted(all_tags)


@router.get("/counts")
def get_counts(
    db: Session = Depends(get_db),
    current_user=Depends(get_current_user)
):
    total = db.query(MediaAsset).count()
    by_type = {}
    rows = db.query(MediaAsset.file_type, func.count(MediaAsset.id)).group_by(MediaAsset.file_type).all()
    for ftype, cnt in rows:
        by_type[ftype] = cnt
    return {"total": total, "by_type": by_type}


@router.post("/upload", response_model=MediaAssetResponse)
async def upload_asset(
    file: UploadFile = File(...),
    tags: Optional[str] = Query(None, description="逗号分隔的标签"),
    alt_text: Optional[str] = Query(None),
    topic_ids: Optional[str] = Query(None, description="逗号分隔的选题ID"),
    db: Session = Depends(get_db),
    current_user=Depends(get_current_user)
):
    if file.content_type not in ALLOWED_IMAGE_TYPES:
        raise HTTPException(status_code=400, detail=f"不支持的文件类型: {file.content_type}")

    UPLOAD_DIR.mkdir(parents=True, exist_ok=True)

    suffix = Path(file.filename).suffix or ""
    unique_name = f"{uuid.uuid4().hex[:12]}{suffix}"
    file_path = UPLOAD_DIR / unique_name

    content = await file.read()
    file_size = len(content)

    with open(file_path, "wb") as f:
        f.write(content)

    file_type = file.content_type.split("/")[0]
    if file_type not in ("image", "video", "application"):
        if suffix in (".pdf", ".doc", ".docx", ".ppt", ".pptx"):
            file_type = "document"
        elif suffix in (".mp4", ".mov", ".avi"):
            file_type = "video"
        else:
            file_type = "image"

    parsed_tags = [t.strip() for t in tags.split(",")] if tags else []
    parsed_topic_ids = [t.strip() for t in topic_ids.split(",")] if topic_ids else []

    asset = MediaAsset(
        filename=file.filename,
        file_path=str(file_path),
        file_type=file_type,
        mime_type=file.content_type,
        size=file_size,
        alt_text=alt_text,
        tags=parsed_tags,
        topic_ids=parsed_topic_ids,
        uploaded_by=current_user.username
    )
    db.add(asset)
    db.commit()
    db.refresh(asset)
    return asset


@router.put("/{asset_id}", response_model=MediaAssetResponse)
def update_asset(
    asset_id: int,
    data: MediaAssetUpdate,
    db: Session = Depends(get_db),
    current_user=Depends(get_current_user)
):
    asset = db.query(MediaAsset).filter(MediaAsset.id == asset_id).first()
    if not asset:
        raise HTTPException(status_code=404, detail="素材不存在")

    for k, v in data.model_dump(exclude_unset=True).items():
        setattr(asset, k, v)
    db.commit()
    db.refresh(asset)
    return asset


@router.delete("/{asset_id}")
def delete_asset(
    asset_id: int,
    db: Session = Depends(get_db),
    current_user=Depends(get_current_user)
):
    asset = db.query(MediaAsset).filter(MediaAsset.id == asset_id).first()
    if not asset:
        raise HTTPException(status_code=404, detail="素材不存在")

    if os.path.exists(asset.file_path):
        try:
            os.remove(asset.file_path)
        except OSError:
            pass

    db.delete(asset)
    db.commit()
    return {"ok": True}


@router.post("/{asset_id}/use")
def increment_usage(
    asset_id: int,
    db: Session = Depends(get_db),
    current_user=Depends(get_current_user)
):
    asset = db.query(MediaAsset).filter(MediaAsset.id == asset_id).first()
    if not asset:
        raise HTTPException(status_code=404, detail="素材不存在")
    asset.usage_count = (asset.usage_count or 0) + 1
    db.commit()
    return {"ok": True, "usage_count": asset.usage_count}