"""
노트 문서 관련 API 엔드포인트
"""
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from sqlalchemy import func, desc, asc
from typing import List, Optional
import html

from ...core.database import get_sync_db
from ..dependencies import get_current_user
from ...models.user import User
from ...models.note_document import (
    NoteDocument, 
    NoteDocumentCreate, 
    NoteDocumentUpdate, 
    NoteDocumentResponse,
    NoteDocumentListItem,
    NoteStats
)
from ...models.notebook import Notebook

router = APIRouter()


def calculate_reading_time(content: str) -> int:
    """HTML 내용에서 예상 읽기 시간 계산 (분)"""
    if not content:
        return 0
    
    # HTML 태그 제거
    text_content = html.unescape(content)
    # 간단한 HTML 태그 제거 (정확하지 않지만 대략적인 계산용)
    import re
    text_content = re.sub(r'<[^>]+>', '', text_content)
    
    # 단어 수 계산 (한국어 + 영어)
    words = len(text_content.split())
    korean_chars = len([c for c in text_content if '\uac00' <= c <= '\ud7af'])
    
    # 대략적인 읽기 속도: 영어 200단어/분, 한국어 300자/분
    english_time = words / 200
    korean_time = korean_chars / 300
    
    return max(1, int(english_time + korean_time))


@router.get("/", response_model=List[NoteDocumentListItem])
def get_note_documents(
    skip: int = Query(0, ge=0),
    limit: int = Query(50, ge=1, le=100),
    search: Optional[str] = Query(None),
    note_type: Optional[str] = Query(None),
    published_only: bool = Query(False),
    notebook_id: Optional[str] = Query(None),
    sort_by: str = Query("updated_at", regex="^(title|created_at|updated_at|word_count)$"),
    order: str = Query("desc", regex="^(asc|desc)$"),
    db: Session = Depends(get_sync_db),
    current_user: User = Depends(get_current_user)
):
    """노트 문서 목록 조회"""
    query = db.query(NoteDocument)
    
    # 필터링
    if search:
        search_term = f"%{search}%"
        query = query.filter(
            (NoteDocument.title.ilike(search_term)) |
            (NoteDocument.content.ilike(search_term))
        )
    
    if note_type:
        query = query.filter(NoteDocument.note_type == note_type)
    
    if published_only:
        query = query.filter(NoteDocument.is_published == True)
    
    if notebook_id:
        query = query.filter(NoteDocument.notebook_id == notebook_id)
    
    # 정렬
    if sort_by == 'title':
        query = query.order_by(asc(NoteDocument.title) if order == 'asc' else desc(NoteDocument.title))
    elif sort_by == 'created_at':
        query = query.order_by(asc(NoteDocument.created_at) if order == 'asc' else desc(NoteDocument.created_at))
    elif sort_by == 'word_count':
        query = query.order_by(asc(NoteDocument.word_count) if order == 'asc' else desc(NoteDocument.word_count))
    else:
        query = query.order_by(desc(NoteDocument.updated_at))
    
    # 페이지네이션
    notes = query.offset(skip).limit(limit).all()
    
    # 자식 노트 개수 계산
    result = []
    for note in notes:
        child_count = db.query(func.count(NoteDocument.id)).filter(
            NoteDocument.parent_note_id == note.id
        ).scalar()
        
        note_item = NoteDocumentListItem.from_orm(note, child_count)
        result.append(note_item)
    
    return result


@router.get("/stats", response_model=NoteStats)
def get_note_stats(
    db: Session = Depends(get_sync_db),
    current_user: User = Depends(get_current_user)
):
    """노트 통계 정보"""
    total_notes = db.query(func.count(NoteDocument.id)).scalar()
    published_notes = db.query(func.count(NoteDocument.id)).filter(
        NoteDocument.is_published == True
    ).scalar()
    draft_notes = total_notes - published_notes
    
    # 노트 타입별 통계
    type_stats = db.query(
        NoteDocument.note_type, 
        func.count(NoteDocument.id)
    ).group_by(NoteDocument.note_type).all()
    note_types = {note_type: count for note_type, count in type_stats}
    
    # 총 단어 수와 읽기 시간
    total_words = db.query(func.sum(NoteDocument.word_count)).scalar() or 0
    total_reading_time = db.query(func.sum(NoteDocument.reading_time)).scalar() or 0
    
    # 최근 노트들
    recent_notes_query = db.query(NoteDocument).order_by(
        desc(NoteDocument.updated_at)
    ).limit(5).all()
    
    recent_notes = [NoteDocumentListItem.from_orm(note) for note in recent_notes_query]
    
    return NoteStats(
        total_notes=total_notes,
        published_notes=published_notes,
        draft_notes=draft_notes,
        note_types=note_types,
        total_words=total_words,
        total_reading_time=total_reading_time,
        recent_notes=recent_notes
    )


