from flask.views import MethodView
from flask_smorest import Blueprint
from src.views.student.utils import StudentsManager
from flask import request
from src.utils import custom_response
from src.models.schema import (
    StudentSchema,
    TeachingSessionSchema,
    AttendanceSchema,
    AssignmentSchema,
    EnrollmentSchema,
    CourseProgressSchema
)

student_router = Blueprint("Student Management Routes", __name__, description="Operations related to student management")

@student_router.route("/students")
class StudentRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200, schema=StudentSchema(many=True))
    def get(self):
        """Get all students with pagination"""
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        filters = request.args.to_dict()
        return self.student_manager.fetchAll(page=page, per_page=per_page, filters=filters)

    @student_router.arguments(schema=StudentSchema, location='json')
    @student_router.response(status_code=201, schema=StudentSchema)
    def post(self, payload):
        """Create a new student"""
        return self.student_manager.create(payload)

@student_router.route("/students/<string:student_id>")
class StudentDetailRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200, schema=StudentSchema)
    def get(self, student_id):
        """Get a student by ID"""
        return self.student_manager.get(student_id)

    @student_router.arguments(schema=StudentSchema, location='json')
    @student_router.response(status_code=200)
    def put(self, payload, student_id):
        """Update a student"""
        return self.student_manager.update(student_id, payload)

    @student_router.response(status_code=204)
    def delete(self, student_id):
        """Deactivate a student"""
        return self.student_manager.delete(student_id)

@student_router.route("/students/<string:student_id>/courses")
class StudentCoursesRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    def get(self, student_id):
        """Get all courses a student is enrolled in"""
        return self.student_manager.get_courses(student_id)

@student_router.route("/students/<string:student_id>/courses/<string:course_id>", methods=["POST", "DELETE"])
class StudentCourseEnrollmentRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200)
    def post(self, student_id, course_id):
        """Enroll a student in a course"""
        return self.student_manager.enroll_in_course(student_id, course_id)

    @student_router.response(status_code=200)
    def delete(self, student_id, course_id):
        """Withdraw a student from a course"""
        reason = request.args.get('reason')
        return self.student_manager.withdraw_from_course(student_id, course_id, reason)

@student_router.route("/students/<string:student_id>/sessions/upcoming")
class StudentUpcomingSessionsRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200, schema=TeachingSessionSchema(many=True))
    def get(self, student_id):
        """Get upcoming sessions for a student"""
        days_ahead = request.args.get('days_ahead', 7, type=int)
        return self.student_manager.get_upcoming_sessions(student_id, days_ahead)

@student_router.route("/students/<string:student_id>/sessions/past")
class StudentPastSessionsRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200, schema=TeachingSessionSchema(many=True))
    def get(self, student_id):
        """Get past sessions for a student"""
        days_back = request.args.get('days_back', 30, type=int)
        return self.student_manager.get_past_sessions(student_id, days_back)

@student_router.route("/students/<string:student_id>/daily-sessions")
class StudentDailySessionsRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    def get(self, student_id):
        """Get all daily sessions for a student (upcoming and past)"""
        return self.student_manager.get_daily_sessions(student_id)

@student_router.route("/students/<string:student_id>/attendance")
class StudentAttendanceRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200, schema=AttendanceSchema(many=True))
    def get(self, student_id):
        """Get attendance records for a student"""
        course_id = request.args.get('course_id')
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 20, type=int)
        return self.student_manager.get_attendance_records(student_id, course_id, page, per_page)

@student_router.route("/students/<string:student_id>/attendance/record", methods=["POST"])
class StudentRecordAttendanceRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=201)
    def post(self, student_id):
        """Record student attendance for a daily session"""
        data = request.get_json()
        daily_session_id = data.get('daily_session_id')
        status = data.get('status')  # present, late, absent
        notes = data.get('notes')
        verification_data = data.get('verification_data', {})
        
        if not daily_session_id or not status:
            return custom_response(
                success=False,
                data="daily_session_id and status are required",
                status_code=400
            )
        
        if status not in ['present', 'late', 'absent']:
            return custom_response(
                success=False,
                data="status must be one of: present, late, absent",
                status_code=400
            )
        
        return self.student_manager.record_student_attendance(
            student_id, daily_session_id, status, notes, verification_data
        )

