"""
Institute Admin routes - filtered by logged-in user's institute_id
"""
from flask import Blueprint, request, jsonify
from sqlalchemy import func, or_

from config import db
from models.user import Admin, Courses, User, Instructor
from models.institute import Institute, InstituteMember, Enrollment, LiveClass
from utils.decorators import token_required

institute_bp = Blueprint('institute', __name__, url_prefix='/api/institute')


@institute_bp.route('/my-institute', methods=['GET'])
@token_required
def get_my_institute(current_user, user_role, institute_id, instructor_id):
    """Get the institute that the current user manages"""
    # Only allow institute admins and superadmins
    if user_role not in ['superadmin', 'institute_admin', 'institute_owner']:
        return jsonify({'error': 'Access denied'}), 403
        
    try:
        institute = None
        
        # Use institute_id from token/user
        if institute_id:
            institute = db.session.get(Institute, institute_id)
        
        # For superadmin without specific institute, we are in "Global" mode
        is_global_mode = False
        if not institute and user_role == 'superadmin':
            is_global_mode = True
            # Create a mock institute object to satisfy the frontend
            class MockInstitute:
                def __init__(self):
                    self.id = 0
                    self.name = "Global (All Institutes)"
                    self.slug = "global"
                    
                def to_dict(self):
                    return {
                        'id': self.id,
                        'name': self.name,
                        'slug': self.slug
                    }
            institute = MockInstitute()
        
        if not institute:
            return jsonify({'error': 'No institute found. Please contact admin to link your account.'}), 404
        
        # Get statistics for this institute
        course_query = Courses.query
        instructor_query = Instructor.query
        enrollment_query = Enrollment.query
        user_query = User.query
        revenue_query = db.session.query(func.sum(Enrollment.payment_amount))
        
        if institute_id:
            course_query = course_query.filter_by(institute_id=institute_id)
            instructor_query = instructor_query.filter_by(institute_id=institute_id)
            enrollment_query = enrollment_query.join(Courses, Enrollment.course_id == Courses.id).filter(Courses.institute_id == institute_id)
            user_query = user_query.filter(User.id.in_(
                db.session.query(Enrollment.user_id).join(Courses, Enrollment.course_id == Courses.id).filter(Courses.institute_id == institute_id)
            ))
            revenue_query = revenue_query.join(Courses, Enrollment.course_id == Courses.id).filter(Courses.institute_id == institute_id)
            
        total_courses = course_query.count()
        total_instructors = instructor_query.count()
        total_enrollments = enrollment_query.count()
        total_students = user_query.count()
        total_revenue = revenue_query.scalar() or 0
        
        # Get recent enrollments
        recent_enrollments_query = db.session.query(
            Enrollment, User, Courses
        ).select_from(
            Enrollment
        ).join(
            User, Enrollment.user_id == User.id
        ).join(
            Courses, Enrollment.course_id == Courses.id
        )
        
        if institute_id:
            recent_enrollments_query = recent_enrollments_query.filter(Courses.institute_id == institute_id)
            
        recent_enrollments = recent_enrollments_query.order_by(
            Enrollment.enrolled_at.desc()
        ).limit(5).all()

        recent_enrollments_data = [{
            'id': e.id,
            'user_name': u.fullname,
            'user_image': u.profile_img_url,
            'course_title': c.title,
            'enrolled_at': e.enrolled_at.isoformat() if e.enrolled_at else None,
            'payment_status': e.payment_status
        } for e, u, c in recent_enrollments]

        # Get upcoming live classes
        from datetime import datetime
        upcoming_classes = LiveClass.query.filter(
            LiveClass.scheduled_start_time >= datetime.now(),
            LiveClass.status.in_(['scheduled', 'live'])
        ).order_by(
            LiveClass.scheduled_start_time.asc()
        ).limit(5).all()

        upcoming_classes_data = [{
            'id': lc.id,
            'title': lc.title,
            'scheduled_start_time': lc.scheduled_start_time.isoformat() if lc.scheduled_start_time else None,
            'duration_minutes': lc._calculate_duration() or 60,
            'status': lc.status,
            'max_participants': lc.max_participants
        } for lc in upcoming_classes]
        
        # Apply global fetch restrictions correctly
        
        return jsonify({
            'institute': institute.to_dict(),
            'stats': {
                'totalCourses': total_courses,
                'totalInstructors': total_instructors,
                'totalEnrollments': total_enrollments,
                'totalRevenue': float(total_revenue),
                'activeStudents': total_students,
                'pendingEnrollments': Enrollment.query.filter_by(payment_status='pending').count()
            },
            'recentEnrollments': recent_enrollments_data,
            'upcomingClasses': upcoming_classes_data
        }), 200
    except Exception as e:
        import traceback
        traceback.print_exc()
        return jsonify({'error': str(e)}), 500


