from typing import Any, Dict
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship

from db.models.base import Base, BaseMixin


class Article(Base, BaseMixin):
    __tablename__ = 'article'
    title = Column(String, unique=True)
    article_authors = relationship("ArticleAuthor")

    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.title = import_data['title']

    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['title'] = self.title
        return item


class Author(Base, BaseMixin):
    __tablename__ = 'author'
    first_name = Column(String)
    last_name = Column(String)
    article_authors = relationship("ArticleAuthor")
    book_authors = relationship("BookAuthor")

    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']

    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
        return item


class BookshelfPublisher(Base, BaseMixin):
    __tablename__ = 'bookshelf_publisher'
    name = Column(String, unique=True)
    books = relationship("Book")

    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 Book(Base, BaseMixin):
    __tablename__ = 'book'
    isbn = Column(String, unique=True)
    title = Column(String)
    year = Column(Integer, nullable=False)
    publisher_id = Column(String, ForeignKey('bookshelf_publisher.id'), nullable=False)
    publisher = relationship('BookshelfPublisher', back_populates="books")
    book_authors = relationship("BookAuthor")

    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.isbn = import_data['isbn']
        self.title = import_data['title']
        self.year = import_data['year']
        self.publisher_id = import_data['publisher_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['isbn'] = self.isbn
        item['title'] = self.title
        item['year'] = self.year
        item['publisher_id'] = self.publisher_id
        return item


class ArticleAuthor(Base, BaseMixin):
    __tablename__ = 'article_author'
    article_id = Column(String, ForeignKey('article.id'), nullable=False)
    article = relationship('Article', back_populates="article_authors")
    author_id = Column(String, ForeignKey('author.id'), nullable=False)
    author = relationship('Author', back_populates="article_authors")

    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.article_id = import_data['article_id']
        self.author_id = import_data['author_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['article_id'] = self.article_id
        item['author_id'] = self.author_id
        return item


class BookAuthor(Base, BaseMixin):
    __tablename__ = 'book_author'
    author_id = Column(String, ForeignKey('author.id'), nullable=False)
    author = relationship('Author', back_populates="book_authors")
    book_id = Column(String, ForeignKey('book.id'), nullable=False)
    book = relationship('Book', back_populates="book_authors")

    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.author_id = import_data['author_id']
        self.book_id = import_data['book_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['author_id'] = self.author_id
        item['book_id'] = self.book_id
        return item
