"""Pydantic schemas for CuCu Note (moved to common.memos_core.schemas)."""

from __future__ import annotations

from datetime import datetime
from enum import Enum
from typing import Any, List, Optional

from pydantic import BaseModel, ConfigDict, EmailStr, Field
from pydantic.aliases import AliasChoices


class DeadlineStatus(str, Enum):
    """Trạng thái deadline của memo."""
    PENDING = "PENDING"      # Chưa làm, chưa quá hạn
    DONE = "DONE"            # Đã hoàn thành
    OVERDUE = "OVERDUE"      # Quá hạn mà chưa làm


class MemoRelationPriority(str, Enum):
    """Mức độ ưu tiên."""
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    URGENT = "urgent"


class InstanceInfo(BaseModel):
  mode: Optional[str] = None
  version: Optional[str] = None


class InstanceUpdate(BaseModel):
  data_dir: Optional[str] = None


class InstanceSetting(BaseModel):
  # Stub fields for Connect compatibility
  allow_signup: bool = True
  disallow_login: bool = False
  additional_setting: dict | None = None


class AuthSignInRequest(BaseModel):
  """Accept both REST-style and Connect/proto-like payloads."""

  # REST-style
  email: Optional[EmailStr] = None
  password: Optional[str] = None

  # Connect/proto-like
  credentials: Optional[dict[str, Any]] = None


class AuthSignInResponse(BaseModel):
  accessToken: str = Field(validation_alias=AliasChoices("accessToken", "access_token"))
  tokenType: str = Field(default="bearer", validation_alias=AliasChoices("tokenType", "token_type"))

  model_config = ConfigDict(populate_by_name=True)


class AuthSignUpRequest(BaseModel):
  email: EmailStr
  password: str


class AuthSignUpResponse(BaseModel):
  user_id: str


class AuthMeResponse(BaseModel):
  id: str
  email: EmailStr
  username: Optional[str] = None
  first_name: Optional[str] = Field(default=None, alias="firstName")
  last_name: Optional[str] = Field(default=None, alias="lastName")
  avatar_url: Optional[str] = Field(default=None, alias="avatarUrl")
  
  model_config = ConfigDict(populate_by_name=True)


class UserBase(BaseModel):
  email: Optional[EmailStr] = None


class UserCreate(UserBase):
  password: str = ""


class UserUpdate(BaseModel):
  email: Optional[EmailStr] = None
  nickname: Optional[str] = None


class UserResponse(UserBase):
  id: str
  nickname: Optional[str] = None
  username: Optional[str] = None
  display_name: Optional[str] = Field(default=None, alias="displayName")
  avatar_url: Optional[str] = Field(default=None, alias="avatarUrl")
  name: Optional[str] = None  # Resource name: users/{id}
  role: int = 1  # 1 = HOST
  state: int = 1  # 1 = ACTIVE
  
  model_config = ConfigDict(populate_by_name=True)


class UserStatsResponse(BaseModel):
  """User statistics including tag counts and memo timestamps."""
  tag_count: dict[str, int] = Field(default_factory=dict, alias="tagCount")
  memo_display_timestamps: List[str] = Field(default_factory=list, alias="memoDisplayTimestamps")

  model_config = ConfigDict(populate_by_name=True)


class MemoBase(BaseModel):
  content: str
  visibility: Optional[str] = "PRIVATE"
  tags: List[str] = []
  is_read: Optional[bool] = None


class MemoCreate(MemoBase):
  create_time: Optional[datetime] = None
  anonymous_id: Optional[str] = None
  anonymous_name: Optional[str] = None
  # --- Deadline fields ---
  deadline: Optional[datetime] = None           # Thời hạn chót (UTC)
  priority: Optional[str] = None                # low | medium | high | urgent
  reminder_at: Optional[datetime] = None        # Nhắc nhở trước deadline
  # --- Workspace isolation ---
  workspace_id: Optional[str] = None            # PERSONAL | AI_SALES_CRM


class MemoUpdate(BaseModel):
  content: Optional[str] = None
  visibility: Optional[str] = None
  tags: Optional[List[str]] = None
  pinned: Optional[bool] = None
  row_status: Optional[str] = None
  # --- Deadline fields ---
  deadline: Optional[datetime] = None
  priority: Optional[str] = None
  reminder_at: Optional[datetime] = None
  is_completed: Optional[bool] = None
  completed_at: Optional[datetime] = None
  # --- Inbox fields ---
  is_read: Optional[bool] = None


