"""Pydantic schemas for the Mail plugin."""

from __future__ import annotations

from datetime import datetime

from pydantic import BaseModel, ConfigDict, Field

# ─── Mail Accounts ───


class MailAccountCreate(BaseModel):
    model_config = ConfigDict(populate_by_name=True)
    email_address: str = Field(..., min_length=1, max_length=255, alias="email")
    display_name: str = Field(default="", max_length=255)
    imap_host: str = Field(..., min_length=1, max_length=255)
    imap_port: int = Field(default=993, ge=1, le=65535)
    imap_ssl: bool = True
    smtp_host: str = Field(..., min_length=1, max_length=255)
    smtp_port: int = Field(default=587, ge=1, le=65535)
    smtp_tls: bool = True
    username: str = Field(default="", min_length=0, max_length=255)
    password: str = Field(..., min_length=1, max_length=512)
    is_shared: bool = False
    sent_folder_imap_name: str | None = Field(None, max_length=255)
    drafts_folder_imap_name: str | None = Field(None, max_length=255)
    spam_folder_imap_name: str | None = Field(None, max_length=255)
    trash_folder_imap_name: str | None = Field(None, max_length=255)


class MailAccountUpdate(BaseModel):
    model_config = ConfigDict(populate_by_name=True)
    email_address: str | None = Field(None, min_length=1, max_length=255, alias="email")
    display_name: str | None = Field(None, max_length=255)
    imap_host: str | None = Field(None, min_length=1, max_length=255)
    imap_port: int | None = Field(None, ge=1, le=65535)
    imap_ssl: bool | None = None
    smtp_host: str | None = Field(None, min_length=1, max_length=255)
    smtp_port: int | None = Field(None, ge=1, le=65535)
    smtp_tls: bool | None = None
    username: str | None = Field(None, min_length=1, max_length=255)
    password: str | None = Field(None, min_length=1, max_length=512)
    is_shared: bool | None = None
    is_active: bool | None = None
    sent_folder_imap_name: str | None = Field(None, max_length=255)
    drafts_folder_imap_name: str | None = Field(None, max_length=255)
    spam_folder_imap_name: str | None = Field(None, max_length=255)
    trash_folder_imap_name: str | None = Field(None, max_length=255)


class MailAccountResponse(BaseModel):
    id: str
    email: str
    email_address: str
    display_name: str
    imap_host: str
    imap_port: int
    imap_ssl: bool
    smtp_host: str
    smtp_port: int
    smtp_tls: bool
    username: str
    is_shared: bool
    is_active: bool
    sent_folder_imap_name: str | None = None
    drafts_folder_imap_name: str | None = None
    spam_folder_imap_name: str | None = None
    trash_folder_imap_name: str | None = None
    created_at: datetime | None = None
    updated_at: datetime | None = None


class SharedMailboxUserAssign(BaseModel):
    user_ids: list[str] = Field(default_factory=list)


class DelegateCreate(BaseModel):
    delegate_user_id: str
    access_level: str = Field("read", pattern="^(read|full)$")


class SendPermissionCreate(BaseModel):
    user_id: str


# ─── Mail Folders ───


class MailFolderCreate(BaseModel):
    account_id: str
    name: str = Field(..., min_length=1, max_length=255)
    imap_name: str = Field(..., min_length=1, max_length=255)
    parent_id: str | None = None


class MailFolderUpdate(BaseModel):
    name: str | None = Field(None, min_length=1, max_length=255)


class MailFolderResponse(BaseModel):
    id: str
    account_id: str
    name: str
    imap_name: str
    parent_id: str | None = None
    is_standard: bool
    unread_count: int
    total_count: int


# ─── Mails ───


class MailSendRequest(BaseModel):
    account_id: str
    to: list[str] = Field(..., min_length=1)
    cc: list[str] = Field(default_factory=list)
    bcc: list[str] = Field(default_factory=list)
    subject: str = Field(default="", max_length=512)
    body_html: str = ""
    body_text: str = ""
    in_reply_to: str | None = None
    references_header: str | None = None
    signature_id: str | None = None
    template_id: str | None = None
    template_vars: dict[str, str] = Field(default_factory=dict)
    attachments: list[str] = Field(default_factory=list)


class MailReplyRequest(BaseModel):
    body_html: str = ""
    body_text: str = ""
    reply_to_all: bool = False
    signature_id: str | None = None


class MailForwardRequest(BaseModel):
    to: list[str] = Field(..., min_length=1)
    cc: list[str] = Field(default_factory=list)
    body_html: str = ""
    body_text: str = ""
    signature_id: str | None = None


class MailFlagsUpdate(BaseModel):
    is_seen: bool | None = None
    is_flagged: bool | None = None
    flag_type: str | None = None
    is_draft: bool | None = None
    is_answered: bool | None = None
    is_forwarded: bool | None = None


