from dataclasses import dataclass, field
from datetime import UTC, datetime

from dataclasses_ujson.dataclasses_ujson import UJsonMixin  # type: ignore
from sqlalchemy import BigInteger, Boolean, Column, DateTime, String

from server.config import get_app_config
from server.infra.db.db_mapper import mapper_registry
from server.modules.attachments.domains.attachments import Attachment as AttachmentModel


@mapper_registry.mapped
@dataclass
class Attachment(UJsonMixin):
    __sa_dataclass_metadata_key__ = "sa"
    __tablename__ = "attachments"

    id: str = field(metadata={"sa": Column(String(), primary_key=True, nullable=False)})
    size: int = field(metadata={"sa": Column(BigInteger(), nullable=False)})
    storage_driver_name: str = field(metadata={"sa": Column(String(), nullable=False)})
    path: str = field(metadata={"sa": Column(String(), nullable=False)})
    media_type: str = field(metadata={"sa": Column(String(), nullable=False)})
    content_type: str = field(metadata={"sa": Column(String(), nullable=False)})

    created_at: datetime = field(
        default=datetime.now(UTC),
        metadata={"sa": Column(DateTime(timezone=True), nullable=False)},
    )
    updated_at: datetime = field(
        default=datetime.now(UTC),
        metadata={"sa": Column(DateTime(timezone=True), nullable=False)},
    )
    is_deleted: bool = field(default=False, metadata={"sa": Column(Boolean(), nullable=False, default=False)})

    def __str__(self):
        return f"{get_app_config().app_public_url}/api/v0/attachment/{self.id}.original.ext"

    def to_domain(self) -> AttachmentModel:
        return AttachmentModel(
            id=self.id,
            size=self.size,
            media_type=self.media_type,
            content_type=self.content_type,
            created_at=self.created_at,
            updated_at=self.updated_at,
            storage_driver_name=self.storage_driver_name,
            path=self.path,
        )
