from typing import List

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

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


class Article(Base, BaseMixin):
    __tablename__ = 'article'
    title: Mapped[str] = mapped_column(unique=True)
    article_authors = relationship("ArticleAuthor")


class Author(Base, BaseMixin):
    __tablename__ = 'author'
    first_name: Mapped[str]
    last_name: Mapped[str]
    article_authors: Mapped[List["ArticleAuthor"]] = relationship(back_populates="author")
    book_authors: Mapped[List["BookAuthor"]] = relationship(back_populates="author")


class BookshelfPublisher(Base, BaseMixin):
    __tablename__ = 'bookshelf_publisher'
    name: Mapped[str] = mapped_column(unique=True)
    books: Mapped[List["Book"]] = relationship(back_populates="publisher")


class Book(Base, BaseMixin):
    __tablename__ = 'book'
    isbn: Mapped[str] = mapped_column(unique=True)
    title: Mapped[str]
    year: Mapped[int] = mapped_column(nullable=False)
    publisher_id: Mapped[str] = mapped_column(ForeignKey("bookshelf_publisher.id"), nullable=False)
    publisher: Mapped[BookshelfPublisher] = relationship(back_populates="books")
    book_authors: Mapped[List["BookAuthor"]] = relationship(back_populates="book")


class ArticleAuthor(Base, BaseMixin):
    __tablename__ = 'article_author'
    article_id: Mapped[str] = mapped_column(ForeignKey("article.id"), nullable=False)
    article: Mapped[Article] = relationship(back_populates="article_authors")
    author_id: Mapped[str] = mapped_column(ForeignKey("author.id"), nullable=False)
    author: Mapped[Author] = relationship(back_populates="article_authors")


class BookAuthor(Base, BaseMixin):
    __tablename__ = 'book_author'
    author_id: Mapped[str] = mapped_column(ForeignKey("author.id"), nullable=False)
    author: Mapped[Author] = relationship(back_populates="book_authors")
    book_id: Mapped[str] = mapped_column(ForeignKey("book.id"), nullable=False)
    book: Mapped[Book] = relationship(back_populates="book_authors")