@institute_bp.route('/courses', methods=['POST'])
@token_required
def get_institute_courses(current_user, user_role, institute_id, instructor_id):
    """Get courses - filtered by institute for institute admins, by instructor for instructors"""
    data = request.get_json() or {}
    search_query = data.get('query', '')
    
    try:
        query = Courses.query
        
        # Filter by instructor for instructor role
        if user_role in ['instructor', 'teacher'] and instructor_id:
            query = query.filter_by(instructor_id=instructor_id)
        elif user_role in ['instructor', 'teacher'] and hasattr(current_user, 'name'):
            # Fallback: filter by name
            query = query.filter(Courses.instructor_name == current_user.name)
        
        if institute_id:
            query = query.filter_by(institute_id=institute_id)
        
        # Apply search filter
        if search_query:
            query = query.filter(Courses.title.ilike(f'%{search_query}%'))
        
        courses = query.all()
        
        output = []
        for course in courses:
            enrollment_count = Enrollment.query.filter_by(course_id=course.id).count()
            
            output.append({
                'id': course.id,
                'title': course.title,
                'description': course.description,
                'image_url': course.image_url,
                'price': float(course.price) if course.price else 0,
                'final_price': float(course.final_price) if course.final_price else 0,
                'status': course.status or 'draft',
                'enrollments_count': enrollment_count,
                'instructor_name': course.instructor_name,
                'instructor_id': course.instructor_id,
                'created_at': course.created_at.isoformat() if course.created_at else None
            })
        
        return jsonify({'courses': output}), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@institute_bp.route('/instructors', methods=['POST'])
@token_required
def get_institute_instructors(current_user, user_role, institute_id, instructor_id):
    """Get instructors for the institute"""
    data = request.get_json() or {}
    search_query = data.get('query', '')
    
    # Only allow institute admins and superadmins
    if user_role not in ['superadmin', 'institute_admin', 'institute_owner']:
        return jsonify({'error': 'Access denied'}), 403
    
    try:
        query = Instructor.query
        
        if search_query:
            query = query.filter(
                or_(
                    Instructor.name.ilike(f'%{search_query}%'),
                    Instructor.bio.ilike(f'%{search_query}%')
                )
            )
        
        if institute_id:
            query = query.filter_by(institute_id=institute_id)
        
        instructors = query.limit(50).all()
        
        output = []
        for instructor in instructors:
            course_count = Courses.query.filter_by(instructor_id=instructor.id).count()
            
            output.append({
                'id': instructor.id,
                'user_id': instructor.user_id,
                'name': instructor.name,
                'bio': instructor.bio,
                'profile_image_url': instructor.profile_image_url,
                'specializations': instructor.specializations,
                'qualifications': instructor.qualifications,
                'experience_years': instructor.experience_years or 0,
                'hourly_rate': float(instructor.hourly_rate) if instructor.hourly_rate else 0.0,
                'availability': instructor.availability,
                'linkedin_url': instructor.linkedin_url,
                'github_url': instructor.github_url,
                'portfolio_url': instructor.portfolio_url,
                'status': instructor.status or 'active',
                'is_featured': instructor.is_featured,
                'total_courses': course_count,
                'total_students': 0,
                'rating': float(instructor.rating) if instructor.rating else 0.0
            })
        
        return jsonify({'instructors': output}), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@institute_bp.route('/instructors/<int:instructor_id>', methods=['GET'])
