from flask.views import MethodView
from flask_smorest import Blueprint
from src.views.course.utils import CourseManager
from flask import request
from src.models.schema import (
    EnrollmentSchema,
    CourseProgressSchema,
)

course_router = Blueprint("Course Management Routes", __name__, description="Operations on courses")

@course_router.route("/courses")
class CourseRouter(MethodView):
    def __init__(self) -> None:
        self.course_manager = CourseManager()

    def get(self):
        """Get list of courses with pagination (role-specific)"""
        user_id = request.args.get('user_id', type=str)
        user_type = request.args.get('user_type', type=str)
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        search = request.args.get('search', '', type=str)
        status_filter = request.args.get('status', 'all', type=str)
        
        if not user_id or not user_type:
            return {"message": "user_id and user_type parameters are required"}, 400
            
        return self.course_manager.fetchAll(user_id, user_type, page, per_page, search, status_filter)

    def post(self):
        """Create a new course (supervisor only)"""
        payload = request.get_json()
        return self.course_manager.create(payload)

@course_router.route("/courses/<string:course_id>")
class CourseDetailRouter(MethodView):
    def __init__(self) -> None:
        self.course_manager = CourseManager()

    def get(self, course_id):
        """Get course details with role-specific information"""
        user_id = request.args.get('user_id', type=str)
        user_type = request.args.get('user_type', type=str)
        
        if not user_id or not user_type:
            return {"message": "user_id and user_type parameters are required"}, 400
            
        return self.course_manager.get(course_id, user_id, user_type)

    def put(self, course_id):
        """Update course details (supervisor only)"""
        payload= request.get_json()
        return self.course_manager.update(course_id, payload)

    @course_router.response(status_code=204)
    def delete(self, course_id):
        """Archive a course (soft delete, supervisor only)"""
        requester_id = request.args.get('requester_id', type=str)
        if not requester_id:
            return {"message": "requester_id parameter is required"}, 400
        return self.course_manager.delete(course_id, requester_id)

@course_router.route("/courses/<string:course_id>/students")
class CourseStudentsRouter(MethodView):
    def __init__(self) -> None:
        self.course_manager = CourseManager()

    def get(self, course_id):
        """Get all students enrolled in a specific course"""
        requester_id = request.args.get('requester_id', type=str)
        requester_type = request.args.get('requester_type', type=str)
        
        return self.course_manager.get_course_students(course_id, requester_id, requester_type)

@course_router.route("/courses/<string:course_id>/restore")
class CourseRestoreRouter(MethodView):
    def __init__(self) -> None:
        self.course_manager = CourseManager()

    @course_router.response(status_code=200)
    def post(self, course_id):
        """Restore an archived course (supervisor only)"""
        requester_id = request.args.get('requester_id', type=str)
        if not requester_id:
            return {"message": "requester_id parameter is required"}, 400
        return self.course_manager.restore_course(course_id, requester_id)

@course_router.route("/courses/department/<string:department_name>/delete")
class DepartmentCoursesDeletionRouter(MethodView):
    def __init__(self) -> None:
        self.course_manager = CourseManager()

    def delete(self, department_name):
        """Delete all courses belonging to a specific department (supervisor only)"""
        requester_id = request.args.get('requester_id', type=str)
        dry_run = request.args.get('dry_run', 'false', type=str).lower() == 'true'
        
        if not requester_id:
            return {"message": "requester_id parameter is required"}, 400
            
        return self.course_manager.delete_department_courses(department_name, requester_id, dry_run)

@course_router.route("/courses/<string:course_id>/enrollments")
class CourseEnrollmentRouter(MethodView):
    def __init__(self) -> None:
        self.course_manager = CourseManager()

    @course_router.arguments(schema=EnrollmentSchema, location='json')
    @course_router.response(status_code=201)
    def post(self, payload, course_id):
        """Enroll a student in a course"""
        return self.course_manager.enroll_student(
            course_id,
            payload.get('student_id'),
            payload.get('requester_id'),
            payload.get('requester_type')
        )

    @course_router.response(status_code=200)
    def delete(self, course_id):
        """Withdraw a student from a course"""
        student_id = request.args.get('student_id', type=str)
        requester_id = request.args.get('requester_id', type=str)
        requester_type = request.args.get('requester_type', type=str)
        
        if not all([student_id, requester_id, requester_type]):
            return {"message": "student_id, requester_id and requester_type parameters are required"}, 400
            
        return self.course_manager.withdraw_student(
            course_id,
            student_id,
            requester_id,
            requester_type
        )