class MemoVersion(BaseModel):
  """Represents a historical version of a memo's content."""
  version: int = 1
  content: str
  created_at: datetime
  created_by: Optional[str] = None  # User ID who made the edit

  model_config = ConfigDict(populate_by_name=True)


class MemoVersionResponse(BaseModel):
  """Response schema for memo version history."""
  versions: List[MemoVersion] = []
  total: int = 0


class ReactionResponse(BaseModel):
  name: str
  creator: str
  contentId: str
  reactionType: str
  
  model_config = ConfigDict(populate_by_name=True)

class MemoResponse(MemoBase):
  id: str
  uid: str = ""
  creator_id: str
  creator: str = ""  # Resource name: users/{creator_id}
  name: str = ""  # Resource name: memos/{uid}
  pinned: bool = False
  row_status: str = "NORMAL"
  create_time: Optional[str] = None
  update_time: Optional[str] = None
  display_time: Optional[str] = None
  parent: Optional[str] = None
  comment_count: int = 0
  versions: List[MemoVersion] = []  # Version history
  reactions: List[ReactionResponse] = [] # Reactions
  # --- Deadline fields ---
  deadline: Optional[str] = None          # ISO string
  deadline_status: Optional[str] = None  # PENDING | DONE | OVERDUE
  priority: Optional[str] = None          # low | medium | high | urgent
  reminder_at: Optional[str] = None
  is_completed: bool = False
  completed_at: Optional[str] = None
  # --- Workspace isolation ---
  workspace_id: Optional[str] = None      # PERSONAL | AI_SALES_CRM

  model_config = ConfigDict(populate_by_name=True)


class DeadlineListResponse(BaseModel):
  """Response for deadline listing API."""
  overdue: List[MemoResponse] = []      # Quá hạn, chưa hoàn thành
  today: List[MemoResponse] = []        # Deadline hôm nay
  upcoming: List[MemoResponse] = []     # Sắp tới (7 ngày)
  no_date: List[MemoResponse] = []      # Có priority nhưng không có deadline
  total: int = 0


class MemoEmbeddingCreate(BaseModel):
  memoId: int
  content: str
  tags: List[str] = []
  dateKey: Optional[str] = None
  embedding: List[float]
  model: Optional[str] = "stub-embedding"


class MemoEmbeddingResponse(BaseModel):
  id: int
  memoId: int
  content: str
  tags: List[str]
  dateKey: Optional[str] = None
  dim: int
  model: str
  score: Optional[float] = None


class AttachmentResponse(BaseModel):
  id: str
  uid: str = ""
  filename: str
  url: str
  type: str = ""
  size: int = 0


class ShortcutCreate(BaseModel):
  name: str
  filter: str


class ShortcutUpdate(BaseModel):
  name: Optional[str] = None
  filter: Optional[str] = None


class ShortcutResponse(BaseModel):
  id: str
  name: str
  filter: str


class ListShortcutsResponse(BaseModel):
  shortcuts: List[ShortcutResponse] = []


class ActivityMemoCommentPayload(BaseModel):
  """Payload for memo comment activities"""
  memo: str  # Comment memo name (memos/{uid})
  related_memo: str  # Parent memo name that was commented on


class ActivityPayload(BaseModel):
  """Activity payload with different types"""
  memo_comment: Optional[ActivityMemoCommentPayload] = None


class ActivityResponse(BaseModel):
  """Activity record - e.g., when a comment is created"""
  name: str  # activities/{id}
  creator: str  # users/{id}
  type: str  # MEMO_COMMENT, etc.
  level: str = "INFO"  # INFO, WARNING, ERROR
  create_time: Optional[str] = None
  payload: Optional[ActivityPayload] = None


class NotificationStatus:
  """Notification status constants"""
  UNREAD = "UNREAD"
  READ = "READ"
  ARCHIVED = "ARCHIVED"


class NotificationType:
  """Notification type constants"""
  MEMO_COMMENT = "MEMO_COMMENT"


class NotificationResponse(BaseModel):
  """User notification - shows in Inbox"""
  name: str  # notifications/{id}
  sender: str  # users/{creator_id} or anonymous_{id}
  activity_id: int  # Reference to activity
  type: str  # MEMO_COMMENT
  status: str = "UNREAD"  # UNREAD, READ, ARCHIVED
  create_time: Optional[str] = None



class IdentityProviderCreate(BaseModel):
  name: str
  type: str