@router.get("/{note_id}", response_model=NoteDocumentResponse)
def get_note_document(
    note_id: str,
    db: Session = Depends(get_sync_db),
    current_user: User = Depends(get_current_user)
):
    """특정 노트 문서 조회"""
    note = db.query(NoteDocument).filter(NoteDocument.id == note_id).first()
    if not note:
        raise HTTPException(status_code=404, detail="Note not found")
    
    return NoteDocumentResponse.from_orm(note)


@router.post("/", response_model=NoteDocumentResponse)
def create_note_document(
    note_data: NoteDocumentCreate,
    db: Session = Depends(get_sync_db),
    current_user: User = Depends(get_current_user)
):
    """새 노트 문서 생성"""
    # 단어 수 및 읽기 시간 계산
    word_count = len(note_data.content or '') if note_data.content else 0
    reading_time = calculate_reading_time(note_data.content or '')
    
    note = NoteDocument(
        title=note_data.title,
        content=note_data.content,
        note_type=note_data.note_type,
        tags=note_data.tags,
        is_published=note_data.is_published,
        parent_note_id=note_data.parent_note_id,
        sort_order=note_data.sort_order,
        created_by=current_user.email,
        word_count=word_count,
        reading_time=reading_time
    )
    
    db.add(note)
    db.commit()
    db.refresh(note)
    
    return NoteDocumentResponse.from_orm(note)


@router.put("/{note_id}", response_model=NoteDocumentResponse)
def update_note_document(
    note_id: str,
    note_data: NoteDocumentUpdate,
    db: Session = Depends(get_sync_db),
    current_user: User = Depends(get_current_user)
):
    """노트 문서 업데이트"""
    note = db.query(NoteDocument).filter(NoteDocument.id == note_id).first()
    if not note:
        raise HTTPException(status_code=404, detail="Note not found")
    
    # 권한 확인
    if note.created_by != current_user.email and not current_user.is_admin:
        raise HTTPException(status_code=403, detail="Permission denied")
    
    # 업데이트할 필드만 적용
    update_data = note_data.dict(exclude_unset=True)
    
    # 내용이 변경되면 단어 수와 읽기 시간 재계산
    if 'content' in update_data:
        update_data['word_count'] = len(update_data['content'] or '')
        update_data['reading_time'] = calculate_reading_time(update_data['content'] or '')
    
    for field, value in update_data.items():
        setattr(note, field, value)
    
    db.commit()
    db.refresh(note)
    
    return NoteDocumentResponse.from_orm(note)


@router.delete("/{note_id}")
def delete_note_document(
    note_id: str,
    db: Session = Depends(get_sync_db),
    current_user: User = Depends(get_current_user)
):
    """노트 문서 삭제"""
    note = db.query(NoteDocument).filter(NoteDocument.id == note_id).first()
    if not note:
        raise HTTPException(status_code=404, detail="Note not found")
    
    # 권한 확인
    if note.created_by != current_user.email and not current_user.is_admin:
        raise HTTPException(status_code=403, detail="Permission denied")
    
    # 자식 노트들이 있는지 확인
    child_count = db.query(func.count(NoteDocument.id)).filter(
        NoteDocument.parent_note_id == note.id
    ).scalar()
    
    if child_count > 0:
        raise HTTPException(
            status_code=400, 
            detail=f"Cannot delete note with {child_count} child notes"
        )
    
    db.delete(note)
    db.commit()
    
    return {"message": "Note deleted successfully"}


@router.get("/{note_id}/content")
def get_note_document_content(
    note_id: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_sync_db)
):
    """노트 문서의 HTML 콘텐츠만 반환"""
    note = db.query(NoteDocument).filter(NoteDocument.id == note_id).first()
    
    if not note:
        raise HTTPException(status_code=404, detail="Note document not found")
    
    return note.content or ""
