"""
하이라이트 관리 API 라우터
"""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, delete, and_
from sqlalchemy.orm import selectinload
from typing import List, Optional
from datetime import datetime
from uuid import UUID

from ...core.database import get_db
from ...models.user import User
from ...models.document import Document
from ...models.highlight import Highlight
from ...models.note import Note
from ..dependencies import get_current_active_user
from pydantic import BaseModel


class CreateHighlightRequest(BaseModel):
    """하이라이트 생성 요청"""
    document_id: str
    start_offset: int
    end_offset: int
    selected_text: str
    element_selector: Optional[str] = None
    start_container_xpath: Optional[str] = None
    end_container_xpath: Optional[str] = None
    highlight_color: str = "#FFFF00"
    highlight_type: str = "highlight"
    note_content: Optional[str] = None  # 바로 메모 추가


class UpdateHighlightRequest(BaseModel):
    """하이라이트 업데이트 요청"""
    highlight_color: Optional[str] = None
    highlight_type: Optional[str] = None
    note: Optional[str] = None  # 메모 업데이트 지원


class HighlightResponse(BaseModel):
    """하이라이트 응답"""
    id: str
    user_id: str
    document_id: str
    start_offset: int
    end_offset: int
    selected_text: str
    element_selector: Optional[str]
    start_container_xpath: Optional[str]
    end_container_xpath: Optional[str]
    highlight_color: str
    highlight_type: str
    created_at: datetime
    updated_at: Optional[datetime]
    note: Optional[dict] = None  # 연결된 메모 정보

    class Config:
        from_attributes = True


router = APIRouter()






@router.post("/", response_model=HighlightResponse)
async def create_highlight(
    highlight_data: CreateHighlightRequest,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """하이라이트 생성 (메모 포함 가능)"""
    # 문서 존재 및 권한 확인
    result = await db.execute(select(Document).where(Document.id == highlight_data.document_id))
    document = result.scalar_one_or_none()
    
    if not document:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Document not found"
        )
    
    # 문서 접근 권한 확인
    if not document.is_public and document.uploaded_by != current_user.id and not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions to access this document"
        )
    
    # 하이라이트 생성
    highlight = Highlight(
        user_id=current_user.id,
        document_id=highlight_data.document_id,
        start_offset=highlight_data.start_offset,
        end_offset=highlight_data.end_offset,
        selected_text=highlight_data.selected_text,
        element_selector=highlight_data.element_selector,
        start_container_xpath=highlight_data.start_container_xpath,
        end_container_xpath=highlight_data.end_container_xpath,
        highlight_color=highlight_data.highlight_color,
        highlight_type=highlight_data.highlight_type
    )
    
    db.add(highlight)
    await db.flush()  # ID 생성을 위해
    
    # 메모가 있으면 함께 생성
    note = None
    if highlight_data.note_content:
        note = Note(
            highlight_id=highlight.id,
            content=highlight_data.note_content
        )
        db.add(note)
    
    await db.commit()
    await db.refresh(highlight)
    
    # 응답 데이터 생성 (Pydantic v2 호환)
    response_data = HighlightResponse(
        id=str(highlight.id),
            user_id=str(highlight.user_id),
            document_id=str(highlight.document_id),
            start_offset=highlight.start_offset,
            end_offset=highlight.end_offset,
            selected_text=highlight.selected_text,
            element_selector=highlight.element_selector,
            start_container_xpath=highlight.start_container_xpath,
            end_container_xpath=highlight.end_container_xpath,
            highlight_color=highlight.highlight_color,
            highlight_type=highlight.highlight_type,
            created_at=highlight.created_at,
            updated_at=highlight.updated_at,
            note=None
        )
    
    if note:
        response_data.note = {
            "id": str(note.id),
            "content": note.content,
            "tags": note.tags,
            "created_at": note.created_at.isoformat(),
            "updated_at": note.updated_at.isoformat() if note.updated_at else None
        }
    
    return response_data


