from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, update
from typing import List
from uuid import UUID

from ...core.database import get_db
from ..dependencies import get_current_active_user
from ...models.user import User
from ...models.book import Book
from ...models.book_category import BookCategory
from ...models.document import Document
from ...schemas.book_category import (
    CreateBookCategoryRequest, 
    UpdateBookCategoryRequest, 
    BookCategoryResponse,
    UpdateDocumentOrderRequest
)

router = APIRouter()

@router.post("/", response_model=BookCategoryResponse, status_code=status.HTTP_201_CREATED)
async def create_book_category(
    category_data: CreateBookCategoryRequest,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """새로운 서적 소분류 생성"""
    # 서적 존재 확인
    book_result = await db.execute(select(Book).where(Book.id == category_data.book_id))
    book = book_result.scalar_one_or_none()
    if not book:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Book not found")
    
    # 권한 확인 (관리자만)
    if not current_user.is_admin:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Only administrators can create categories")
    
    new_category = BookCategory(**category_data.model_dump())
    db.add(new_category)
    await db.commit()
    await db.refresh(new_category)
    
    return await _get_category_response(db, new_category)

@router.get("/book/{book_id}", response_model=List[BookCategoryResponse])
async def get_book_categories(
    book_id: UUID,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """특정 서적의 소분류 목록 조회"""
    result = await db.execute(
        select(BookCategory)
        .where(BookCategory.book_id == book_id)
        .order_by(BookCategory.sort_order, BookCategory.name)
    )
    categories = result.scalars().all()
    
    response_categories = []
    for category in categories:
        response_categories.append(await _get_category_response(db, category))
    return response_categories

@router.put("/{category_id}", response_model=BookCategoryResponse)
async def update_book_category(
    category_id: UUID,
    category_data: UpdateBookCategoryRequest,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """서적 소분류 수정"""
    if not current_user.is_admin:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Only administrators can update categories")
    
    result = await db.execute(select(BookCategory).where(BookCategory.id == category_id))
    category = result.scalar_one_or_none()
    if not category:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Category not found")
    
    for field, value in category_data.model_dump(exclude_unset=True).items():
        setattr(category, field, value)
    
    await db.commit()
    await db.refresh(category)
    return await _get_category_response(db, category)

@router.delete("/{category_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_book_category(
    category_id: UUID,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """서적 소분류 삭제 (포함된 문서들은 미분류로 이동)"""
    if not current_user.is_admin:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Only administrators can delete categories")
    
    result = await db.execute(select(BookCategory).where(BookCategory.id == category_id))
    category = result.scalar_one_or_none()
    if not category:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Category not found")
    
    # 포함된 문서들을 미분류로 이동 (category_id를 NULL로 설정)
    await db.execute(
        update(Document)
        .where(Document.category_id == category_id)
        .values(category_id=None)
    )
    
    await db.delete(category)
    await db.commit()
    return {"message": "Category deleted successfully"}

@router.put("/documents/reorder", status_code=status.HTTP_200_OK)
async def update_document_order(
    order_data: UpdateDocumentOrderRequest,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """문서 순서 변경"""
    if not current_user.is_admin:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Only administrators can reorder documents")
    
    # 문서 순서 업데이트
    for item in order_data.document_orders:
        document_id = item.get("document_id")
        sort_order = item.get("sort_order", 0)
        
        await db.execute(
            update(Document)
            .where(Document.id == document_id)
            .values(sort_order=sort_order)
        )
    
    await db.commit()
    return {"message": "Document order updated successfully"}

# Helper function
async def _get_category_response(db: AsyncSession, category: BookCategory) -> BookCategoryResponse:
    """BookCategory를 BookCategoryResponse로 변환"""
    document_count_result = await db.execute(
        select(func.count(Document.id)).where(Document.category_id == category.id)
    )
    document_count = document_count_result.scalar_one()
    
    return BookCategoryResponse(
        id=category.id,
        book_id=category.book_id,
        name=category.name,
        description=category.description,
        sort_order=category.sort_order,
        created_at=category.created_at,
        updated_at=category.updated_at,
        document_count=document_count
    )
