from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.dialects.mysql import BIT
from sqlalchemy.orm import relationship

from .base import Base, BaseMixin


class Publisher(Base, BaseMixin):
    __tablename__ = "publisher"
    name = Column(String(length=255), unique=True)
    comics = relationship("Comic")

    def __repr__(self):
        return f'Publisher({self.id} {self.name})'

    def __str__(self):
        return self.__repr__()


class Comic(Base, BaseMixin):
    __tablename__ = 'comic'
    title = Column(String(length=255), unique=True)
    publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False)
    publisher = relationship("Publisher", back_populates="comics")
    current_order = Column(BIT(1))
    completed = Column(BIT(1))
    issues = relationship("Issue")
    story_arcs = relationship("StoryArc")
    trade_paperbacks = relationship("TradePaperback")
    volumes = relationship("Volume")
    comic_works = relationship("ComicWork")

    def __repr__(self):
        return f'Comic({self.id} {self.version} {self.title} {self.publisher.name})'

    def __str__(self):
        return f'{self.title}({self.id})'


class Volume(Base, BaseMixin):
    __tablename__ = "volume"
    name = Column(String(length=255), nullable=False)
    comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
    comic = relationship("Comic", back_populates="volumes")
    issues = relationship("Issue")


class TradePaperback(Base, BaseMixin):
    __tablename__ = "trade_paperback"
    name = Column(String(length=255), nullable=False)
    issue_start = Column(Integer)
    issue_end = Column(Integer)
    comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
    comic = relationship("Comic", back_populates="trade_paperbacks")


class StoryArc(Base, BaseMixin):
    __tablename__ = "story_arc"
    name = Column(String(length=255), nullable=False)
    comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
    comic = relationship("Comic", back_populates="story_arcs")


class Issue(Base, BaseMixin):
    __tablename__ = "issue"
    issue_number = Column(String(255))
    in_stock = Column(BIT(1))
    is_read = Column(BIT(1))
    comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
    comic = relationship("Comic", back_populates="issues")
    volume_id = Column(String, ForeignKey("volume.id"), nullable=True)
    volume = relationship("Volume", back_populates="issues")


class Artist(Base, BaseMixin):
    __tablename__ = "artist"
    name = Column(String(length=255), nullable=False)
    comic_works = relationship("ComicWork")


class WorkType(Base, BaseMixin):
    __tablename__ = "worktype"
    name = Column(String(length=255), nullable=False, unique=True)
    comic_works = relationship("ComicWork")

    def __repr__(self):
        return f'Worktype({self.id} {self.version} {self.name} {len(self.comic_works)})'

    def __str__(self):
        return f'{self.name}({self.id})'


class ComicWork(Base, BaseMixin):
    __tablename__ = "comic_work"
    comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
    comic = relationship("Comic", back_populates="comic_works")
    artist_id = Column(String, ForeignKey("artist.id"), nullable=False)
    artist = relationship("Artist", back_populates="comic_works")
    work_type_id = Column(String, ForeignKey("worktype.id"), nullable=False)
    work_type = relationship("WorkType", back_populates="comic_works")