@token_required
def get_instructor_details(current_user, user_role, institute_id, req_instructor_id, instructor_id):
    """Get single instructor details"""
    if user_role not in ['superadmin', 'institute_admin', 'institute_owner']:
        return jsonify({'error': 'Access denied'}), 403
    
    try:
        instructor = db.session.get(Instructor, instructor_id)
        if not instructor:
            return jsonify({'error': 'Instructor not found'}), 404
            
        course_count = Courses.query.filter_by(instructor_id=instructor.id).count()
        
        return jsonify({
            'instructor': {
                'id': instructor.id,
                'user_id': instructor.user_id,
                'name': instructor.name,
                'bio': instructor.bio,
                'profile_image_url': instructor.profile_image_url,
                'specializations': instructor.specializations,
                'qualifications': instructor.qualifications,
                'experience_years': instructor.experience_years or 0,
                'hourly_rate': float(instructor.hourly_rate) if instructor.hourly_rate else 0.0,
                'availability': instructor.availability,
                'linkedin_url': instructor.linkedin_url,
                'github_url': instructor.github_url,
                'portfolio_url': instructor.portfolio_url,
                'status': instructor.status or 'active',
                'is_featured': instructor.is_featured,
                'total_courses': course_count,
                'total_students': 0,
                'rating': float(instructor.rating) if instructor.rating else 0.0
            }
        }), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@institute_bp.route('/instructors/add', methods=['POST'])
