from sqlalchemy import Column, String, Text, Integer, Boolean, DateTime, ForeignKey, ARRAY
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from pydantic import BaseModel, Field
from typing import List, Optional
from datetime import datetime
import uuid

from ..core.database import Base

class NoteDocument(Base):
    """노트 문서 모델"""
    __tablename__ = "notes_documents"
    
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    title = Column(String(500), nullable=False)
    content = Column(Text)  # HTML 내용 (기본)
    markdown_content = Column(Text)  # 마크다운 내용 (선택사항)
    note_type = Column(String(50), default='note')  # note, research, summary, idea 등
    tags = Column(ARRAY(String), default=[])
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
    created_by = Column(String(100), nullable=False)
    is_published = Column(Boolean, default=False)
    parent_note_id = Column(UUID(as_uuid=True), ForeignKey('notes_documents.id'), nullable=True)
    notebook_id = Column(UUID(as_uuid=True), ForeignKey('notebooks.id'), nullable=True)
    sort_order = Column(Integer, default=0)
    
    # 관계 설정
    notebook = relationship("Notebook", back_populates="notes")
    highlights = relationship("NoteHighlight", back_populates="note", cascade="all, delete-orphan")
    notes = relationship("NoteNote", back_populates="note", cascade="all, delete-orphan")
    word_count = Column(Integer, default=0)
    reading_time = Column(Integer, default=0)  # 예상 읽기 시간 (분)
    
    # 관계
    parent_note = relationship("NoteDocument", remote_side=[id], back_populates="child_notes")
    child_notes = relationship("NoteDocument", back_populates="parent_note")

# Pydantic 모델들
class NoteDocumentBase(BaseModel):
    title: str = Field(..., min_length=1, max_length=500)
    content: Optional[str] = None
    note_type: str = Field(default='note', pattern='^(note|research|summary|idea|guide|reference)$')
    tags: List[str] = Field(default=[])
    is_published: bool = Field(default=False)
    parent_note_id: Optional[str] = None
    notebook_id: Optional[str] = None
    sort_order: int = Field(default=0)

class NoteDocumentCreate(NoteDocumentBase):
    pass

class NoteDocumentUpdate(BaseModel):
    title: Optional[str] = Field(None, min_length=1, max_length=500)
    content: Optional[str] = None
    note_type: Optional[str] = Field(None, pattern='^(note|research|summary|idea|guide|reference)$')
    tags: Optional[List[str]] = None
    is_published: Optional[bool] = None
    parent_note_id: Optional[str] = None
    notebook_id: Optional[str] = None
    sort_order: Optional[int] = None

class NoteDocumentResponse(NoteDocumentBase):
    id: str
    markdown_content: Optional[str] = None
    created_at: datetime
    updated_at: datetime
    created_by: str
    word_count: int
    reading_time: int
    
    # 계층 구조 정보
    parent_note: Optional['NoteDocumentResponse'] = None
    child_notes: List['NoteDocumentResponse'] = []
    
    class Config:
        from_attributes = True
        
    @classmethod
    def from_orm(cls, obj):
        """ORM 객체에서 Pydantic 모델로 변환"""
        data = {
            'id': str(obj.id),  # UUID를 문자열로 변환
            'title': obj.title,
            'content': obj.content,
            'note_type': obj.note_type,
            'tags': obj.tags or [],
            'is_published': obj.is_published,
            'parent_note_id': str(obj.parent_note_id) if obj.parent_note_id else None,
            'notebook_id': str(obj.notebook_id) if obj.notebook_id else None,
            'sort_order': obj.sort_order,
            'markdown_content': obj.markdown_content,
            'created_at': obj.created_at,
            'updated_at': obj.updated_at,
            'created_by': obj.created_by,
            'word_count': obj.word_count or 0,
            'reading_time': obj.reading_time or 0,
        }
        return cls(**data)

# 자기 참조 관계를 위한 모델 업데이트
NoteDocumentResponse.model_rebuild()

class NoteDocumentListItem(BaseModel):
    """노트 목록용 간소화된 모델"""
    id: str
    title: str
    note_type: str
    tags: List[str]
    created_at: datetime
    updated_at: datetime
    created_by: str
    is_published: bool
    word_count: int
    reading_time: int
    parent_note_id: Optional[str] = None
    child_count: int = 0  # 자식 노트 개수
    
    class Config:
        from_attributes = True
        
    @classmethod
    def from_orm(cls, obj, child_count=0):
        """ORM 객체에서 Pydantic 모델로 변환"""
        data = {
            'id': str(obj.id),  # UUID를 문자열로 변환
            'title': obj.title,
            'note_type': obj.note_type,
            'tags': obj.tags or [],
            'created_at': obj.created_at,
            'updated_at': obj.updated_at,
            'created_by': obj.created_by,
            'is_published': obj.is_published,
            'word_count': obj.word_count or 0,
            'reading_time': obj.reading_time or 0,
            'parent_note_id': str(obj.parent_note_id) if obj.parent_note_id else None,
            'child_count': child_count,
        }
        return cls(**data)

class NoteStats(BaseModel):
    """노트 통계 정보"""
    total_notes: int
    published_notes: int
    draft_notes: int
    note_types: dict  # {type: count}
    total_words: int
    total_reading_time: int
    recent_notes: List[NoteDocumentListItem]
