from flask.views import MethodView
from flask_smorest import Blueprint
from src.views.assignments.utils import AssignmentManager
from src.models.schema import (
    AssignmentSchema,
    AssignmentCreateSchema,
    AssignmentUpdateSchema,
    AssignmentSubmissionSchema,
    AssignmentGradeSchema,
    FeedbackResponseSchema
)
from flask import request

assignment_router = Blueprint("Assignment Management Routes", __name__, description="Operations related to assignment management")

@assignment_router.route("/assignments")
class AssignmentRouter(MethodView):
    def __init__(self) -> None:
        self.manager = AssignmentManager()

    @assignment_router.response(status_code=200, schema=AssignmentSchema(many=True))
    def get(self):
        """Get all assignments with pagination"""
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        course_id = request.args.get('course_id')
        return self.manager.get_course_assignments(course_id=course_id, page=page, per_page=per_page)

    @assignment_router.arguments(schema=AssignmentCreateSchema, location='json')
    @assignment_router.response(status_code=201, schema=AssignmentSchema)
    def post(self, payload):
        """Create a new assignment"""
        return self.manager.create_assignment(payload)

@assignment_router.route("/assignments/<string:assignment_id>")
class AssignmentDetailRouter(MethodView):
    def __init__(self) -> None:
        self.manager = AssignmentManager()

    @assignment_router.response(status_code=200, schema=AssignmentSchema)
    def get(self, assignment_id):
        """Get assignment details"""
        include_submissions = request.args.get('include_submissions', False, type=bool)
        return self.manager.get_assignment_details(assignment_id, include_submissions=include_submissions)

    @assignment_router.arguments(schema=AssignmentUpdateSchema, location='json')
    @assignment_router.response(status_code=200, schema=AssignmentSchema)
    def put(self, payload, assignment_id):
        """Update an assignment"""
        return self.manager.update_assignment(assignment_id, payload)

    @assignment_router.response(status_code=204)
    def delete(self, assignment_id):
        """Delete an assignment"""
        return self.manager.delete_assignment(assignment_id)

@assignment_router.route("/assignments/<string:assignment_id>/submissions")
class AssignmentSubmissionRouter(MethodView):
    def __init__(self) -> None:
        self.manager = AssignmentManager()

    @assignment_router.response(status_code=200, schema=AssignmentSubmissionSchema(many=True))
    def get(self, assignment_id):
        """Get all submissions for an assignment"""
        graded_only = request.args.get('graded_only', False, type=bool)
        return self.manager.get_course_submissions(assignment_id, graded_only=graded_only)

    @assignment_router.arguments(schema=AssignmentSubmissionSchema, location='json')
    @assignment_router.response(status_code=201, schema=AssignmentSubmissionSchema)
    def post(self, payload, assignment_id):
        """Submit an assignment"""
        return self.manager.submit_assignment(payload['student_id'], assignment_id, payload)

@assignment_router.route("/assignments/stats")
class AssignmentGeneralStatsRouter(MethodView):
    def __init__(self) -> None:
        self.manager = AssignmentManager()

    @assignment_router.response(status_code=200)
    def get(self):
        """Get general assignment statistics for a course"""
        course_id = request.args.get('course_id')
        return self.manager.get_general_assignment_stats(course_id)

@assignment_router.route("/assignments/<string:assignment_id>/stats")
class AssignmentStatsRouter(MethodView):
    def __init__(self) -> None:
        self.manager = AssignmentManager()

    @assignment_router.response(status_code=200)
    def get(self, assignment_id):
        """Get assignment statistics"""
        return self.manager.get_assignment_stats(assignment_id)

@assignment_router.route("/assignments/<string:assignment_id>/reminders")
class AssignmentReminderRouter(MethodView):
    def __init__(self) -> None:
        self.manager = AssignmentManager()

    @assignment_router.response(status_code=200)
    def post(self, assignment_id):
        """Send reminders for an assignment"""
        return self.manager.send_assignment_reminders(assignment_id)

@assignment_router.route("/submissions/<string:submission_id>")
class SubmissionDetailRouter(MethodView):
    def __init__(self) -> None:
        self.manager = AssignmentManager()

    @assignment_router.response(status_code=200, schema=AssignmentSubmissionSchema)
    def get(self, submission_id):
        """Get submission details"""
        return self.manager.get_submission_details(submission_id)

    @assignment_router.arguments(schema=AssignmentGradeSchema, location='json')
    @assignment_router.response(status_code=200, schema=AssignmentSubmissionSchema)
    def put(self, payload, submission_id):
        """Grade a submission"""
        return self.manager.grade_submission(submission_id, payload)

@assignment_router.route("/submissions/<string:submission_id>/feedback")
class SubmissionFeedbackRouter(MethodView):
    def __init__(self) -> None:
        self.manager = AssignmentManager()

    @assignment_router.response(status_code=200, schema=FeedbackResponseSchema(many=True))
    def get(self, submission_id):
        """Get feedback responses for a submission"""
        return self.manager.get_feedback_responses(submission_id)

    @assignment_router.arguments(schema=FeedbackResponseSchema, location='json')
    @assignment_router.response(status_code=201, schema=FeedbackResponseSchema)
    def post(self, payload, submission_id):
        """Add feedback response"""
        return self.manager.add_feedback_response(submission_id, payload)

@assignment_router.route("/students/<string:student_id>/assignments")
class StudentAssignmentRouter(MethodView):
    def __init__(self) -> None:
        self.manager = AssignmentManager()

    @assignment_router.response(status_code=200, schema=AssignmentSubmissionSchema(many=True))
    def get(self, student_id):
        """Get all submissions for a student"""
        course_id = request.args.get('course_id')
        return self.manager.get_student_submissions(student_id, course_id=course_id)

@assignment_router.route("/students/<string:student_id>/progress")
class StudentProgressRouter(MethodView):
    def __init__(self) -> None:
        self.manager = AssignmentManager()

    @assignment_router.response(status_code=200)
    def get(self, student_id):
        """Get student progress"""
        course_id = request.args.get('course_id')
        return self.manager.get_student_progress(student_id, course_id=course_id)

@assignment_router.route("/students/<string:student_id>/upcoming")
class StudentUpcomingRouter(MethodView):
    def __init__(self) -> None:
        self.manager = AssignmentManager()

    @assignment_router.response(status_code=200)
    def get(self, student_id):
        """Get upcoming assignments for a student"""
        days_ahead = request.args.get('days_ahead', 7, type=int)
        return self.manager.get_upcoming_assignments(student_id, days_ahead=days_ahead)