@token_required
def add_instructor(current_user, user_role, institute_id, req_instructor_id):
    """Add a new instructor"""
    if user_role not in ['superadmin', 'institute_admin', 'institute_owner']:
        return jsonify({'error': 'Access denied'}), 403
    
    data = request.get_json()
    if not data or not data.get('name'):
        return jsonify({'error': 'Name is required'}), 400
        
    try:
        new_instructor = Instructor(
            institute_id=institute_id,
            user_id=data.get('user_id'),
            name=data.get('name'),
            bio=data.get('bio'),
            profile_image_url=data.get('profile_image_url'),
            specializations=data.get('specializations'),
            qualifications=data.get('qualifications'),
            experience_years=data.get('experience_years', 0),
            hourly_rate=data.get('hourly_rate', 0.0),
            availability=data.get('availability'),
            linkedin_url=data.get('linkedin_url'),
            github_url=data.get('github_url'),
            portfolio_url=data.get('portfolio_url'),
            status=data.get('status', 'active'),
            is_featured=data.get('is_featured', False)
        )
        
        db.session.add(new_instructor)
        db.session.commit()
        
        return jsonify({'message': 'Instructor added successfully', 'id': new_instructor.id}), 201
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@institute_bp.route('/instructors/<int:instructor_id>', methods=['PUT'])
@token_required
def update_instructor(current_user, user_role, institute_id, req_instructor_id, instructor_id):
    """Update an existing instructor"""
    if user_role not in ['superadmin', 'institute_admin', 'institute_owner']:
        return jsonify({'error': 'Access denied'}), 403
    
    data = request.get_json()
    if not data:
        return jsonify({'error': 'No data provided'}), 400
        
    try:
        instructor = db.session.get(Instructor, instructor_id)
        if not instructor:
            return jsonify({'error': 'Instructor not found'}), 404
            
        updatable_fields = [
            'name', 'bio', 'profile_image_url', 'specializations', 
            'qualifications', 'experience_years', 'hourly_rate', 
            'availability', 'linkedin_url', 'github_url', 
            'portfolio_url', 'status', 'is_featured', 'user_id'
        ]
        
        for field in updatable_fields:
            if field in data:
                setattr(instructor, field, data[field])
                
        db.session.commit()
        return jsonify({'message': 'Instructor updated successfully'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@institute_bp.route('/instructors/<int:instructor_id>', methods=['DELETE'])
@token_required
def delete_instructor(current_user, user_role, institute_id, req_instructor_id, instructor_id):
    """Remove an instructor"""
    if user_role not in ['superadmin', 'institute_admin', 'institute_owner']:
        return jsonify({'error': 'Access denied'}), 403
        
    try:
        instructor = db.session.get(Instructor, instructor_id)
        if not instructor:
            return jsonify({'error': 'Instructor not found'}), 404
            
        db.session.delete(instructor)
        db.session.commit()
        return jsonify({'message': 'Instructor removed successfully'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@institute_bp.route('/students', methods=['POST'])
@token_required
def get_institute_students(current_user, user_role, institute_id, instructor_id):
    """Get students enrolled in institute courses"""
    data = request.get_json() or {}
    search_query = data.get('query', '')
    
    # Only allow institute admins and superadmins
    if user_role not in ['superadmin', 'institute_admin', 'institute_owner']:
        return jsonify({'error': 'Access denied'}), 403
    
    try:
        query = User.query
        
        if institute_id:
            query = query.filter(User.id.in_(
                db.session.query(Enrollment.user_id)
                .join(Courses, Enrollment.course_id == Courses.id)
                .filter(Courses.institute_id == institute_id)
            ))

        if search_query:
            query = query.filter(
                or_(
                    User.fullname.ilike(f'%{search_query}%'),
                    User.email.ilike(f'%{search_query}%')
                )
            )
        
        students = query.limit(50).all()
        
        output = []
        for student in students:
            enrollment_count = Enrollment.query.filter_by(user_id=student.id).count()
            completed_count = Enrollment.query.filter_by(
                user_id=student.id, 
                is_completed=True
            ).count()
            
            first_enrollment = Enrollment.query.filter_by(user_id=student.id).order_by(
                Enrollment.enrolled_at.asc()
            ).first()
            
            output.append({
                'id': student.id,
                'user_id': student.id,
                'name': student.fullname,
                'email': student.email,
                'profile_image_url': student.profile_img_url,
                'enrolled_courses': enrollment_count,
                'completed_courses': completed_count,
                'enrollment_date': first_enrollment.enrolled_at.isoformat() if first_enrollment and first_enrollment.enrolled_at else None,
                'last_activity': None
            })
        
        return jsonify({'students': output}), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@institute_bp.route('/live-classes', methods=['POST'])
@token_required
def get_institute_live_classes(current_user, user_role, institute_id, instructor_id):
    """Get live classes - filtered by instructor for instructor role"""
    data = request.get_json() or {}
    status_filter = data.get('status')
    
    try:
        query = LiveClass.query
        
        # Filter by instructor for instructor role
        if user_role in ['instructor', 'teacher'] and instructor_id:
            query = query.filter_by(instructor_id=instructor_id)
        
        # Filter by institute
        if institute_id and user_role not in ['superadmin']:
            query = query.filter_by(institute_id=institute_id)
        
        if status_filter and status_filter != 'all':
            query = query.filter_by(status=status_filter)
        
        live_classes = query.order_by(LiveClass.scheduled_start_time.desc()).limit(50).all()
        
        output = []
        for lc in live_classes:
            course_title = None
            if lc.course_id:
                course = db.session.get(Courses, lc.course_id)
                if course:
                    course_title = course.title
            
            instructor_name = None
            if lc.instructor_id:
                instructor = db.session.get(Instructor, lc.instructor_id)
                if instructor:
                    instructor_name = instructor.name
            
            output.append({
                'id': lc.id,
                'title': lc.title,
                'description': lc.description,
                'course_id': lc.course_id,
                'course_title': course_title,
                'instructor_name': instructor_name,
                'scheduled_at': lc.scheduled_start_time.isoformat() if lc.scheduled_start_time else None,
                'scheduled_end_time': lc.scheduled_end_time.isoformat() if lc.scheduled_end_time else None,
                'meeting_url': f"https://meet.jit.si/{lc.jitsi_room_name}" if lc.jitsi_room_name else None,
                'status': lc.status or 'scheduled',
                'max_participants': lc.max_participants,
                'stream_type': lc.stream_type or 'jitsi',
                'is_public': lc.is_public
            })
        
        return jsonify({'live_classes': output}), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@institute_bp.route('/analytics', methods=['POST'])
@token_required
def get_institute_analytics(current_user, user_role, institute_id, instructor_id):
    """Get analytics for the institute"""
    data = request.get_json() or {}
    period = data.get('period', 'month')
    
    # Only allow institute admins and superadmins
    if user_role not in ['superadmin', 'institute_admin', 'institute_owner']:
        return jsonify({'error': 'Access denied'}), 403
    
    try:
        # Get real statistics
        enrollment_query = Enrollment.query
        user_query = User.query
        revenue_query = db.session.query(func.sum(Enrollment.payment_amount))
        
        top_courses_query = db.session.query(
            Courses.title,
            func.count(Enrollment.id).label('enrollments'),
            func.sum(Enrollment.payment_amount).label('revenue')
        ).join(
            Enrollment, Enrollment.course_id == Courses.id
        )
        
        if institute_id:
            enrollment_query = enrollment_query.join(Courses, Enrollment.course_id == Courses.id).filter(Courses.institute_id == institute_id)
            user_query = user_query.filter(User.id.in_(
                db.session.query(Enrollment.user_id).join(Courses, Enrollment.course_id == Courses.id).filter(Courses.institute_id == institute_id)
            ))
            revenue_query = revenue_query.join(Courses, Enrollment.course_id == Courses.id).filter(Courses.institute_id == institute_id)
            top_courses_query = top_courses_query.filter(Courses.institute_id == institute_id)
            
        total_enrollments = enrollment_query.count()
        total_revenue = revenue_query.scalar() or 0
        active_students = user_query.count()
        completed_enrollments = enrollment_query.filter(Enrollment.is_completed == True).count()
        
        # Get top courses by enrollment
        top_courses_query = top_courses_query.group_by(Courses.id).order_by(func.count(Enrollment.id).desc()).limit(5).all()
        
        top_courses = []
        for course in top_courses_query:
            top_courses.append({
                'title': course.title,
                'enrollments': course.enrollments or 0,
                'revenue': float(course.revenue) if course.revenue else 0
            })
        
        return jsonify({
            'analytics': {
                'totalEnrollments': total_enrollments,
                'totalRevenue': float(total_revenue),
                'activeStudents': active_students,
                'completedCourses': completed_enrollments,
                'averageRating': 4.5,
                'monthlyEnrollments': [],
                'topCourses': top_courses,
                'recentActivity': []
            }
        }), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500


# ==========================================
# CUSTOM DOMAIN MANAGEMENT
# ==========================================

@institute_bp.route('/set-custom-domain', methods=['POST'])
@token_required
def set_custom_domain(current_user, user_role, institute_id, instructor_id):
    """Set a custom domain for the institute"""
    if user_role not in ['superadmin', 'institute_admin', 'institute_owner']:
        return jsonify({'message': 'Unauthorized'}), 403
    if not institute_id:
        return jsonify({'message': 'Institute ID required'}), 400

    data = request.get_json()
    domain = data.get('domain', '').strip().lower()
    if not domain:
        return jsonify({'message': 'Domain is required'}), 400

    try:
        institute = Institute.query.get(institute_id)
        if not institute:
            return jsonify({'message': 'Institute not found'}), 404

        # Check domain not already taken
        existing = Institute.query.filter(
            Institute.custom_domain == domain,
            Institute.id != institute_id
        ).first()
        if existing:
            return jsonify({'message': 'This domain is already in use by another institute'}), 409

        import uuid
        institute.custom_domain = domain
        institute.domain_verified = False
        institute.domain_verification_code = f'ashlya-verify-{uuid.uuid4().hex[:16]}'
        db.session.commit()

        return jsonify({
            'message': 'Custom domain set. Please configure DNS records and verify.',
            'domain': domain,
            'verification_code': institute.domain_verification_code
        }), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@institute_bp.route('/verify-custom-domain', methods=['POST'])
@token_required
def verify_custom_domain(current_user, user_role, institute_id, instructor_id):
    """Verify custom domain DNS configuration"""
    if user_role not in ['superadmin', 'institute_admin', 'institute_owner']:
        return jsonify({'message': 'Unauthorized'}), 403
    if not institute_id:
        return jsonify({'message': 'Institute ID required'}), 400

    try:
        institute = Institute.query.get(institute_id)
        if not institute:
            return jsonify({'message': 'Institute not found'}), 404
        if not institute.custom_domain:
            return jsonify({'message': 'No custom domain configured'}), 400

        # Try DNS lookup for verification TXT record
        import subprocess
        try:
            result = subprocess.run(
                ['dig', '+short', 'TXT', f'_ashlya-verify.{institute.custom_domain}'],
                capture_output=True, text=True, timeout=10
            )
            txt_records = result.stdout.strip().replace('"', '')
            if institute.domain_verification_code and institute.domain_verification_code in txt_records:
                institute.domain_verified = True
                db.session.commit()
                return jsonify({'verified': True, 'message': 'Domain verified successfully!'}), 200
        except Exception:
            pass

        # Fallback: also check CNAME
        try:
            result = subprocess.run(
                ['dig', '+short', 'CNAME', institute.custom_domain],
                capture_output=True, text=True, timeout=10
            )
            cname = result.stdout.strip().rstrip('.')
            if 'ashlya.com' in cname:
                institute.domain_verified = True
                db.session.commit()
                return jsonify({'verified': True, 'message': 'Domain verified via CNAME!'}), 200
        except Exception:
            pass

        return jsonify({
            'verified': False,
            'message': 'DNS records not found yet. Please ensure records are configured and try again after propagation (up to 48h).'
        }), 200

    except Exception as e:
        return jsonify({'error': str(e)}), 500