@student_router.route("/students/<string:student_id>/analytics", methods=["GET"])
class StudentAnalyticsRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200)
    def get(self, student_id):
        """Get comprehensive analytics for a student"""
        try:
            period = request.args.get('period', 'current')  # current, 30d, 90d, 1y
            return self.student_manager.get_student_analytics(student_id, period)
        except Exception as e:
            return custom_response(
                success=False,
                data=f"Failed to retrieve student analytics: {str(e)}",
                status_code=500
            )

@student_router.route("/students/progress", methods=["GET"])
class StudentsProgressRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200)
    def get(self):
        """Get progress data for all students"""
        try:
            return self.student_manager.get_all_students_progress()
        except Exception as e:
            return custom_response(
                success=False,
                data=f"Failed to retrieve students progress: {str(e)}",
                status_code=500
            )

@student_router.route("/assignments/progress", methods=["GET"])
class AssignmentsProgressRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200)
    def get(self):
        """Get progress data for all assignments"""
        try:
            return self.student_manager.get_assignments_progress()
        except Exception as e:
            return custom_response(
                success=False,
                data=f"Failed to retrieve assignments progress: {str(e)}",
                status_code=500
            )

@student_router.route("/students/<string:student_id>/attendance/<string:attendance_id>/dispute", methods=["POST"])
class StudentAttendanceDisputeRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200)
    def post(self, student_id, attendance_id):
        """Dispute an attendance record"""
        reason = request.get_json().get('reason')
        return self.student_manager.dispute_attendance(student_id, attendance_id, reason)

@student_router.route("/students/<string:student_id>/assignments")
class StudentAssignmentsRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200, schema=AssignmentSchema(many=True))
    def get(self, student_id):
        """Get assignments for a student"""
        status = request.args.get('status')
        course_id = request.args.get('course_id')
        return self.student_manager.get_assignments(student_id, status, course_id)

@student_router.route("/students/<string:student_id>/assignments/<string:assignment_id>", methods=["POST"])
class StudentAssignmentSubmissionRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.arguments(schema=AssignmentSchema, location='json')
    @student_router.response(status_code=200)
    def post(self, payload, student_id, assignment_id):
        """Submit an assignment"""
        return self.student_manager.submit_assignment(student_id, assignment_id, payload)

@student_router.route("/students/<string:student_id>/progress")
class StudentProgressRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200, schema=CourseProgressSchema(many=True))
    def get(self, student_id):
        """Get progress for a student across all courses"""
        return self.student_manager.get_progress(student_id)

@student_router.route("/students/<string:student_id>/courses/<string:course_id>/progress")
class StudentCourseProgressRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200, schema=CourseProgressSchema)
    def get(self, student_id, course_id):
        """Get progress for a specific course"""
        return self.student_manager.get_course_progress(student_id, course_id)

@student_router.route("/students/reminders/sessions")
class StudentSessionRemindersRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200)
    def post(self):
        """Trigger session reminders for all students (admin only)"""
        return self.student_manager.send_session_reminders()

@student_router.route("/students/reminders/assignments")
class StudentAssignmentRemindersRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200)
    def post(self):
        """Trigger assignment reminders for all students (admin only)"""
        return self.student_manager.send_assignment_reminders()

@student_router.route("/students/<string:student_id>/specialities")
class StudentSpecialitiesRouter(MethodView):
    def __init__(self) -> None:
        self.student_manager = StudentsManager()

    @student_router.response(status_code=200)
    def get(self, student_id):
        """Get specialities for a student"""
        return self.student_manager.get_student_specialities(student_id)