"""
Modello Mailbox – casella PEC con credenziali IMAP/SMTP cifrate.
"""

import uuid
from datetime import datetime

from sqlalchemy import (
    BigInteger,
    Boolean,
    DateTime,
    Enum,
    ForeignKey,
    Index,
    Integer,
    String,
    Text,
    UniqueConstraint,
    func,
)
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.database import Base

MailboxStatus = Enum(
    "active", "paused", "error", "deleted",
    name="mailbox_status",
    create_type=False,
)


class Mailbox(Base):
    __tablename__ = "mailboxes"

    id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True), primary_key=True, default=uuid.uuid4
    )
    tenant_id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True), ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False
    )
    email_address: Mapped[str] = mapped_column(String(255), nullable=False)
    display_name: Mapped[str | None] = mapped_column(String(255), nullable=True)
    provider: Mapped[str | None] = mapped_column(String(100), nullable=True)

    # Credenziali IMAP cifrate (AES-256-GCM)
    imap_host_enc: Mapped[str] = mapped_column(Text, nullable=False)
    imap_port_enc: Mapped[str] = mapped_column(Text, nullable=False)
    imap_user_enc: Mapped[str] = mapped_column(Text, nullable=False)
    imap_pass_enc: Mapped[str] = mapped_column(Text, nullable=False)
    imap_use_ssl: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)

    # Credenziali SMTP cifrate (AES-256-GCM)
    smtp_host_enc: Mapped[str] = mapped_column(Text, nullable=False)
    smtp_port_enc: Mapped[str] = mapped_column(Text, nullable=False)
    smtp_user_enc: Mapped[str] = mapped_column(Text, nullable=False)
    smtp_pass_enc: Mapped[str] = mapped_column(Text, nullable=False)
    smtp_use_tls: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)

    # Stato sincronizzazione
    status: Mapped[str] = mapped_column(MailboxStatus, nullable=False, default="active")
    last_sync_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
    last_sync_uid: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
    sync_error_msg: Mapped[str | None] = mapped_column(Text, nullable=True)
    sync_error_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)

    created_by: Mapped[uuid.UUID | None] = mapped_column(
        UUID(as_uuid=True), ForeignKey("users.id"), nullable=True
    )
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, server_default=func.now()
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()
    )

    # Relazioni
    tenant: Mapped["Tenant"] = relationship("Tenant", back_populates="mailboxes")  # noqa: F821
    permissions: Mapped[list["MailboxPermission"]] = relationship(  # noqa: F821
        "MailboxPermission", back_populates="mailbox", cascade="all, delete-orphan"
    )

    __table_args__ = (
        UniqueConstraint("tenant_id", "email_address", name="uq_mailbox_email_tenant"),
        Index("idx_mailboxes_tenant", "tenant_id"),
        Index(
            "idx_mailboxes_status",
            "status",
            postgresql_where="status = 'active'",
        ),
    )

    def __repr__(self) -> str:
        return f"<Mailbox {self.email_address!r} status={self.status!r}>"