class MailResponse(BaseModel):
    id: str
    account_id: str
    folder_id: str
    message_id: str
    thread_id: str
    in_reply_to: str | None = None
    subject: str
    from_address: str
    to_addresses: str
    cc_addresses: str
    bcc_addresses: str
    body_text: str
    body_html_sanitized: str
    is_seen: bool
    is_flagged: bool
    flag_type: str | None = None
    is_draft: bool
    is_answered: bool
    is_forwarded: bool
    has_attachments: bool
    size_bytes: int
    received_at: datetime | None = None
    sent_at: datetime | None = None
    contact_id: str | None = None
    attachments: list[dict] = Field(default_factory=list)
    labels: list[dict] = Field(default_factory=list)


class MailListResponse(BaseModel):
    mails: list[MailResponse]
    total: int
    page: int
    page_size: int


class MailLinkRequest(BaseModel):
    contact_id: str | None = None


class MailMoveRequest(BaseModel):
    target_folder_id: str


class MailDraftCreate(BaseModel):
    account_id: str
    to: list[str] = Field(default_factory=list)
    cc: list[str] = Field(default_factory=list)
    bcc: list[str] = Field(default_factory=list)
    subject: str = ""
    body_text: str = ""
    body_html: str = ""


class MailCreateEventRequest(BaseModel):
    calendar_id: str
    title: str | None = None
    start: str | None = None
    end: str | None = None
    description: str | None = None


class ThreadResponse(BaseModel):
    thread_id: str
    subject: str
    mail_count: int
    mails: list[MailResponse] = Field(default_factory=list)


# ─── Templates ───


class MailTemplateCreate(BaseModel):
    name: str = Field(..., min_length=1, max_length=255)
    subject: str = Field(default="", max_length=512)
    body_html: str = ""


class MailTemplateResponse(BaseModel):
    id: str
    name: str
    subject: str
    body_html: str


class TemplateSubstituteRequest(BaseModel):
    template_id: str
    variables: dict[str, str] = Field(default_factory=dict)


# ─── Signatures ───


class MailSignatureCreate(BaseModel):
    name: str = Field(..., min_length=1, max_length=255)
    body_html: str = ""
    account_id: str | None = None
    is_default: bool = False


class MailSignatureResponse(BaseModel):
    id: str
    name: str
    body_html: str
    account_id: str | None = None
    is_default: bool


# ─── Rules ───


class MailRuleCreate(BaseModel):
    name: str = Field(..., min_length=1, max_length=255)
    account_id: str | None = None
    priority: int = 0
    is_active: bool = True
    conditions: dict = Field(default_factory=dict)
    actions: dict = Field(default_factory=dict)


class MailRuleResponse(BaseModel):
    id: str
    name: str
    account_id: str | None = None
    priority: int
    is_active: bool
    conditions: dict
    actions: dict


# ─── Vacation ───


class VacationConfig(BaseModel):
    account_id: str
    is_enabled: bool = True
    subject: str = Field(default="Out of Office", max_length=512)
    body_text: str = ""
    body_html: str = ""
    start_date: str | None = None
    end_date: str | None = None


class VacationResponse(BaseModel):
    is_enabled: bool
    subject: str
    body_text: str
    body_html: str


# ─── PGP ───


class PgpKeyImport(BaseModel):
    private_key_armored: str = Field(..., min_length=1)
    passphrase: str = Field(default="", max_length=255)


class PgpKeyResponse(BaseModel):
    id: str
    key_id: str
    public_key_armored: str


class ContactPgpKeyCreate(BaseModel):
    public_key_armored: str = Field(..., min_length=1)


class ContactPgpKeyResponse(BaseModel):
    id: str
    contact_id: str
    public_key_armored: str
    key_id: str


class PgpEncryptRequest(BaseModel):
    recipient_email: str
    plaintext: str


class PgpDecryptRequest(BaseModel):
    ciphertext: str
    passphrase: str = ""


# ─── Labels ───


class MailLabelCreate(BaseModel):
    name: str = Field(..., min_length=1, max_length=100)
    color: str = Field(default="#808080", max_length=20)


class MailLabelResponse(BaseModel):
    id: str
    name: str
    color: str


class MailLabelAssign(BaseModel):
    label_id: str


# ─── Search ───


class MailSearchResponse(BaseModel):
    results: list[MailResponse]
    total: int


# ─── Connection Test ───


class ConnectionTestRequest(BaseModel):
    imap_host: str
    imap_port: int = 993
    smtp_host: str
    smtp_port: int = 587
    username: str
    password: str


class ConnectionTestResponse(BaseModel):
    imap_ok: bool
    smtp_ok: bool
    message: str
