from datetime import datetime
from typing import Any, Dict

from sqlalchemy import Column, ForeignKey, Integer, String, Boolean
from sqlalchemy.orm import relationship, mapped_column, Mapped

from db.models.base import Base, BaseMixin


class Profile(Base, BaseMixin):
    __tablename__ = 'profile'
    first_name = Column(String)
    last_name = Column(String)
    user_name = Column(String, nullable=False)
    email = Column(String)
    password = Column(String)
    enabled = Column(Boolean)
    assignments = relationship("Assignment")
    tokens = relationship("Token")

    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 import_dict(self, import_data: Dict[str, Any]):
        self.id = import_data['id']
        self.created_date = import_data['created_date']
        self.last_modified_date = import_data['last_modified_date']
        self.version = import_data['version']
        self.first_name = import_data['first_name']
        self.last_name = import_data['last_name']
        self.user_name = import_data['user_name']
        self.email = import_data['email']
        self.password = import_data['password']
        self.enabled = import_data['enabled']

    def export_dict(self) -> Dict[str, Any]:
        item: Dict[str, Any] = {}
        item['id'] = self.id
        item['created_date'] = str(self.created_date)
        item['last_modified_date'] = str(self.last_modified_date)
        item['version'] = self.version
        item['first_name'] = self.first_name
        item['last_name'] = self.last_name
        item['user_name'] = self.user_name
        item['email'] = self.email
        item['password'] = self.password
        item['enabled'] = self.enabled
        return item


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

    def import_dict(self, import_data: Dict[str, Any]):
        self.id = import_data['id']
        self.created_date = import_data['created_date']
        self.last_modified_date = import_data['last_modified_date']
        self.version = import_data['version']
        self.token = import_data['token']
        self.name = import_data['name']
        self.last_used_date = import_data['last_used_date']
        self.enabled = import_data['enabled']
        self.profile_id = import_data['profile_id']

    def export_dict(self) -> Dict[str, Any]:
        item: Dict[str, Any] = {}
        item['id'] = self.id
        item['created_date'] = str(self.created_date)
        item['last_modified_date'] = str(self.last_modified_date)
        item['version'] = self.version
        item['token'] = self.token
        item['name'] = self.name
        item['last_used_date'] = self.last_used_date
        item['enabled'] = self.enabled
        item['profile_id'] = self.profile_id
        return item


class Permission(Base, BaseMixin):
    __tablename__ = "permission"
    name = Column(String, nullable=False)
    assignments = relationship("Assignment")

    def import_dict(self, import_data: Dict[str, Any]):
        self.id = import_data['id']
        self.created_date = import_data['created_date']
        self.last_modified_date = import_data['last_modified_date']
        self.version = import_data['version']
        self.name = import_data['name']

    def export_dict(self) -> Dict[str, Any]:
        item: Dict[str, Any] = {}
        item['id'] = self.id
        item['created_date'] = str(self.created_date)
        item['last_modified_date'] = str(self.last_modified_date)
        item['version'] = self.version
        item['name'] = self.name
        return item

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

    def import_dict(self, import_data: Dict[str, Any]):
        self.id = import_data['id']
        self.created_date = import_data['created_date']
        self.last_modified_date = import_data['last_modified_date']
        self.version = import_data['version']
        self.profile_id = import_data['profile_id']
        self.permission_id = import_data['permission_id']

    def export_dict(self) -> Dict[str, Any]:
        item: Dict[str, Any] = {}
        item['id'] = self.id
        item['created_date'] = str(self.created_date)
        item['last_modified_date'] = str(self.last_modified_date)
        item['version'] = self.version
        item['profile_id'] = self.profile_id
        item['permission_id'] = self.permission_id
        return item


class MailAccount(Base, BaseMixin):
    __tablename__ = "mail_account"
    host = Column(String)
    port = Column(Integer)
    protocol = Column(String)
    user_name = Column(String)
    password = Column(String)
    start_tls = Column(Boolean)

    def import_dict(self, import_data: Dict[str, Any]):
        self.id = import_data['id']
        self.created_date = import_data['created_date']
        self.last_modified_date = import_data['last_modified_date']
        self.version = import_data['version']
        self.host = import_data['host']
        self.port = import_data['port']
        self.protocol = import_data['protocol']
        self.user_name = import_data['user_name']
        self.password = import_data['password']
        self.start_tls = import_data['start_tls']

    def export_dict(self) -> Dict[str, Any]:
        item: Dict[str, Any] = {}
        item['id'] = self.id
        item['created_date'] = str(self.created_date)
        item['last_modified_date'] = str(self.last_modified_date)
        item['version'] = self.version
        item['host'] = self.host
        item['port'] = self.port
        item['protocol'] = self.protocol
        item['user_name'] = self.user_name
        item['password'] = self.password
        item['start_tls'] = self.start_tls
        return item


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

    def import_dict(self, import_data: Dict[str, Any]):
        self.id = import_data['id']
        self.created_date = import_data['created_date']
        self.last_modified_date = import_data['last_modified_date']
        self.version = import_data['version']
        self.folder = import_data['folder']
        self.subject = import_data['subject']
        self.body = import_data['body']
        self.sent_date = import_data['sent_date']
        self.received_date = import_data['received_date']

    def export_dict(self) -> Dict[str, Any]:
        item: Dict[str, Any] = {}
        item['id'] = self.id
        item['created_date'] = str(self.created_date)
        item['last_modified_date'] = str(self.last_modified_date)
        item['version'] = self.version
        item['folder'] = self.folder
        item['subject'] = self.subject
        item['body'] = self.body
        item['sent_date'] = str(self.sent_date)
        item['received_date'] = str(self.received_date)
        return item
