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

from __future__ import annotations

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

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


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] = []


class MemoCreate(MemoBase):
  create_time: Optional[datetime] = None
  anonymous_id: Optional[str] = None
  anonymous_name: Optional[str] = None


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


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 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

  model_config = ConfigDict(populate_by_name=True)


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