@course_router.route("/courses/<string:course_id>/progress/<string:student_id>")
class CourseProgressRouter(MethodView):
    def __init__(self) -> None:
        self.course_manager = CourseManager()

    @course_router.response(status_code=200, schema=CourseProgressSchema)
    def get(self, course_id, student_id):
        """Get student progress in a course"""
        requester_id = request.args.get('requester_id', type=str)
        requester_type = request.args.get('requester_type', type=str)
        
        if not requester_id or not requester_type:
            return {"message": "requester_id and requester_type parameters are required"}, 400
            
        return self.course_manager.get_course_progress(
            course_id,
            student_id,
            requester_id,
            requester_type
        )

@course_router.route("/assign/tutor/<string:tutor_id>/<string:course_id>/progress/supervisor/<string:supervisor_id>")
class CourseProgressRouter(MethodView):
    def __init__(self) -> None:
        self.course_manager = CourseManager()

    @course_router.response(status_code=200, schema=CourseProgressSchema)
    def post(self,tutor_id, course_id, supervisor_id):
        """Get student progress in a course"""
        payload = request.get_json()
        
        return self.course_manager.assign_tutor_to_course(
            course_id=course_id,
            tutor_id=tutor_id,
            requester_id=supervisor_id,
            is_primary=payload['is_primary']
        )


@course_router.route("/courses/<string:course_id>/analytics")
class CourseAnalyticsRouter(MethodView):
    def __init__(self) -> None:
        self.course_manager = CourseManager()

    def get(self, course_id):
        """Get course analytics (supervisor only)"""
        requester_id = request.args.get('requester_id', type=str)
        if not requester_id:
            return {"message": "requester_id parameter is required"}, 400
        return self.course_manager.get_course_analytics(course_id, requester_id)

@course_router.route("/courses/assign-supervisor")
class CourseSupervisorAssignmentRouter(MethodView):
    def __init__(self) -> None:
        self.course_manager = CourseManager()

    def post(self):
        """Assign a supervisor to a course (supervisor can assign themselves)"""
        payload = request.get_json()
        course_id = payload.get('course_id')
        supervisor_id = payload.get('supervisor_id')
        requester_id = payload.get('requester_id')
        
        if not all([course_id, supervisor_id, requester_id]):
            return {"message": "course_id, supervisor_id, and requester_id are required"}, 400
            
        return self.course_manager.assign_supervisor_to_course(
            course_id=course_id,
            supervisor_id=supervisor_id,
            requester_id=requester_id
        )

@course_router.route("/courses/supervisor-teaching")
class SupervisorTeachingCoursesRouter(MethodView):
    def __init__(self) -> None:
        self.course_manager = CourseManager()

    def get(self):
        """Get courses where supervisor is teaching (based on supervisor_course_association)"""
        supervisor_id = request.args.get('supervisor_id', type=str)
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        search = request.args.get('search', '', type=str)
        status_filter = request.args.get('status', 'all', type=str)
        
        if not supervisor_id:
            return {"message": "supervisor_id parameter is required", "success": False}, 400
            
        return self.course_manager.get_supervisor_teaching_courses(
            supervisor_id, page, per_page, search, status_filter
        )

@course_router.route("/courses/<string:course_id>/unclaim-supervisor")
class UnclaimSupervisorFromCourseRouter(MethodView):
    def __init__(self) -> None:
        self.course_manager = CourseManager()

    def delete(self, course_id):
        """Remove supervisor from teaching a course (unclaim)"""
        payload = request.get_json()
        supervisor_id = payload.get('supervisor_id')
        requester_id = payload.get('requester_id')
        
        if not all([supervisor_id, requester_id]):
            return {"message": "supervisor_id and requester_id are required", "success": False}, 400
            
        return self.course_manager.unclaim_supervisor_from_course(
            course_id, supervisor_id, requester_id
        )

@course_router.route("/courses/<string:course_id>/can-claim")
class CourseClaimabilityRouter(MethodView):
    def __init__(self) -> None:
        self.course_manager = CourseManager()

    def get(self, course_id):
        """Check if a supervisor can claim a specific course"""
        supervisor_id = request.args.get('supervisor_id')
        
        if not supervisor_id:
            return {"message": "supervisor_id parameter is required"}, 400
            
        return self.course_manager.can_supervisor_claim_course(course_id, supervisor_id)