from flask.views import MethodView
from flask_smorest import Blueprint
from src.models.models import Supervisor
from src.views.supervisors.utils import SupervisorManager
from flask import request
from src.models.schema import (
    SupervisorSchema,
    TimetableSchema,
    TutorAvailabilitySchema,
)

supervisor_router = Blueprint("Supervisor Management Routes", __name__, description="Operations on supervisors")

@supervisor_router.route("/supervisors")
class SupervisorRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200, schema=SupervisorSchema(many=True))
    def get(self):
        """Get all supervisors with pagination"""
        return self.supervisor_manager.fetchAll()

@supervisor_router.route("/supervisors/<string:supervisor_id>")
class SupervisorDetailRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200, schema=SupervisorSchema)
    def get(self, supervisor_id):
        """Get supervisor details including managed tutors and courses"""
        return self.supervisor_manager.get_supervisor_details(supervisor_id)

    @supervisor_router.response(status_code=200)
    def put(self, supervisor_id):
        """Update supervisor information"""
        payload = request.get_json()
        return self.supervisor_manager.update(supervisor_id, payload)

    @supervisor_router.response(status_code=200)
    def delete(self, supervisor_id):
        """Delete supervisor and all associated relations"""
        return self.supervisor_manager.delete(supervisor_id)

@supervisor_router.route("/supervisors/bulk-delete")
class SupervisorBulkDeleteRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def post(self):
        """Delete multiple supervisors and their associated relations"""
        payload = request.get_json()
        supervisor_ids = payload.get('supervisor_ids', [])
        
        if not supervisor_ids:
            return {
                'success': False,
                'data': "supervisor_ids array is required",
                'status_code': 400
            }
        
        return self.supervisor_manager.delete_multiple_supervisors(supervisor_ids)

