from app.main.data_model.games.pv_challenge.pv_challenge_decision import PVChallengeDecision
from app.main.data_model.games.pv_challenge.pv_challenge_challenge_decision import PVChallengeChallengeDecision
from app.main.data_model.games.pv_challenge.pv_challenge_challenge_decision_details import PVChallengeChallengeDecisionDetails
from app.main.data_model.games.pv_challenge.pv_challenge_challenge_day import PVChallengeChallengeDay
from app.main.data_model.games.pv_challenge.pv_challenge_challenge import PVChallengeChallenge
from app.main.data_model.games.pv_challenge.pv_challenge_challenge_story_steps import PVChallengeChallengeStorySteps
from sqlalchemy import func


class PVChallengeDecisionRepository:

    def __init__(self, session):
        self.session = session

    def get_decision_scores(self, decision_ids):
        decision_scores = self.session.query(PVChallengeDecision.day_id, func.sum(PVChallengeDecision.score1),
                                             func.sum(PVChallengeDecision.score2)).filter(PVChallengeDecision.id.in_(decision_ids))\
                                .group_by(PVChallengeDecision.day_id).all()
        if len(decision_scores) == 0:
            return None
        return decision_scores

    def get_aggregated_decision_scores(self, decision_ids, challenge_id):
        decision_scores = self.session.query(func.sum(PVChallengeDecision.score1),
                                             func.sum(PVChallengeDecision.score2)
                                             ).join(PVChallengeChallengeDecision)\
                            .filter(PVChallengeDecision.id.in_(decision_ids),
                            PVChallengeChallengeDecision.challenge_id == challenge_id,
                            PVChallengeChallengeDecision.decision_id == PVChallengeDecision.id).all()
        if decision_scores is None or len(decision_scores) == 0 or decision_scores[0][0] is None:
            return [(0, 0)]
        return decision_scores

    def get_score(self, challenge_id):
        scores = self.session.query(func.sum(PVChallengeDecision.score1), func.sum(PVChallengeDecision.score2))\
            .join(PVChallengeChallengeDecision).filter(
                PVChallengeDecision.id == PVChallengeChallengeDecision.decision_id,
            PVChallengeChallengeDecision.challenge_id == challenge_id).all()
        if len(scores) == 0:
            return None
        return scores

    def get_scores(self, game_session_id):
        scores = self.session.query(PVChallengeChallenge.id, func.sum(PVChallengeDecision.score1),
                                    func.sum(PVChallengeDecision.score2))\
                            .select_from(PVChallengeChallenge)\
                            .join(PVChallengeChallengeDecision).join(PVChallengeDecision)\
                            .filter(PVChallengeDecision.id == PVChallengeChallengeDecision.decision_id,
                                    PVChallengeChallenge.id == PVChallengeChallengeDecision.challenge_id,
                                    PVChallengeChallenge.game_session_id == game_session_id
                                    )\
                            .group_by(PVChallengeChallenge.id).all()

        if len(scores) == 0:
            return None
        return scores

    def get_scores_by_challenge_id(self, challenge_id):
        scores = self.session.query(PVChallengeChallenge.id, func.sum(PVChallengeDecision.score1), func.sum(PVChallengeDecision.score2)) \
            .select_from(PVChallengeChallenge) \
            .join(PVChallengeChallengeDecision).join(PVChallengeDecision) \
            .filter(PVChallengeDecision.id == PVChallengeChallengeDecision.decision_id,
                    PVChallengeChallenge.id == PVChallengeChallengeDecision.challenge_id,
                    PVChallengeChallenge.id == challenge_id
                    ) \
            .group_by(PVChallengeChallenge.id).all()

        if len(scores) == 0:
            return None
        return scores



    def get_pv_challenge_challenge_day(self, challenge_id, day_id):
        challenge_day = self.session.query(PVChallengeChallengeDay).filter(
            PVChallengeChallengeDay.challenge_id == challenge_id,
            PVChallengeChallengeDay.day_id == day_id
        ).first()
        return challenge_day

    def get_pv_challenge_challenge_days(self, challenge_id):
        challenge_days = self.session.query(PVChallengeChallengeDay).filter(
            PVChallengeChallengeDay.challenge_id == challenge_id).all()
        if len(challenge_days) == 0:
            return None
        return challenge_days

    def get_pv_challenge_challenge_decisions(self, challenge_id):
        decisions = self.session.query(PVChallengeChallengeDecision).filter(PVChallengeChallengeDecision.challenge_id == challenge_id).all()
        if len(decisions) == 0:
            return None
        return decisions

    def get_pv_challenge_challenge_decision_details(self, challenge_id, day_id):
        decision_details = self.session.query(PVChallengeChallengeDecisionDetails).\
            filter(
            PVChallengeChallengeDecisionDetails.challenge_id == challenge_id,
                PVChallengeChallengeDecisionDetails.day_id == day_id).all()
        if len(decision_details) == 0:
            return []
        return decision_details

    def get_pv_challenge_challenge_decisions_by_challenge_id_and_day_id(self, challenge_id, day_id):
        old_decisions = self.session.query(PVChallengeChallengeDecision).filter(
            PVChallengeChallengeDecision.challenge_id == challenge_id,
            PVChallengeChallengeDecision.day_id == day_id
        ).all()
        if len(old_decisions) == 0:
            return None
        return old_decisions

    def delete_pv_challenge_challenge_decisions(self, decision_ids):
        self.session.query(PVChallengeChallengeDecision).filter(
            PVChallengeChallengeDecision.id.in_(decision_ids)
        ).delete()
        self.session.flush()

    def get_pv_challenge_challenge_old_decision_details(self, challenge_id, day_id):
        old_decisions_details = self.session.query(PVChallengeChallengeDecisionDetails).filter(
            PVChallengeChallengeDecisionDetails.challenge_id == challenge_id,
            PVChallengeChallengeDecisionDetails.day_id == day_id
        ).all()
        if len(old_decisions_details) == 0:
            return None
        return old_decisions_details[0]

    def get_challenge_badge_decisions(self, decision_ids, challenge_id):
        challenge_decision_ids = self.session.query(PVChallengeDecision.id).join(PVChallengeChallengeDecision).filter(
            PVChallengeChallengeDecision.challenge_id == challenge_id,
            PVChallengeChallengeDecision.decision_id == PVChallengeDecision.id,
            PVChallengeDecision.id.in_(decision_ids)
        ).all()
        return challenge_decision_ids

    def get_challenge_story_steps(self, challenge_id):
        challenge_story_steps = self.session.query(PVChallengeChallengeStorySteps).filter(
            PVChallengeChallengeStorySteps.challenge_id == challenge_id
        ).all()
        if len(challenge_story_steps) == 0:
            return []
        return challenge_story_steps



