import uuid

from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile
from sqlalchemy import delete, select
from sqlalchemy.ext.asyncio import AsyncSession

from app.dependencies import get_db, get_face_service
from app.models.face import FaceEmbedding
from app.models.user import User
from app.schemas.face import FaceDeleteResponse, FaceIdentifyResponse, FaceRegisterResponse
from app.services.face_service import FaceService
from app.utils.image import delete_image

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


@router.post("/register", response_model=FaceRegisterResponse)
async def register_face(
    image: UploadFile = File(...),
    user_name: str = Form(...),
    db: AsyncSession = Depends(get_db),
    face_service: FaceService = Depends(get_face_service),
):
    """Register face for a user.

    - If face matches an existing user → adds embedding to that user (face priority)
    - If no match → gets or creates user by name → adds embedding
    """
    image_bytes = await image.read()
    try:
        result = await face_service.register(db, image_bytes, user_name)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    return FaceRegisterResponse(**result)


@router.post("/identify", response_model=FaceIdentifyResponse)
async def identify_face(
    image: UploadFile = File(...),
    db: AsyncSession = Depends(get_db),
    face_service: FaceService = Depends(get_face_service),
):
    """Identify user from face image."""
    image_bytes = await image.read()
    try:
        result = await face_service.identify(db, image_bytes)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))

    if result is None:
        raise HTTPException(status_code=404, detail="매칭되는 사용자를 찾을 수 없습니다.")

    return FaceIdentifyResponse(**result)


@router.delete("/{user_id}", response_model=FaceDeleteResponse)
async def delete_faces(
    user_id: uuid.UUID,
    db: AsyncSession = Depends(get_db),
):
    """Delete all face embeddings and face images for a user."""
    # Verify user exists
    user_result = await db.execute(select(User).where(User.id == user_id))
    user = user_result.scalar_one_or_none()
    if user is None:
        raise HTTPException(status_code=404, detail="사용자를 찾을 수 없습니다.")

    # Fetch face embeddings to get image paths
    result = await db.execute(
        select(FaceEmbedding).where(FaceEmbedding.user_id == user_id)
    )
    embeddings = list(result.scalars().all())

    if not embeddings:
        raise HTTPException(status_code=404, detail="등록된 얼굴이 없습니다.")

    # Collect image paths before deletion
    image_paths = [e.image_path for e in embeddings]

    # Delete DB records
    await db.execute(
        delete(FaceEmbedding).where(FaceEmbedding.user_id == user_id)
    )
    await db.commit()

    # Delete image files
    for path in image_paths:
        delete_image(path)

    return FaceDeleteResponse(user_id=user_id, deleted_count=len(embeddings))
