"""
노트 문서 (Note Document) 관리 API

용어 정의:
- 노트 (Note Document): 독립적인 HTML 기반 문서 작성
- 노트북 (Notebook): 노트들을 그룹화하는 폴더  
- 메모 (Memo): 하이라이트에 달리는 짧은 코멘트 (별도 API - highlights.py)
"""

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session, selectinload
from sqlalchemy import func, desc, asc, select
from typing import List, Optional
# import markdown  # 임시로 비활성화
import re
from datetime import datetime, timedelta

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

router = APIRouter()

# === 하이라이트 메모 (Highlight Memo) API ===
# 용어 정의: 하이라이트에 달리는 짧은 코멘트

@router.post("/")
async def create_note(
    note_data: dict,
    db: Session = Depends(get_sync_db),
    current_user: User = Depends(get_current_user)
):
    """하이라이트 메모 생성"""
    from ...models.note import Note
    from ...models.highlight import Highlight
    
    # 하이라이트 소유권 확인
    highlight = db.query(Highlight).filter(
        Highlight.id == note_data.get('highlight_id'),
        Highlight.user_id == current_user.id
    ).first()
    
    if not highlight:
        raise HTTPException(status_code=404, detail="하이라이트를 찾을 수 없습니다")
    
    # 메모 생성
    note = Note(
        highlight_id=note_data.get('highlight_id'),
        content=note_data.get('content', ''),
        is_private=note_data.get('is_private', False),
        tags=note_data.get('tags', [])
    )
    
    db.add(note)
    db.commit()
    db.refresh(note)
    
    return note

@router.get("/document/{document_id}")
async def get_document_notes(
    document_id: str,
    db: Session = Depends(get_sync_db),
    current_user: User = Depends(get_current_user)
):
    """특정 문서의 모든 하이라이트 메모 조회"""
    from ...models.note import Note
    from ...models.highlight import Highlight
    
    notes = db.query(Note).join(Highlight).filter(
        Highlight.document_id == document_id,
        Highlight.user_id == current_user.id
    ).options(
        selectinload(Note.highlight)
    ).all()
    
    return notes

def clean_html_content(content: str) -> str:
    """HTML 내용 정리 및 검증"""
    if not content:
        return ""
    
    # 기본적인 HTML 정리 (나중에 더 정교하게 할 수 있음)
    return content.strip()

def calculate_reading_time(content: str) -> int:
    """읽기 시간 계산 (분 단위)"""
    if not content:
        return 0
    
    # 단어 수 계산 (한글, 영문 모두 고려)
    korean_chars = len(re.findall(r'[가-힣]', content))
    english_words = len(re.findall(r'\b[a-zA-Z]+\b', content))
    
    # 한글: 분당 500자, 영문: 분당 200단어 기준
    korean_time = korean_chars / 500
    english_time = english_words / 200
    
    total_minutes = max(1, int(korean_time + english_time))
    return total_minutes

def calculate_word_count(content: str) -> int:
    """단어/글자 수 계산"""
    if not content:
        return 0
    
    korean_chars = len(re.findall(r'[가-힣]', content))
    english_words = len(re.findall(r'\b[a-zA-Z]+\b', content))
    
    return korean_chars + english_words