class IdentityProviderUpdate(BaseModel):
  name: Optional[str] = None
  config: Optional[dict] = None


class IdentityProviderResponse(BaseModel):
  id: int
  name: str
  type: str


# ====================== PERSONAL ACCESS TOKENS ======================
class PersonalAccessTokenCreate(BaseModel):
  description: str
  expires_at: Optional[datetime] = None


class PersonalAccessTokenResponse(BaseModel):
  id: str
  description: str
  created_at: str
  last_used_at: Optional[str] = None
  expires_at: Optional[str] = None
  is_active: bool = True
  token: Optional[str] = None  # Only included on creation


# ====================== WEBHOOKS ======================
class WebhookCreate(BaseModel):
  name: str
  url: str
  events: List[str]
  secret: Optional[str] = None


class WebhookUpdate(BaseModel):
  name: Optional[str] = None
  url: Optional[str] = None
  events: Optional[List[str]] = None
  secret: Optional[str] = None
  is_active: Optional[bool] = None


class WebhookResponse(BaseModel):
  id: str
  user_id: str
  name: str
  url: str
  events: List[str]
  is_active: bool = True
  created_at: str
  updated_at: Optional[str] = None


# ====================== DOCUMENTS (DOCX/PDF) ======================
class DocumentBase(BaseModel):
  """Base schema for document."""
  filename: str = Field(..., min_length=1, max_length=255)
  workspace_id: str = Field(default="PERSONAL", pattern=r"^[A-Z0-9_]+$")
  title: Optional[str] = Field(None, max_length=500)


class DocumentCreate(BaseModel):
  """Schema for creating a new document (upload)."""
  filename: str = Field(..., min_length=1, max_length=255)
  original_filename: str = Field(..., min_length=1, max_length=255)
  file_size: int = Field(..., ge=1)
  mime_type: str = Field(..., max_length=100)
  workspace_id: str = Field(default="PERSONAL", pattern=r"^[A-Z0-9_]+$")
  content: Optional[str] = Field(None, description="Extracted markdown content")
  pages: Optional[int] = Field(None, ge=1)


class DocumentUpdate(BaseModel):
  """Schema for updating document metadata."""
  title: Optional[str] = Field(None, max_length=500)
  tags: Optional[List[str]] = Field(None, max_length=50)
  summary: Optional[str] = Field(None, max_length=2000)
  ai_enhanced: Optional[bool] = None
  workspace_id: Optional[str] = Field(None, pattern=r"^[A-Z0-9_]+$")


class DocumentResponse(BaseModel):
  """Schema for document response."""
  model_config = ConfigDict(from_attributes=True)

  id: int
  uid: str
  creator_id: str
  filename: str
  original_filename: str
  file_path: str
  file_size: int
  mime_type: str
  workspace_id: str
  status: str  # PENDING | PROCESSING | COMPLETED | FAILED
  pages: Optional[int] = None
  title: Optional[str] = None
  content: Optional[str] = None
  summary: Optional[str] = None
  tags: Optional[List[str]] = None
  ai_enhanced: bool = False
  error_message: Optional[str] = None
  created_at: datetime
  updated_at: datetime
  processed_at: Optional[datetime] = None


class DocumentListResponse(BaseModel):
  """Schema for list of documents."""
  documents: List[DocumentResponse] = []
  total: int = 0
  workspace_filter: Optional[str] = None


class DocumentProcessRequest(BaseModel):
  """Schema for requesting document processing/AI enhancement."""
  enhance_with_ai: bool = Field(default=True, description="Enable AI tagging/summary")
  generate_summary: bool = Field(default=True, description="Generate AI summary")
  extract_tags: bool = Field(default=True, description="Extract tags from content")


class DocumentImportRequest(BaseModel):
  """Schema for importing document content into memos."""
  memo_title: Optional[str] = Field(None, max_length=500, description="Title for imported memo")
  tags: List[str] = Field(default_factory=list, max_length=50, description="Tags to add to memo")
  visibility: str = Field(default="PRIVATE", pattern=r"^(PRIVATE|PROTECTED|PUBLIC)$")
  create_as_memo: bool = Field(default=True, description="Create a memo from this document")


class DocumentUploadResponse(BaseModel):
  """Schema for document upload response."""
  success: bool
  document: DocumentResponse
  message: str = "Document uploaded successfully"


class DocumentDeleteResponse(BaseModel):
  """Schema for document deletion response."""
  success: bool
  message: str = "Document deleted successfully"


