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

from dataclasses_ujson.dataclasses_ujson import UJsonMixin  # type: ignore
from sqlalchemy import (
    Column,
    DateTime,
    ForeignKeyConstraint,
    Integer,
    String,
)
from sqlalchemy.orm import relationship

from server.infra.db.db_mapper import mapper_registry
from server.modules.attachments.repository.attachments import Attachment
from server.modules.descriptions.repository.models import Beerds


@mapper_registry.mapped
@dataclass
class Results(UJsonMixin):
    __sa_dataclass_metadata_key__ = "sa"
    __tablename__ = "recognizer_results"
    __table_args__ = (ForeignKeyConstraint(["attachment_id"], ["attachments.id"], "votes_attachment_id_fk"),)

    __mapper_args__ = {
        "properties": {
            "attachment": relationship(Attachment, foreign_keys="Results.attachment_id"),
        }
    }

    id: str = field(metadata={"sa": Column(String(), primary_key=True, nullable=False)})
    attachment_id: str = field(metadata={"sa": Column(String(), nullable=False)})
    user_id: str = field(metadata={"sa": Column(String(), nullable=False)})
    device_id: str = field(metadata={"sa": Column(String(), nullable=False)})
    created_at: datetime = field(
        default=datetime.now(UTC),
        metadata={"sa": Column(DateTime(timezone=True), nullable=False)},
    )

    def __str__(self):
        formatted_date = self.created_at.strftime("%Y-%m-%d %H:%M")
        return f"{formatted_date}, device_id: {self.device_id}, user_id: {self.user_id}"


@mapper_registry.mapped
@dataclass
class ResultBeerds(UJsonMixin):
    __sa_dataclass_metadata_key__ = "sa"
    __tablename__ = "recognizer_results_beerds"
    __table_args__ = (
        ForeignKeyConstraint(["recognizer_results_id"], ["recognizer_results.id"], "recognizer_results_id_fk"),
        ForeignKeyConstraint(["beerd_id"], ["beerds.id"], "recognizer_results_beerd_id_fk"),
    )

    __mapper_args__ = {
        "properties": {
            "result": relationship(Results, foreign_keys="ResultBeerds.recognizer_results_id"),
            "beerd": relationship(Beerds, foreign_keys="ResultBeerds.beerd_id"),
        }
    }

    id: str = field(metadata={"sa": Column(String(), primary_key=True, nullable=False)})
    recognizer_results_id: str = field(metadata={"sa": Column(String(), nullable=False)})
    beerd_id: str = field(metadata={"sa": Column(String(), nullable=False)})
    probability: int = field(metadata={"sa": Column(Integer(), nullable=True)})