@router.get("/document/{document_id}", response_model=List[HighlightResponse])
async def get_document_highlights(
    document_id: UUID,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """특정 문서의 하이라이트 목록 조회"""
    try:
        print(f"DEBUG: Getting highlights for document {document_id}, user {current_user.id}")
        
        # 문서 존재 및 권한 확인
        result = await db.execute(select(Document).where(Document.id == document_id))
        document = result.scalar_one_or_none()
        
        if not document:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Document not found"
            )
        
        # 문서 접근 권한 확인
        if not document.is_public and document.uploaded_by != current_user.id and not current_user.is_admin:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="Not enough permissions to access this document"
            ) 
        
        # 사용자의 하이라이트만 조회 (연관된 메모도 함께 로드)
        result = await db.execute(
            select(Highlight)
            .options(selectinload(Highlight.notes))  # 메모 관계 로드
            .where(
                and_(
                    Highlight.document_id == document_id,
                    Highlight.user_id == current_user.id
                )
            )
            .order_by(Highlight.start_offset)
        )
        highlights = result.scalars().all()
        
        print(f"DEBUG: Found {len(highlights)} highlights for user {current_user.id}")
        
        # 응답 데이터 변환
        response_data = []
        for highlight in highlights:
            # 연관된 메모 정보 포함 (notes는 리스트이므로 첫 번째 메모 사용)
            note_data = None
            if highlight.notes and len(highlight.notes) > 0:
                first_note = highlight.notes[0]  # 첫 번째 메모 사용
                note_data = {
                    "id": str(first_note.id),
                    "content": first_note.content,
                    "created_at": first_note.created_at.isoformat(),
                    "updated_at": first_note.updated_at.isoformat() if first_note.updated_at else None
                }
            
            highlight_data = HighlightResponse(
                id=str(highlight.id),
                user_id=str(highlight.user_id),
                document_id=str(highlight.document_id),
                start_offset=highlight.start_offset,
                end_offset=highlight.end_offset,
                selected_text=highlight.selected_text,
                element_selector=highlight.element_selector,
                start_container_xpath=highlight.start_container_xpath,
                end_container_xpath=highlight.end_container_xpath,
                highlight_color=highlight.highlight_color,
                highlight_type=highlight.highlight_type,
                created_at=highlight.created_at,
                updated_at=highlight.updated_at,
                note=note_data
            )
            response_data.append(highlight_data)
        
        return response_data
        
    except Exception as e:
        print(f"ERROR in get_document_highlights: {e}")
        import traceback
        traceback.print_exc()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Internal server error: {str(e)}"
        )


@router.get("/{highlight_id}", response_model=HighlightResponse)
async def get_highlight(
    highlight_id: str,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """하이라이트 상세 조회"""
    result = await db.execute(
        select(Highlight)
        .options(selectinload(Highlight.user))
        .where(Highlight.id == highlight_id)
    )
    highlight = result.scalar_one_or_none()
    
    if not highlight:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Highlight not found"
        )
    
    # 소유자 확인
    if highlight.user_id != current_user.id and not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions"
        )
    
    response_data = HighlightResponse(
        id=str(highlight.id),
            user_id=str(highlight.user_id),
            document_id=str(highlight.document_id),
            start_offset=highlight.start_offset,
            end_offset=highlight.end_offset,
            selected_text=highlight.selected_text,
            element_selector=highlight.element_selector,
            start_container_xpath=highlight.start_container_xpath,
            end_container_xpath=highlight.end_container_xpath,
            highlight_color=highlight.highlight_color,
            highlight_type=highlight.highlight_type,
            created_at=highlight.created_at,
            updated_at=highlight.updated_at,
            note=None
        )
    if highlight.notes:
        response_data.note = {
            "id": str(highlight.notes.id),
            "content": highlight.notes.content,
            "tags": highlight.notes.tags,
            "created_at": highlight.notes.created_at.isoformat(),
            "updated_at": highlight.notes.updated_at.isoformat() if highlight.notes.updated_at else None
        }
    
    return response_data


