from flask import jsonify, request, send_file
from flask_restx import Resource

from app.main.api_declaration import ne_api
from app.main.data_management.data_base import Schema
from app.main.request_handlers.orchestrators.games.pv_challenge_orchestrator import PVChallengeOrchestrator
from app.main.request_handlers.orchestrators.common.user_orchestrator import UserOrchestrator


@ne_api.route('/participant/pv_challenge/updatechallenge')
class ParticipantPVChallengeUpdateChallenge(Resource):
    def post(self):
        session = Schema.get_session()
        user_orchestrator = UserOrchestrator(session)
        id = user_orchestrator.validate_user_using_bearer_token(request)
        challenge_data = request.get_json()
        orchestrator = PVChallengeOrchestrator(session)
        result = orchestrator.update_challenge(id, challenge_data)
        return jsonify(result)


@ne_api.route('/participant/pv_challenge/getchallenge')
class ParticipantPVChallengeGetChallengeData(Resource):
    def get(self):
        session = Schema.get_session()
        user_orchestrator = UserOrchestrator(session)
        id = user_orchestrator.validate_user_using_bearer_token(request)
        game_session_id = int(request.args.get("game_session_id"))
        orchestrator = PVChallengeOrchestrator(session)
        result = orchestrator.get_challenge_data(id, game_session_id)
        return jsonify(result)


@ne_api.route('/participant/pv_challenge/savedecisions')
class ParticipantPVChallengeSaveDecisions(Resource):
    def post(self):
        session = Schema.get_session()
        user_orchestrator = UserOrchestrator(session)
        id = user_orchestrator.validate_user_using_bearer_token(request)
        decisions_data = request.get_json()
        orchestrator = PVChallengeOrchestrator(session)
        result = orchestrator.save_decisions(id, decisions_data)
        return jsonify(result)


@ne_api.route('/participant/pv_challenge/savedecisiondetails')
class ParticipantPVChallengeSaveDecisionDetails(Resource):
    def post(self):
        session = Schema.get_session()
        user_orchestrator = UserOrchestrator(session)
        id = user_orchestrator.validate_user_using_bearer_token(request)
        decision_details_data = request.get_json()
        orchestrator = PVChallengeOrchestrator(session)
        result = orchestrator.save_decision_details(id, decision_details_data)
        return jsonify(result)


@ne_api.route('/participant/pv_challenge/getdecisiondetails')
class ParticipantPVChallengeGetDecisionDetails(Resource):
    def get(self):
        session = Schema.get_session()
        user_orchestrator = UserOrchestrator(session)
        id = user_orchestrator.validate_user_using_bearer_token(request)
        challenge_id = int(request.args.get("challenge_id"))
        day_id = int(request.args.get("day_id"))
        orchestrator = PVChallengeOrchestrator(session)
        result = orchestrator.get_decision_details(id, challenge_id, day_id)
        return jsonify(result)


@ne_api.route('/participant/pv_challenge/getscore')
class ParticipantPVChallengeGetScore(Resource):
    def get(self):
        session = Schema.get_session()
        user_orchestrator = UserOrchestrator(session)
        id = user_orchestrator.validate_user_using_bearer_token(request)
        challenge_id = int(request.args.get("challenge_id"))
        orchestrator = PVChallengeOrchestrator(session)
        result = orchestrator.get_score(id, challenge_id)
        return jsonify(result)


@ne_api.route('/participant/pv_challenge/getscores')
class ParticipantPVChallengeGetScores(Resource):
    def get(self):
        session = Schema.get_session()
        user_orchestrator = UserOrchestrator(session)
        id = user_orchestrator.validate_user_using_bearer_token(request)
        game_session_id = int(request.args.get("game_session_id"))
        orchestrator = PVChallengeOrchestrator(session)
        result = orchestrator.get_scores(id, game_session_id, number=10)
        return jsonify(result)


@ne_api.route('/moderator/pv_challenge/getscores')
class ModeratorPVChallengeGetScores(Resource):
    def get(self):
        session = Schema.get_session()
        user_orchestrator = UserOrchestrator(session)
        id = user_orchestrator.validate_user_using_bearer_token(request)
        game_session_id = int(request.args.get("game_session_id"))
        orchestrator = PVChallengeOrchestrator(session)
        result = orchestrator.get_scores(id, game_session_id, number=-1)
        return jsonify(result)


@ne_api.route('/participant/pv_challenge/closeday')
class ParticipantPVChallengeCloseDay(Resource):
    def get(self):
        session = Schema.get_session()
        user_orchestrator = UserOrchestrator(session)
        id = user_orchestrator.validate_user_using_bearer_token(request)
        challenge_id = int(request.args.get("challenge_id"))
        day_id = int(request.args.get("day_id"))
        orchestrator = PVChallengeOrchestrator(session)
        result = orchestrator.close_day(id, challenge_id, day_id)
        return jsonify(result)


@ne_api.route('/participant/pv_challenge/gethistoricscores')
class ParticipantPVChallengeGetHistoricScores(Resource):
    def get(self):
        session = Schema.get_session()
        user_orchestrator = UserOrchestrator(session)
        id = user_orchestrator.validate_user_using_bearer_token(request)
        challenge_id = int(request.args.get("challenge_id"))
        orchestrator = PVChallengeOrchestrator(session)
        result = orchestrator.get_historic_scores(id, challenge_id)
        return jsonify(result)


@ne_api.route('/participant/pv_challenge/getbadgesstatus')
class ParticipantPVChallengeGetBadgesStatus(Resource):
    def get(self):
        session = Schema.get_session()
        user_orchestrator = UserOrchestrator(session)
        id = user_orchestrator.validate_user_using_bearer_token(request)
        challenge_id = int(request.args.get("challenge_id"))
        orchestrator = PVChallengeOrchestrator(session)
        result = orchestrator.get_badges_status(id, challenge_id)
        return jsonify(result)


@ne_api.route('/participant/pv_challenge/export_certificate')
class ParticipantPVChallengeExportCertificate(Resource):
    def get(self):
        session = Schema.get_session()
        user_orchestrator = UserOrchestrator(session)
        id = user_orchestrator.validate_user_using_bearer_token(request)
        challenge_id = int(request.args.get("challenge_id"))
        orchestrator = PVChallengeOrchestrator(session)
        result, file_name = orchestrator.get_certificate(id, challenge_id)
        return send_file(result, download_name=file_name, as_attachment=True)


@ne_api.route('/participant/pv_challenge/finish_challenge')
class ParticipantPVChallengeFinishChallenge(Resource):
    def get(self):
        session = Schema.get_session()
        user_orchestrator = UserOrchestrator(session)
        id = user_orchestrator.validate_user_using_bearer_token(request)
        challenge_id = int(request.args.get("challenge_id"))
        orchestrator = PVChallengeOrchestrator(session)
        result = orchestrator.finish_challenge(id, challenge_id)
        return jsonify(result)