from datetime import datetime
from app import db
from app.utils import misc

class ReviewForm(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    application_form_id = db.Column(db.Integer(), db.ForeignKey('application_form.id'), nullable=False)
    is_open = db.Column(db.Boolean(), nullable=False)
    deadline = db.Column(db.DateTime(), nullable=False)

    application_form = db.relationship('ApplicationForm', foreign_keys=[application_form_id])
    review_questions = db.relationship('ReviewQuestion')

    def __init__(self, application_form_id, deadline):
        self.application_form_id = application_form_id
        self.is_open = True
        self.deadline = deadline

    def close(self):
        self.is_open = False


class ReviewQuestion(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    review_form_id = db.Column(db.Integer(), db.ForeignKey('review_form.id'), nullable=False)
    question_id = db.Column(db.Integer(), db.ForeignKey('question.id'), nullable=True)
    
    type = db.Column(db.String(), nullable=False)
    
    is_required = db.Column(db.Boolean(), nullable=False)
    order = db.Column(db.Integer(), nullable=False)
    weight = db.Column(db.Float(), nullable=False)
    review_form = db.relationship('ReviewForm', foreign_keys=[review_form_id])
    question = db.relationship('Question', foreign_keys=[question_id])

    translations = db.relationship('ReviewQuestionTranslation', lazy='dynamic')

    def __init__(self,
                 review_form_id,
                 question_id,
                 type,
                 is_required,
                 order,
                 weight):
        self.review_form_id = review_form_id
        self.question_id = question_id
        self.type = type
        self.is_required = is_required
        self.order = order
        self.weight = weight

    def get_translation(self, language):
        translation = self.translations.filter_by(language=language).first()
        return translation


class ReviewQuestionTranslation(db.Model):
    __tablename__ = 'review_question_translation'
    __table_args__ = tuple([db.UniqueConstraint('review_question_id', 'language', name='uq_review_question_id_language')])

    id = db.Column(db.Integer(), primary_key=True)
    review_question_id = db.Column(db.Integer(), db.ForeignKey('review_question.id'), nullable=False)
    language = db.Column(db.String(2), nullable=False)

    description = db.Column(db.String(), nullable=True)
    headline = db.Column(db.String(), nullable=True)
    placeholder = db.Column(db.String(), nullable=True)
    options = db.Column(db.JSON(), nullable=True)
    validation_regex = db.Column(db.String(), nullable=True)
    validation_text = db.Column(db.String(), nullable=True)

    def __init__(self, 
                 review_question_id,
                 language, 
                 description=None, 
                 headline=None, 
                 placeholder=None, 
                 options=None, 
                 validation_regex=None, 
                 validation_text=None):
        self.review_question_id = review_question_id
        self.language = language
        self.description = description
        self.headline = headline
        self.placeholder = placeholder
        self.options = options
        self.validation_regex = validation_regex
        self.validation_text = validation_text


class ReviewResponse(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    review_form_id = db.Column(db.Integer(), db.ForeignKey('review_form.id'), nullable=False)
    reviewer_user_id = db.Column(db.Integer(), db.ForeignKey('app_user.id'), nullable=False)
    response_id = db.Column(db.Integer(), db.ForeignKey('response.id'), nullable=False)
    submitted_timestamp = db.Column(db.DateTime(), nullable=False)
    language = db.Column(db.String(2), nullable=False)
    is_submitted = db.Column(db.Boolean(), nullable=False)
    submitted_timestamp = db.Column(db.DateTime(), nullable=True)

    review_form = db.relationship('ReviewForm', foreign_keys=[review_form_id])
    reviewer_user = db.relationship('AppUser', foreign_keys=[reviewer_user_id])
    response = db.relationship('Response', foreign_keys=[response_id])
    review_scores = db.relationship('ReviewScore')

    def __init__(self,
                 review_form_id,
                 reviewer_user_id,
                 response_id,
                 language):
        self.review_form_id = review_form_id
        self.reviewer_user_id = reviewer_user_id
        self.response_id = response_id
        self.language = language
        self.is_submitted = False

    def submit(self):
        self.is_submitted = True
        self.submitted_timestamp = datetime.now()

    def calculate_score(self):
        return sum([
            misc.try_parse_float(score.value) * score.review_question.weight for score in self.review_scores
            if score.review_question.weight > 0
        ])


class ReviewScore(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    review_response_id = db.Column(db.Integer(), db.ForeignKey('review_response.id'), nullable=False)
    review_question_id = db.Column(db.Integer(), db.ForeignKey('review_question.id'), nullable=False)
    value = db.Column(db.String(), nullable=False)

    review_response = db.relationship('ReviewResponse', foreign_keys=[review_response_id])
    review_question = db.relationship('ReviewQuestion', foreign_keys=[review_question_id])

    def __init__(self,
                 review_question_id,
                 value):
        self.review_question_id = review_question_id
        self.value = value


class ReviewConfiguration(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    review_form_id = db.Column(db.Integer(), db.ForeignKey('review_form.id'), nullable=False)
    num_reviews_required = db.Column(db.Integer(), nullable=False)
    num_optional_reviews = db.Column(db.Integer(), nullable=False)
    drop_optional_question_id = db.Column(db.Integer(), db.ForeignKey('review_question.id'), nullable=True)
    drop_optional_agreement_values = db.Column(db.String(), nullable=True)

    review_form = db.relationship('ReviewForm', foreign_keys=[review_form_id])
    review_question = db.relationship('ReviewQuestion', foreign_keys=[drop_optional_question_id])

[((11, 23, 11, 93), 'app.db.relationship', 'db.relationship', (), '', False, 'from app import db\n'), ((12, 23, 12, 56), 'app.db.relationship', 'db.relationship', ({(12, 39, 12, 55): '"""ReviewQuestion"""'}, {}), "('ReviewQuestion')", False, 'from app import db\n'), ((24, 9, 24, 48), 'app.db.Column', 'db.Column', (), '', False, 'from app import db\n'), ((33, 18, 33, 78), 'app.db.relationship', 'db.relationship', (), '', False, 'from app import db\n'), ((34, 15, 34, 70), 'app.db.relationship', 'db.relationship', (), '', False, 'from app import db\n'), ((36, 19, 36, 79), 'app.db.relationship', 'db.relationship', (), '', False, 'from app import db\n'), ((101, 18, 101, 78), 'app.db.relationship', 'db.relationship', (), '', False, 'from app import db\n'), ((102, 20, 102, 79), 'app.db.relationship', 'db.relationship', (), '', False, 'from app import db\n'), ((103, 15, 103, 70), 'app.db.relationship', 'db.relationship', (), '', False, 'from app import db\n'), ((104, 20, 104, 50), 'app.db.relationship', 'db.relationship', ({(104, 36, 104, 49): '"""ReviewScore"""'}, {}), "('ReviewScore')", False, 'from app import db\n'), ((134, 22, 134, 90), 'app.db.relationship', 'db.relationship', (), '', False, 'from app import db\n'), ((135, 22, 135, 90), 'app.db.relationship', 'db.relationship', (), '', False, 'from app import db\n'), ((152, 18, 152, 78), 'app.db.relationship', 'db.relationship', (), '', False, 'from app import db\n'), ((153, 22, 153, 97), 'app.db.relationship', 'db.relationship', (), '', False, 'from app import db\n'), ((6, 19, 6, 31), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((7, 36, 7, 48), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((7, 50, 7, 86), 'app.db.ForeignKey', 'db.ForeignKey', ({(7, 64, 7, 85): '"""application_form.id"""'}, {}), "('application_form.id')", False, 'from app import db\n'), ((8, 24, 8, 36), 'app.db.Boolean', 'db.Boolean', ({}, {}), '()', False, 'from app import db\n'), ((9, 25, 9, 38), 'app.db.DateTime', 'db.DateTime', ({}, {}), '()', False, 'from app import db\n'), ((25, 31, 25, 43), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((25, 45, 25, 76), 'app.db.ForeignKey', 'db.ForeignKey', ({(25, 59, 25, 75): '"""review_form.id"""'}, {}), "('review_form.id')", False, 'from app import db\n'), ((26, 28, 26, 40), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((26, 42, 26, 70), 'app.db.ForeignKey', 'db.ForeignKey', ({(26, 56, 26, 69): '"""question.id"""'}, {}), "('question.id')", False, 'from app import db\n'), ((28, 21, 28, 32), 'app.db.String', 'db.String', ({}, {}), '()', False, 'from app import db\n'), ((30, 28, 30, 40), 'app.db.Boolean', 'db.Boolean', ({}, {}), '()', False, 'from app import db\n'), ((31, 22, 31, 34), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((32, 23, 32, 33), 'app.db.Float', 'db.Float', ({}, {}), '()', False, 'from app import db\n'), ((61, 19, 61, 31), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((62, 35, 62, 47), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((62, 49, 62, 84), 'app.db.ForeignKey', 'db.ForeignKey', ({(62, 63, 62, 83): '"""review_question.id"""'}, {}), "('review_question.id')", False, 'from app import db\n'), ((63, 25, 63, 37), 'app.db.String', 'db.String', ({(63, 35, 63, 36): '2'}, {}), '(2)', False, 'from app import db\n'), ((65, 28, 65, 39), 'app.db.String', 'db.String', ({}, {}), '()', False, 'from app import db\n'), ((66, 25, 66, 36), 'app.db.String', 'db.String', ({}, {}), '()', False, 'from app import db\n'), ((67, 28, 67, 39), 'app.db.String', 'db.String', ({}, {}), '()', False, 'from app import db\n'), ((68, 24, 68, 33), 'app.db.JSON', 'db.JSON', ({}, {}), '()', False, 'from app import db\n'), ((69, 33, 69, 44), 'app.db.String', 'db.String', ({}, {}), '()', False, 'from app import db\n'), ((70, 32, 70, 43), 'app.db.String', 'db.String', ({}, {}), '()', False, 'from app import db\n'), ((92, 19, 92, 31), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((93, 31, 93, 43), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((93, 45, 93, 76), 'app.db.ForeignKey', 'db.ForeignKey', ({(93, 59, 93, 75): '"""review_form.id"""'}, {}), "('review_form.id')", False, 'from app import db\n'), ((94, 33, 94, 45), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((94, 47, 94, 75), 'app.db.ForeignKey', 'db.ForeignKey', ({(94, 61, 94, 74): '"""app_user.id"""'}, {}), "('app_user.id')", False, 'from app import db\n'), ((95, 28, 95, 40), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((95, 42, 95, 70), 'app.db.ForeignKey', 'db.ForeignKey', ({(95, 56, 95, 69): '"""response.id"""'}, {}), "('response.id')", False, 'from app import db\n'), ((96, 36, 96, 49), 'app.db.DateTime', 'db.DateTime', ({}, {}), '()', False, 'from app import db\n'), ((97, 25, 97, 37), 'app.db.String', 'db.String', ({(97, 35, 97, 36): '2'}, {}), '(2)', False, 'from app import db\n'), ((98, 29, 98, 41), 'app.db.Boolean', 'db.Boolean', ({}, {}), '()', False, 'from app import db\n'), ((99, 36, 99, 49), 'app.db.DateTime', 'db.DateTime', ({}, {}), '()', False, 'from app import db\n'), ((119, 35, 119, 49), 'datetime.datetime.now', 'datetime.now', ({}, {}), '()', False, 'from datetime import datetime\n'), ((129, 19, 129, 31), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((130, 35, 130, 47), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((130, 49, 130, 84), 'app.db.ForeignKey', 'db.ForeignKey', ({(130, 63, 130, 83): '"""review_response.id"""'}, {}), "('review_response.id')", False, 'from app import db\n'), ((131, 35, 131, 47), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((131, 49, 131, 84), 'app.db.ForeignKey', 'db.ForeignKey', ({(131, 63, 131, 83): '"""review_question.id"""'}, {}), "('review_question.id')", False, 'from app import db\n'), ((132, 22, 132, 33), 'app.db.String', 'db.String', ({}, {}), '()', False, 'from app import db\n'), ((145, 19, 145, 31), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((146, 31, 146, 43), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((146, 45, 146, 76), 'app.db.ForeignKey', 'db.ForeignKey', ({(146, 59, 146, 75): '"""review_form.id"""'}, {}), "('review_form.id')", False, 'from app import db\n'), ((147, 37, 147, 49), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((148, 37, 148, 49), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((149, 42, 149, 54), 'app.db.Integer', 'db.Integer', ({}, {}), '()', False, 'from app import db\n'), ((149, 56, 149, 91), 'app.db.ForeignKey', 'db.ForeignKey', ({(149, 70, 149, 90): '"""review_question.id"""'}, {}), "('review_question.id')", False, 'from app import db\n'), ((150, 47, 150, 58), 'app.db.String', 'db.String', ({}, {}), '()', False, 'from app import db\n'), ((59, 28, 59, 120), 'app.db.UniqueConstraint', 'db.UniqueConstraint', (), '', False, 'from app import db\n'), ((123, 12, 123, 45), 'app.utils.misc.try_parse_float', 'misc.try_parse_float', ({(123, 33, 123, 44): 'score.value'}, {}), '(score.value)', False, 'from app.utils import misc\n')]