@router.put("/{highlight_id}", response_model=HighlightResponse)
async def update_highlight(
    highlight_id: str,
    highlight_data: UpdateHighlightRequest,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """하이라이트 업데이트"""
    result = await db.execute(
        select(Highlight)
        .options(selectinload(Highlight.user), selectinload(Highlight.notes))
        .where(Highlight.id == highlight_id)
    )
    highlight = result.scalar_one_or_none()
    
    if not highlight:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Highlight not found"
        )
    
    # 소유자 확인
    if highlight.user_id != current_user.id and not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions"
        )
    
    # 업데이트
    if highlight_data.highlight_color:
        highlight.highlight_color = highlight_data.highlight_color
    if highlight_data.highlight_type:
        highlight.highlight_type = highlight_data.highlight_type
    
    # 메모 업데이트 처리
    if highlight_data.note is not None:
        if highlight.notes:
            # 기존 메모 업데이트
            highlight.notes.content = highlight_data.note
            highlight.notes.updated_at = datetime.utcnow()
        else:
            # 새 메모 생성
            new_note = Note(
                user_id=current_user.id,
                document_id=highlight.document_id,
                highlight_id=highlight.id,
                content=highlight_data.note,
                tags=""
            )
            db.add(new_note)
    
    await db.commit()
    await db.refresh(highlight)
    
    response_data = HighlightResponse(
        id=str(highlight.id),
            user_id=str(highlight.user_id),
            document_id=str(highlight.document_id),
            start_offset=highlight.start_offset,
            end_offset=highlight.end_offset,
            selected_text=highlight.selected_text,
            element_selector=highlight.element_selector,
            start_container_xpath=highlight.start_container_xpath,
            end_container_xpath=highlight.end_container_xpath,
            highlight_color=highlight.highlight_color,
            highlight_type=highlight.highlight_type,
            created_at=highlight.created_at,
            updated_at=highlight.updated_at,
            note=None
        )
    if highlight.notes:
        response_data.note = {
            "id": str(highlight.notes.id),
            "content": highlight.notes.content,
            "tags": highlight.notes.tags,
            "created_at": highlight.notes.created_at.isoformat(),
            "updated_at": highlight.notes.updated_at.isoformat() if highlight.notes.updated_at else None
        }
    
    return response_data


@router.delete("/{highlight_id}")
async def delete_highlight(
    highlight_id: str,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """하이라이트 삭제 (연결된 메모도 함께 삭제)"""
    result = await db.execute(select(Highlight).where(Highlight.id == highlight_id))
    highlight = result.scalar_one_or_none()
    
    if not highlight:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Highlight not found"
        )
    
    # 소유자 확인
    if highlight.user_id != current_user.id and not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions"
        )
    
    # 안전한 하이라이트 삭제 (연결된 메모 먼저 삭제)
    try:
        print(f"DEBUG: Starting deletion of highlight {highlight_id}")
        
        # 1. 먼저 연결된 메모 삭제
        from ...models.note import Note
        note_result = await db.execute(delete(Note).where(Note.highlight_id == highlight_id))
        print(f"DEBUG: Deleted {note_result.rowcount} notes for highlight {highlight_id}")
        
        # 2. 하이라이트 삭제
        highlight_result = await db.execute(delete(Highlight).where(Highlight.id == highlight_id))
        print(f"DEBUG: Deleted {highlight_result.rowcount} highlights")
        
        # 3. 커밋
        await db.commit()
        print(f"DEBUG: Successfully deleted highlight {highlight_id}")
        
    except Exception as e:
        print(f"ERROR: Failed to delete highlight {highlight_id}: {e}")
        await db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to delete highlight: {str(e)}"
        )
    
    return {"message": "Highlight deleted successfully"}


@router.get("/", response_model=List[HighlightResponse])
async def list_user_highlights(
    skip: int = 0,
    limit: int = 50,
    document_id: Optional[str] = None,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """사용자의 모든 하이라이트 조회"""
    query = select(Highlight).options(selectinload(Highlight.user)).where(
        Highlight.user_id == current_user.id
    )
    
    if document_id:
        query = query.where(Highlight.document_id == document_id)
    
    query = query.order_by(Highlight.created_at.desc()).offset(skip).limit(limit)
    
    result = await db.execute(query)
    highlights = result.scalars().all()
    
    # 응답 데이터 변환
    response_data = []
    for highlight in highlights:
        highlight_data = HighlightResponse(
            id=str(highlight.id),
            user_id=str(highlight.user_id),
            document_id=str(highlight.document_id),
            start_offset=highlight.start_offset,
            end_offset=highlight.end_offset,
            selected_text=highlight.selected_text,
            element_selector=highlight.element_selector,
            start_container_xpath=highlight.start_container_xpath,
            end_container_xpath=highlight.end_container_xpath,
            highlight_color=highlight.highlight_color,
            highlight_type=highlight.highlight_type,
            created_at=highlight.created_at,
            updated_at=highlight.updated_at,
            note=None
        )
        # 메모는 별도 API에서 조회하므로 여기서는 처리하지 않음
        response_data.append(highlight_data)
    
    return response_data