@router.get("/", response_model=List[NoteDocumentListItem])
def get_notes(
    skip: int = Query(0, ge=0),
    limit: int = Query(50, ge=1, le=100),
    note_type: Optional[str] = Query(None),
    tags: Optional[str] = Query(None),  # 쉼표로 구분된 태그
    search: Optional[str] = Query(None),
    published_only: bool = Query(False),
    parent_id: Optional[str] = Query(None),
    notebook_id: Optional[str] = Query(None),  # 노트북 필터
    db: Session = Depends(get_sync_db),
    current_user: User = Depends(get_current_user)
):
    """노트 목록 조회"""
    # 동기 SQLAlchemy 스타일
    query = db.query(NoteDocument)
    
    # 필터링
    if note_type:
        query = query.filter(NoteDocument.note_type == note_type)
    
    if tags:
        tag_list = [tag.strip() for tag in tags.split(',')]
        query = query.filter(NoteDocument.tags.overlap(tag_list))
    
    if search:
        search_term = f"%{search}%"
        query = query.filter(
            (NoteDocument.title.ilike(search_term)) |
            (NoteDocument.content.ilike(search_term))
        )
    
    if published_only:
        query = query.filter(NoteDocument.is_published == True)
    
    if notebook_id:
        if notebook_id == 'null':
            # 미분류 노트 (notebook_id가 None인 것들)
            query = query.filter(NoteDocument.notebook_id.is_(None))
        else:
            query = query.filter(NoteDocument.notebook_id == notebook_id)
    
    if parent_id:
        query = query.filter(NoteDocument.parent_note_id == parent_id)
    else:
        # 최상위 노트만 (parent_id가 None인 것들)
        query = query.filter(NoteDocument.parent_note_id.is_(None))
    
    # 정렬 및 페이징
    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}
    
    # 총 단어 수와 읽기 시간
    totals = db.query(
        func.sum(NoteDocument.word_count),
        func.sum(NoteDocument.reading_time)
    ).first()
    
    total_words = totals[0] or 0
    total_reading_time = totals[1] or 0
    
    # 최근 노트 (5개)
    recent_notes_query = db.query(NoteDocument).order_by(
        desc(NoteDocument.updated_at)
    ).limit(5)
    
    recent_notes = []
    for note in recent_notes_query.all():
        child_count = db.query(func.count(NoteDocument.id)).filter(
            NoteDocument.parent_note_id == note.id
        ).scalar()
        
        note_item = NoteDocumentListItem.from_orm(note, child_count)
        recent_notes.append(note_item)
    
    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(
    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(
    note_data: NoteDocumentCreate,
    db: Session = Depends(get_sync_db),
    current_user: User = Depends(get_current_user)
):
    """새 노트 생성"""
    # HTML 내용 정리
    cleaned_content = clean_html_content(note_data.content or "")
    
    # 통계 계산
    word_count = calculate_word_count(note_data.content or "")
    reading_time = calculate_reading_time(note_data.content or "")
    
    note = NoteDocument(
        title=note_data.title,
        content=cleaned_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,
        word_count=word_count,
        reading_time=reading_time,
        created_by=current_user.email
    )
    
    db.add(note)
    db.commit()
    db.refresh(note)
    
    return NoteDocumentResponse.from_orm(note)

@router.put("/{note_id}", response_model=NoteDocumentResponse)
def update_note(
    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.username and not current_user.is_admin:
        raise HTTPException(status_code=403, detail="Permission denied")
    
    # 필드 업데이트
    update_data = note_data.dict(exclude_unset=True)
    
    for field, value in update_data.items():
        setattr(note, field, value)
    
    # 내용이 변경된 경우 통계 재계산
    if 'content' in update_data:
        note.content = clean_html_content(note.content or "")
        note.word_count = calculate_word_count(note.content or "")
        note.reading_time = calculate_reading_time(note.content or "")
    
    db.commit()
    db.refresh(note)
    
    return NoteDocumentResponse.from_orm(note)

@router.delete("/{note_id}")
def delete_note(
    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")
    
    # 자식 노트들의 parent_note_id를 NULL로 설정
    db.query(NoteDocument).filter(
        NoteDocument.parent_note_id == note_id
    ).update({"parent_note_id": None})
    
    db.delete(note)
    db.commit()
    
    return {"message": "Note deleted successfully"}

@router.get("/{note_id}/children", response_model=List[NoteDocumentListItem])
async def get_note_children(
    note_id: str,
    db: Session = Depends(get_sync_db),
    current_user: User = Depends(get_current_user)
):
    """노트의 자식 노트들 조회"""
    children = db.query(NoteDocument).filter(
        NoteDocument.parent_note_id == note_id
    ).order_by(asc(NoteDocument.sort_order), desc(NoteDocument.updated_at)).all()
    
    result = []
    for child in children:
        child_count = db.query(func.count(NoteDocument.id)).filter(
            NoteDocument.parent_note_id == child.id
        ).scalar()
        
        child_item = NoteDocumentListItem.from_orm(child)
        child_item.child_count = child_count
        result.append(child_item)
    
    return result

@router.get("/{note_id}/export/html")
async def export_note_html(
    note_id: str,
    db: Session = Depends(get_sync_db),
    current_user: User = Depends(get_current_user)
):
    """노트를 HTML 파일로 내보내기"""
    from fastapi.responses import Response
    
    note = db.query(NoteDocument).filter(NoteDocument.id == note_id).first()
    if not note:
        raise HTTPException(status_code=404, detail="Note not found")
    
    # HTML 템플릿 생성
    html_template = f"""<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{note.title}</title>
    <style>
        body {{ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; 
               line-height: 1.6; max-width: 800px; margin: 0 auto; padding: 20px; }}
        h1, h2, h3 {{ color: #333; }}
        code {{ background: #f4f4f4; padding: 2px 4px; border-radius: 3px; }}
        pre {{ background: #f4f4f4; padding: 10px; border-radius: 5px; overflow-x: auto; }}
        blockquote {{ border-left: 4px solid #ddd; margin: 0; padding-left: 20px; color: #666; }}
        table {{ border-collapse: collapse; width: 100%; }}
        th, td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
        th {{ background-color: #f2f2f2; }}
        .meta {{ color: #666; font-size: 0.9em; margin-bottom: 20px; }}
    </style>
</head>
<body>
    <div class="meta">
        <strong>제목:</strong> {note.title}<br>
        <strong>타입:</strong> {note.note_type}<br>
        <strong>작성자:</strong> {note.created_by}<br>
        <strong>작성일:</strong> {note.created_at.strftime('%Y-%m-%d %H:%M')}<br>
        <strong>태그:</strong> {', '.join(note.tags) if note.tags else '없음'}
    </div>
    <hr>
    {note.content or ''}
</body>
</html>"""
    
    filename = f"{note.title.replace(' ', '_')}.html"
    
    return Response(
        content=html_template,
        media_type="text/html",
        headers={"Content-Disposition": f"attachment; filename={filename}"}
    )

@router.get("/{note_id}/export/markdown")
async def export_note_markdown(
    note_id: str,
    db: Session = Depends(get_sync_db),
    current_user: User = Depends(get_current_user)
):
    """노트를 마크다운 파일로 내보내기"""
    from fastapi.responses import Response
    
    note = db.query(NoteDocument).filter(NoteDocument.id == note_id).first()
    if not note:
        raise HTTPException(status_code=404, detail="Note not found")
    
    # 메타데이터 포함한 마크다운
    markdown_content = f"""---
title: {note.title}
type: {note.note_type}
author: {note.created_by}
created: {note.created_at.strftime('%Y-%m-%d %H:%M')}
tags: [{', '.join(note.tags) if note.tags else ''}]
---

# {note.title}

{note.content or ''}
"""
    
    filename = f"{note.title.replace(' ', '_')}.md"
    
    return Response(
        content=markdown_content,
        media_type="text/plain",
        headers={"Content-Disposition": f"attachment; filename={filename}"}
    )