from datetime import datetime
from typing import List

from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship, mapped_column, Mapped

from src.db.models.base import Base, BaseMixin


class Profile(Base, BaseMixin):
    __tablename__ = 'profile'
    first_name: Mapped[str]
    last_name: Mapped[str]
    user_name: Mapped[str] =  mapped_column(nullable=False)
    email: Mapped[str]
    password: Mapped[str]
    enabled: Mapped[bool]
    assignments: Mapped[List["Assignment"]] = relationship(back_populates="profile")
    tokens: Mapped[List["Token"]] = relationship(back_populates="profile")

    def get_full_name(self) -> str:
        full_name: str = ""
        if self.first_name is not None:
            full_name += str(self.first_name)
        if self.last_name is not None:
            if len(full_name) > 0:
                full_name += " "
            full_name += str(self.last_name)
        return full_name

    def __str__(self):
        return f"Profile({self.id} {self.user_name}, {self.email})"


class Token(Base, BaseMixin):
    __tablename__ = "token"
    token: Mapped[str] = mapped_column(nullable=False, unique=True)
    name: Mapped[str]
    last_used_date: Mapped[datetime]
    enabled: Mapped[bool]
    profile_id = mapped_column(ForeignKey("profile.id"), nullable=False)
    profile: Mapped[Profile] = relationship(back_populates="tokens")


class Permission(Base, BaseMixin):
    __tablename__ = "permission"
    name: Mapped[str] = mapped_column(nullable=False)
    assignments: Mapped[List["Assignment"]] = relationship(back_populates="permission")


class Assignment(Base, BaseMixin):
    __tablename__ = "assignment"
    profile_id = mapped_column(ForeignKey("profile.id"), nullable=False)
    profile: Mapped[Profile] = relationship(back_populates="assignments")
    permission_id = mapped_column(ForeignKey("permission.id"), nullable=False)
    permission: Mapped[Permission] = relationship(back_populates="assignments")


class MailAccount(Base, BaseMixin):
    __tablename__ = "mail_account"
    host: Mapped[str]
    port: Mapped[int]
    protocol: Mapped[str]
    user_name: Mapped[str]
    password: Mapped[str]
    start_tls: Mapped[bool]


class Mail(Base, BaseMixin):
    __tablename__ = "mail"
    folder: Mapped[str]
    subject: Mapped[str]
    body: Mapped[str]
    sent_date: Mapped[datetime]
    received_date: Mapped[datetime]
