"""Tag management endpoints."""

from __future__ import annotations

from typing import List

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session

from backend.db.session import get_db
from backend.schemas.tags import (
    PhotoTagsRequest,
    PhotoTagsResponse,
    TagCreateRequest,
    TagResponse,
    TagsResponse,
    TagUpdateRequest,
    TagDeleteRequest,
    PhotoTagsListResponse,
    PhotoTagItem,
    PhotosWithTagsResponse,
    PhotoWithTagsItem,
)
from backend.services.tag_service import (
    add_tags_to_photos,
    get_or_create_tag,
    list_tags,
    remove_tags_from_photos,
    get_photo_tags,
    update_tag,
    delete_tags,
    get_photos_with_tags,
)
from backend.db.models import Photo

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


@router.get("", response_model=TagsResponse)
def get_tags(db: Session = Depends(get_db)) -> TagsResponse:
    """List all tags."""
    tags = list_tags(db)
    items = [TagResponse.model_validate(t) for t in tags]
    return TagsResponse(items=items, total=len(items))


@router.post("", response_model=TagResponse)
def create_tag(
    request: TagCreateRequest, db: Session = Depends(get_db)
) -> TagResponse:
    """Create a new tag (or return existing if already exists)."""
    tag = get_or_create_tag(db, request.tag_name)
    db.commit()
    db.refresh(tag)
    return TagResponse.model_validate(tag)


@router.post("/photos/add", response_model=PhotoTagsResponse)
def add_tags_to_photos_endpoint(
    request: PhotoTagsRequest, db: Session = Depends(get_db)
) -> PhotoTagsResponse:
    """Add tags to multiple photos."""
    if not request.photo_ids:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="photo_ids is required"
        )
    if not request.tag_names:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="tag_names is required"
        )
    
    photos_updated, tags_added = add_tags_to_photos(
        db, request.photo_ids, request.tag_names
    )
    
    return PhotoTagsResponse(
        message=f"Added tags to {photos_updated} photos",
        photos_updated=photos_updated,
        tags_added=tags_added,
        tags_removed=0,
    )


@router.post("/photos/remove", response_model=PhotoTagsResponse)
def remove_tags_from_photos_endpoint(
    request: PhotoTagsRequest, db: Session = Depends(get_db)
) -> PhotoTagsResponse:
    """Remove tags from multiple photos."""
    if not request.photo_ids:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="photo_ids is required"
        )
    if not request.tag_names:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="tag_names is required"
        )
    
    photos_updated, tags_removed = remove_tags_from_photos(
        db, request.photo_ids, request.tag_names
    )
    
    return PhotoTagsResponse(
        message=f"Removed tags from {photos_updated} photos",
        photos_updated=photos_updated,
        tags_added=0,
        tags_removed=tags_removed,
    )


@router.get("/photos/{photo_id}", response_model=PhotoTagsListResponse)
def get_photo_tags_endpoint(
    photo_id: int, db: Session = Depends(get_db)
) -> PhotoTagsListResponse:
    """Get all tags for a specific photo."""
    # Validate photo exists
    photo = db.query(Photo).filter(Photo.id == photo_id).first()
    if not photo:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail=f"Photo {photo_id} not found"
        )
    
    tags_data = get_photo_tags(db, photo_id)
    
    items = [
        PhotoTagItem(tag_id=tag_id, tag_name=tag_name)
        for tag_id, tag_name in tags_data
    ]
    
    return PhotoTagsListResponse(photo_id=photo_id, tags=items, total=len(items))


@router.put("/{tag_id}", response_model=TagResponse)
def update_tag_endpoint(
    tag_id: int, request: TagUpdateRequest, db: Session = Depends(get_db)
) -> TagResponse:
    """Update a tag name."""
    try:
        tag = update_tag(db, tag_id, request.tag_name)
        return TagResponse.model_validate(tag)
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)
        )


@router.post("/delete", response_model=dict)
def delete_tags_endpoint(
    request: TagDeleteRequest, db: Session = Depends(get_db)
) -> dict:
    """Delete tags and all their linkages."""
    if not request.tag_ids:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="tag_ids list cannot be empty",
        )
    
    deleted_count = delete_tags(db, request.tag_ids)
    
    return {
        "message": f"Deleted {deleted_count} tag(s)",
        "deleted_count": deleted_count,
    }


@router.get("/photos", response_model=PhotosWithTagsResponse)
def get_photos_with_tags_endpoint(db: Session = Depends(get_db)) -> PhotosWithTagsResponse:
    """Get all photos with tags and face counts, matching desktop tag manager query exactly.
    
    Returns all photos with their tags (comma-separated) and face counts,
    ordered by date_taken DESC, filename.
    """
    photos_data = get_photos_with_tags(db)
    
    items = [
        PhotoWithTagsItem(
            id=p['id'],
            filename=p['filename'],
            path=p['path'],
            processed=p['processed'],
            date_taken=p['date_taken'],
            date_added=p['date_added'],
            face_count=p['face_count'],
            unidentified_face_count=p['unidentified_face_count'],
            tags=p['tags'],
            people_names=p.get('people_names', ''),
        )
        for p in photos_data
    ]
    
    return PhotosWithTagsResponse(items=items, total=len(items))