@supervisor_router.route("/supervisors/<string:supervisor_id>/deletion-impact")
class SupervisorDeletionImpactRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get information about what will be affected when deleting a supervisor"""
        return self.supervisor_manager.get_supervisor_deletion_impact(supervisor_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/departments/<string:department_id>")
class SupervisorDepartmentRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def delete(self, supervisor_id, department_id):
        """Delete a specific department from a supervisor"""
        return self.supervisor_manager.delete_supervisor_department(supervisor_id, department_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/departments/remove-by-name")
class SupervisorDepartmentRemoveByNameRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def post(self, supervisor_id):
        """Remove a department from a supervisor by department name"""
        payload = request.get_json()
        department_name = payload.get('department_name')
        
        if not department_name:
            return {
                'success': False,
                'data': "Department name is required",
                'status_code': 400
            }
        
        return self.supervisor_manager.remove_department_by_name(supervisor_id, department_name)

@supervisor_router.route("/supervisors/<string:supervisor_id>/departments/bulk-remove")
class SupervisorDepartmentBulkRemoveRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def post(self, supervisor_id):
        """Remove multiple departments from a supervisor"""
        payload = request.get_json()
        department_names = payload.get('department_names', [])
        
        if not department_names or not isinstance(department_names, list):
            return {
                'success': False,
                'data': "Department names list is required",
                'status_code': 400
            }
        
        return self.supervisor_manager.bulk_remove_departments(supervisor_id, department_names)

@supervisor_router.route("/supervisors/<string:supervisor_id>/department/stats")
class DepartmentStatsRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get comprehensive statistics for the supervisor's department"""
        return self.supervisor_manager.get_department_statistics(supervisor_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/students/<string:student_id>/stats")
class StudentStatsRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id, student_id):
        """Get detailed statistics for a specific student"""
        return self.supervisor_manager.get_student_statistics(supervisor_id, student_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/tutor-availability/approve/<string:availability_id>")
class TutorAvailabilityApprovalRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def post(self, supervisor_id, availability_id):
        """Approve or reject a tutor's availability request"""
        payload = request.get_json()
        return self.supervisor_manager.approve_tutor_availability(
            supervisor_id, 
            availability_id, 
            payload.get('approve', True),
            payload.get('notes')
        )

@supervisor_router.route("/supervisors/<string:supervisor_id>/availability/approve/<string:availability_id>")
class AvailabilityApprovalRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def post(self, supervisor_id, availability_id):
        """Approve a tutor's availability request (alternative route)"""
        return self.supervisor_manager.approve_tutor_availability(
            supervisor_id, 
            availability_id, 
            True,
            None
        )

@supervisor_router.route("/supervisors/<string:supervisor_id>/availability/reject/<string:availability_id>")
class AvailabilityRejectionRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def post(self, payload, supervisor_id, availability_id):
        """Reject a tutor's availability request"""
        reason = payload.get('reason', 'No reason provided')
        return self.supervisor_manager.approve_tutor_availability(
            supervisor_id, 
            availability_id, 
            False,
            reason
        )

@supervisor_router.route("/supervisors/<string:supervisor_id>/availability/<string:availability_id>")
class SupervisorAvailabilityUpdateRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.arguments(schema=TutorAvailabilitySchema, location='json')
    @supervisor_router.response(status_code=200)
    def put(self, payload, supervisor_id, availability_id):
        """Update a specific availability slot (supervisor route)"""
        return self.supervisor_manager.update_tutor_availability(supervisor_id, availability_id, payload)

@supervisor_router.route("/supervisors/<string:supervisor_id>/availability/bulk-edit")
class SupervisorBulkEditAvailabilityRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def put(self, supervisor_id):
        """Bulk edit availability slots for a specific tutor"""
        payload = request.get_json()
        return self.supervisor_manager.bulk_edit_tutor_availability(supervisor_id, payload)

@supervisor_router.route("/supervisors/<string:supervisor_id>/opening-sessions/<string:session_id>/send-reminders")
class SupervisorSendRemindersRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def post(self, supervisor_id, session_id):
        """Send email reminders to tutors for availability slots"""
        return self.supervisor_manager.send_availability_reminders(supervisor_id, session_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/tutor-availability/pending")
class PendingAvailabilityRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get tutor availability requests that need approval"""
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        return self.supervisor_manager.get_pending_approvals(supervisor_id, page, per_page)

@supervisor_router.route("/supervisors/<string:supervisor_id>/timetables")
class TimetableRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.arguments(schema=TimetableSchema, location='json')
    @supervisor_router.response(status_code=201)
    def post(self, payload, supervisor_id):
        """Generate a master timetable for the department"""
        return self.supervisor_manager.generate_timetable(supervisor_id, payload)

@supervisor_router.route("/supervisors/<string:supervisor_id>/timetables/<string:timetable_id>/approve")
class TimetableApprovalRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.arguments(schema=TimetableSchema, location='json')
    @supervisor_router.response(status_code=200)
    def post(self, payload, supervisor_id, timetable_id):
        """Approve or reject a timetable"""
        return self.supervisor_manager.approve_timetable(
            supervisor_id,
            timetable_id,
            payload.get('approve', True),
            payload.get('notes')
        )

@supervisor_router.route("/supervisors/<string:supervisor_id>/timetables/pending")
class PendingTimetableRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get timetables that need approval"""
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        return self.supervisor_manager.get_pending_timetables(supervisor_id, page, per_page)

@supervisor_router.route("/supervisors/<string:supervisor_id>/sessions/<string:session_id>/verify")
class SessionVerificationRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def post(self, supervisor_id, session_id):
        """Verify a completed teaching session"""
        payload = request.get_json()
        return self.supervisor_manager.verify_teaching_session(
            supervisor_id,
            session_id,
            payload.get('verify', True),
            payload.get('notes')
        )

@supervisor_router.route("/supervisors/<string:supervisor_id>/sessions/pending-verification")
class PendingVerificationRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get teaching sessions that need verification"""
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        return self.supervisor_manager.get_pending_verifications(supervisor_id, page, per_page)

@supervisor_router.route("/supervisors/<string:supervisor_id>/attendance/<string:attendance_id>/resolve-dispute")
class AttendanceDisputeResolutionRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def post(self, payload, supervisor_id, attendance_id):
        """Resolve an attendance dispute"""
        payload = request.get_json()
        return self.supervisor_manager.resolve_attendance_dispute(
            supervisor_id,
            attendance_id,
            payload
        )

@supervisor_router.route("/supervisors/<string:supervisor_id>/alerts/session-completion")
class SessionCompletionAlertsRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def post(self, supervisor_id):
        """Trigger session completion alerts (typically run by a scheduled job)"""
        return self.supervisor_manager.send_session_completion_alerts()

@supervisor_router.route("/supervisors/<string:supervisor_id>/timetables/approved")
class SupervisorApprovedTimetablesRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get approved timetables for a supervisor's department"""
        return self.supervisor_manager.get_approved_timetables_for_supervisor(supervisor_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/timetables/approved/by-speciality")
class SupervisorApprovedTimetablesBySpecialityRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get approved timetables for a supervisor's department, filtered by speciality"""
        speciality_id = request.args.get('speciality_id')
        return self.supervisor_manager.get_approved_timetables_for_supervisor_by_speciality(supervisor_id, speciality_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/timetable-blocks")
class SupervisorTimetableBlocksRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get timetable blocks for authenticated supervisor from approved timetables"""
        return self.supervisor_manager.get_supervisor_timetable_blocks(supervisor_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/tutors")
class SupervisorTutorsRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get tutors under supervisor - lightweight endpoint without analytics"""
        return self.supervisor_manager.get_supervisor_tutors_lightweight(supervisor_id)



@supervisor_router.route("/supervisors/<string:supervisor_id>/analytics")
class SupervisorAnalyticsRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get comprehensive course analytics for a supervisor"""
        return self.supervisor_manager.get_course_analytics_for_supervisor(supervisor_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/dashboard/stats")
class SupervisorDashboardStatsRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get comprehensive dashboard statistics for a supervisor"""
        return self.supervisor_manager.get_supervisor_dashboard_stats(supervisor_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/students")
class SupervisorStudentsRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get all students in the supervisor's department with comprehensive information"""
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        return self.supervisor_manager.get_department_students(supervisor_id, page, per_page)

@supervisor_router.route("/supervisors/<string:supervisor_id>/students/<string:student_id>/assign-speciality")
class SupervisorStudentSpecialityRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def post(self, supervisor_id, student_id):
        """Assign a student to a speciality"""
        payload = request.get_json()
        speciality_id = payload.get('speciality_id')
        term = payload.get('term')  # Optional term parameter
        return self.supervisor_manager.assign_student_to_speciality(supervisor_id, student_id, speciality_id, term)

@supervisor_router.route("/supervisors/<string:supervisor_id>/students/<string:student_id>/update")
class SupervisorStudentUpdateRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def put(self, supervisor_id, student_id):
        """Update student information"""
        payload = request.get_json()
        return self.supervisor_manager.update_student_info(supervisor_id, student_id, payload)

@supervisor_router.route("/supervisors/<string:supervisor_id>/department")
class SupervisorDepartmentRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get the supervisor's department information"""
        return self.supervisor_manager.get_supervisor_department(supervisor_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/tutor-analytics")
class SupervisorTutorAnalyticsRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get comprehensive tutor analytics for the supervisor's department"""
        return self.supervisor_manager.get_tutor_analytics(supervisor_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/tutor-analytics/summary")
class SupervisorTutorAnalyticsSummaryRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get tutor analytics summary with key metrics"""
        return self.supervisor_manager.get_tutor_analytics_summary(supervisor_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/tutor-analytics/performance")
class SupervisorTutorPerformanceAnalyticsRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get tutor performance analytics and trends"""
        return self.supervisor_manager.get_tutor_performance_analytics(supervisor_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/tutor-analytics/speciality-distribution")
class SupervisorTutorSpecialityDistributionRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get tutor distribution by speciality"""
        return self.supervisor_manager.get_tutor_speciality_distribution(supervisor_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/tutor-analytics/teaching-hours")
class SupervisorTutorTeachingHoursRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get tutor teaching hours analytics and trends"""
        return self.supervisor_manager.get_tutor_teaching_hours_analytics(supervisor_id)

@supervisor_router.route("/supervisors/<string:supervisor_id>/tutor-analytics/top-performers")
class SupervisorTopPerformersRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get top performing tutors in the department"""
        return self.supervisor_manager.get_top_performing_tutors(supervisor_id)

@supervisor_router.route("/admin/supervisors/workload")
class SupervisorWorkloadRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self):
        """Get supervisor workload data for all supervisors"""
        return self.supervisor_manager.get_supervisor_workload_data()

@supervisor_router.route("/user-management/supervisors/analytics")
class SupervisorAnalyticsRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self):
        """Get comprehensive analytics data for all supervisors"""
        return self.supervisor_manager.get_supervisor_analytics_data()

@supervisor_router.route("/user-management/supervisors/<string:supervisor_id>/analytics-detail")
class SupervisorAnalyticsDetailRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self, supervisor_id):
        """Get detailed analytics data for a specific supervisor"""
        return self.supervisor_manager.get_supervisor_detail_analytics(supervisor_id)

@supervisor_router.route("/user-management/supervisors/attendance")
class SupervisorAttendanceAnalyticsRouter(MethodView):
    def __init__(self) -> None:
        self.supervisor_manager = SupervisorManager()

    @supervisor_router.response(status_code=200)
    def get(self):
        """Get comprehensive attendance and verification analytics for all supervisors"""
        return self.supervisor_manager.get_supervisor_attendance_analytics()