from app import db
from marshmallow import Schema, fields, ValidationError, pre_load
import datetime
from sqlalchemy import Column, Integer, DateTime
import flask_whooshalchemyplus


authors = db.Table('books_authors',
    db.Column('book_id', db.Integer, db.ForeignKey('books.id'), primary_key=True),
    db.Column('author_id', db.Integer, db.ForeignKey('authors.id'), primary_key=True)
)

stacks = db.Table('books_stacks',
    db.Column('book_id', db.Integer, db.ForeignKey('books.id'), primary_key=True),
    db.Column('stack_id', db.Integer, db.ForeignKey('stacks.id'), primary_key=True)
)

instances = db.Table('books_instances',
    db.Column('book_id', db.Integer, db.ForeignKey('books.id'), primary_key=True),
    db.Column('instance_id', db.Integer, db.ForeignKey('instances.id'), primary_key=True)
)

class Book(db.Model):
    __tablename__ = 'books'

    id = db.Column(db.Integer, primary_key = True)
    title = db.Column(db.String(255))
    file = db.Column(db.String(255))
    cover = db.Column(db.String(255))
    fileformat = db.Column(db.String(255))
    category = db.Column(db.String(255))
    year_published = db.Column(db.Numeric(4,0))
    description = db.Column(db.String(2500))
    html = db.Column(db.String(255))
    downloads = db.Column(db.Numeric(100,0))
    authors = db.relationship('Author', secondary=authors,cascade="delete", lazy='subquery',
        backref=db.backref('books', lazy=True),passive_deletes=True)
    stacks = db.relationship('Stack', secondary=stacks, lazy='subquery',
    backref=db.backref('books', lazy=True))
    instances = db.relationship('Instance', secondary=instances, lazy='subquery',
    backref=db.backref('books', lazy=True))
    scapeX = db.Column(db.Numeric(10,2))
    scapeY = db.Column(db.Numeric(10,2))
    message = db.Column(db.String(1000))
    sameness = db.Column(db.Numeric())
    diversity = db.Column(db.Numeric())
    gender = db.Column(db.Numeric())
    who = db.Column(db.String(255))
    time = db.Column(db.Numeric())


    def __init__(self, title, file, cover, fileformat, category, year_published, message, sameness, diversity, gender, who, time):
        self.title = title
        self.file = file
        self.cover = cover
        self.fileformat = fileformat
        self.category = category
        self.year_published = year_published
        self.download = None
        self.scapeX = 0
        self.scapeY = 0
        self.message = message
        self.sameness = sameness
        self.diversity = diversity
        self.gender = gender
        self.who = who
        self.time = time


    def __repr__(self):
        return '<Title %r>' % self.title

    def get_id(self):
        return self.id


class Author(db.Model):
    __tablename__ = 'authors'

    id = db.Column(db.Integer(), primary_key=True)
    author_name = db.Column(db.String(50))

    def __init__(self, author_name):
        self.author_name = author_name

class Instance(db.Model):
    __tablename__ = 'instances'

    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(50))
    ip = db.Column(db.String(50))
    action = db.Column(db.String(50))

    def __init__(self, ip, action):
        self.name = ip
        self.ip = ip
        self.action = action


class UserIns(db.Model):
    __tablename__ = 'userins'

    id = db.Column(db.Integer(), primary_key=True)
    title = db.Column(db.String(500))
    info = db.Column(db.String(500))

    def __init__(self, title, info):
        self.title = title
        self.info = info

class Chat(db.Model):
    __tablename__ = 'chat'

    id = db.Column(db.Integer(), primary_key=True)
    message = db.Column(db.String(1000))
    time = Column(DateTime, default=datetime.datetime.utcnow)

    def __init__(self, message):
        self.message = message
        self.time = datetime.datetime.utcnow()

class Stack(db.Model):
    __tablename__ = 'stacks'
    id = db.Column(db.Integer, primary_key = True)
    stack_name = db.Column(db.String(50))
    stack_description = db.Column(db.String(1000))
    stack_author = db.Column(db.String(255))


    def __init__(self, stack_name, stack_description, stack_author):
        self.stack_name = stack_name
        self.stack_description = stack_description
        self.stack_author = stack_author

    def __repr__(self):
        return '<Stack %r>' % self.stack_name


class Potential(db.Model):
    __tablename__ = 'potential'
    id = db.Column(db.Integer, primary_key = True)
    ptitle = db.Column(db.String(50))
    time = db.Column(DateTime, default=datetime.datetime.utcnow())

    def __init__(self, ptitle):
        self.ptitle = ptitle
        self.time = datetime.datetime.utcnow()


class AuthorSchema(Schema):
    id = fields.Int(dump_only=True)
    author_name = fields.Str()

class StackSchema(Schema):
    id = fields.Int(dump_only=True)
    stack_name = fields.Str()
    stack_description = fields.Str()

class ChatSchema(Schema):
    id = fields.Int(dump_only=True)
    message = fields.Str()
    time = fields.DateTime()

class BookSchema(Schema):
    id = fields.Int(dump_only=True)
    title = fields.Str()
    file = fields.Str()
    authors = fields.Nested(AuthorSchema, many=True)
    cover = fields.Str()
    html = fields.Str()
    fileformat = fields.Str()
    category = fields.Str()
    year_published = fields.Str()
    stacks = fields.Nested(StackSchema, many=True)


def must_not_be_blank(data):
    if not data:
        raise ValidationError('You forgot to write stuff.')
