"""
Extended Admin API Routes
Handles coupons, payments, notifications, reviews, pages, settings
"""
from flask import Blueprint, request, jsonify
from datetime import datetime
from config import db
from utils.decorators import token_required

extended_admin_bp = Blueprint('extended_admin', __name__, url_prefix='/api')


# ==========================================
# COUPON MANAGEMENT
# ==========================================

@extended_admin_bp.route('/coupons', methods=['GET'])
@token_required
def get_coupons(current_user, user_role, institute_id=None, instructor_id=None):
    """List all coupons"""
    from models.institute import Coupon
    try:
        query = Coupon.query
        if institute_id:
            query = query.filter_by(institute_id=institute_id)
        coupons = query.order_by(Coupon.created_at.desc()).all()
        return jsonify({'coupons': [c.to_dict() for c in coupons]}), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@extended_admin_bp.route('/coupons', methods=['POST'])
@token_required
def create_coupon(current_user, user_role, institute_id=None, instructor_id=None):
    """Create a new coupon"""
    from models.institute import Coupon
    data = request.get_json()
    try:
        coupon = Coupon(
            code=data['code'],
            name=data.get('name', data['code']),
            coupon_type=data.get('coupon_type', 'balance'),
            discount_value=data.get('discount_value', data.get('value', 0)),
            balance=data.get('balance', data.get('initial_balance', 0)),
            initial_balance=data.get('initial_balance', data.get('balance', 0)),
            min_purchase_amount=data.get('min_purchase_amount', data.get('min_purchase', 0)),
            max_discount_amount=data.get('max_discount_amount', data.get('max_discount')),
            usage_limit=data.get('usage_limit'),
            valid_until=datetime.strptime(data['valid_until'], '%Y-%m-%d') if data.get('valid_until') else (datetime.strptime(data['end_date'], '%Y-%m-%d') if data.get('end_date') else None),
            institute_id=institute_id,
            created_by=current_user.id if hasattr(current_user, 'id') else None,
        )
        db.session.add(coupon)
        db.session.commit()
        return jsonify({'message': 'Coupon created', 'coupon': coupon.to_dict()}), 201
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@extended_admin_bp.route('/coupons/<int:coupon_id>/toggle', methods=['PUT'])
@token_required
def toggle_coupon(current_user, user_role, coupon_id, institute_id=None, instructor_id=None):
    """Toggle coupon active status"""
    from models.institute import Coupon
    try:
        coupon = db.session.get(Coupon, coupon_id)
        if not coupon:
            return jsonify({'error': 'Coupon not found'}), 404
        coupon.is_active = not coupon.is_active
        db.session.commit()
        return jsonify({'message': 'Coupon toggled', 'is_active': coupon.is_active}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@extended_admin_bp.route('/coupons/<int:coupon_id>', methods=['DELETE'])
@token_required
def delete_coupon(current_user, user_role, coupon_id, institute_id=None, instructor_id=None):
    """Delete a coupon"""
    from models.institute import Coupon
    try:
        coupon = db.session.get(Coupon, coupon_id)
        if not coupon:
            return jsonify({'error': 'Coupon not found'}), 404
        db.session.delete(coupon)
        db.session.commit()
        return jsonify({'message': 'Coupon deleted'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


# ==========================================
# PAYMENT VERIFICATION
# ==========================================

@extended_admin_bp.route('/payments/admin/submissions', methods=['GET'])
@token_required
def get_payment_submissions(current_user, user_role, institute_id=None, instructor_id=None):
    """List payment submissions for verification"""
    from models.institute import PaymentSubmission, Enrollment
    from models.user import User, Courses
    status = request.args.get('status', 'pending')
    try:
        query = PaymentSubmission.query
        if institute_id:
            # Filter submissions by enrollments linked to courses in this institute
            query = query.filter(
                PaymentSubmission.enrollment_id.in_(
                    db.session.query(Enrollment.id)
                    .join(Courses, Enrollment.course_id == Courses.id)
                    .filter(Courses.institute_id == institute_id)
                ) | PaymentSubmission.enrollment_id.is_(None)
            )
        if status != 'all':
            query = query.filter_by(status=status)
        submissions = query.order_by(PaymentSubmission.submitted_at.desc()).all()
        results = []
        for sub in submissions:
            sub_dict = sub.to_dict()
            user = db.session.get(User, sub.user_id)
            if user:
                sub_dict['user_name'] = user.fullname
                sub_dict['user_email'] = user.email
            results.append(sub_dict)
        return jsonify({'submissions': results}), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@extended_admin_bp.route('/payments/admin/verify/<int:submission_id>', methods=['POST'])
@token_required
def verify_payment(current_user, user_role, submission_id, institute_id=None, instructor_id=None):
    """Verify or reject a payment submission"""
    from models.institute import PaymentSubmission, Enrollment
    data = request.get_json()
    action = data.get('action')
    try:
        submission = db.session.get(PaymentSubmission, submission_id)
        if not submission:
            return jsonify({'error': 'Submission not found'}), 404
        
        if action == 'verify':
            submission.status = 'verified'
            submission.verified_at = datetime.utcnow()
            submission.verified_by = current_user.id if hasattr(current_user, 'id') else None
            # Auto-approve enrollment if linked
            if submission.enrollment_id:
                enrollment = db.session.get(Enrollment, submission.enrollment_id)
                if enrollment:
                    enrollment.payment_status = 'completed'
        elif action == 'reject':
            submission.status = 'rejected'
            submission.rejection_reason = data.get('reason', '')
            submission.verified_at = datetime.utcnow()
        else:
            return jsonify({'error': 'Invalid action'}), 400
        
        db.session.commit()
        return jsonify({'message': f'Payment {action}ed'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


# ==========================================
# NOTIFICATIONS
# ==========================================

@extended_admin_bp.route('/notifications/send', methods=['POST'])
@token_required
def send_notification(current_user, user_role, institute_id=None, instructor_id=None):
    """Send push notification"""
    import requests as http_requests
    data = request.get_json()
    title = data.get('title')
    message = data.get('message')
    
    if not title or not message:
        return jsonify({'error': 'Title and message are required'}), 400
    
    try:
        # OneSignal integration
        onesignal_app_id = 'YOUR_ONESIGNAL_APP_ID'  # Should be from env
        onesignal_api_key = 'YOUR_ONESIGNAL_API_KEY'  # Should be from env
        
        payload = {
            'app_id': onesignal_app_id,
            'headings': {'en': title},
            'contents': {'en': message},
        }
        
        if data.get('image_url'):
            payload['big_picture'] = data['image_url']
        if data.get('action_url'):
            payload['url'] = data['action_url']
        
        if data.get('segments'):
            payload['included_segments'] = data['segments']
        elif data.get('user_ids'):
            payload['include_external_user_ids'] = data['user_ids']
        else:
            payload['included_segments'] = ['All']
        
        headers = {
            'Authorization': f'Basic {onesignal_api_key}',
            'Content-Type': 'application/json',
        }
        
        response = http_requests.post('https://onesignal.com/api/v1/notifications', json=payload, headers=headers)
        
        if response.status_code in [200, 201]:
            return jsonify({'message': 'Notification sent', 'details': response.json()}), 200
        else:
            return jsonify({'error': 'Failed to send', 'details': response.text}), 500
    except Exception as e:
        return jsonify({'error': str(e)}), 500


# ==========================================
# INSTITUTE REVIEWS
# ==========================================

@extended_admin_bp.route('/institute/reviews', methods=['GET'])
@token_required
def get_institute_reviews(current_user, user_role, institute_id=None, instructor_id=None):
    """List institute reviews"""
    from models.institute import InstituteReview
    from models.user import User
    status = request.args.get('status', 'pending')
    try:
        query = InstituteReview.query
        if institute_id:
            query = query.filter_by(institute_id=institute_id)
        if status != 'all':
            query = query.filter_by(status=status)
        reviews = query.order_by(InstituteReview.created_at.desc()).all()
        results = []
        for r in reviews:
            r_dict = r.to_dict()
            user = db.session.get(User, r.user_id)
            if user:
                r_dict['user_name'] = user.fullname
            results.append(r_dict)
        return jsonify({'reviews': results}), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@extended_admin_bp.route('/institute/reviews/<int:review_id>/moderate', methods=['PUT'])
@token_required
def moderate_review(current_user, user_role, review_id, institute_id=None, instructor_id=None):
    """Approve, reject, or feature a review"""
    from models.institute import InstituteReview
    data = request.get_json()
    action = data.get('action')
    try:
        review = db.session.get(InstituteReview, review_id)
        if not review:
            return jsonify({'error': 'Review not found'}), 404
        if action == 'approve':
            review.status = 'approved'
            review.moderated_by = current_user.id if hasattr(current_user, 'id') else None
            review.moderated_at = datetime.utcnow()
        elif action == 'reject':
            review.status = 'rejected'
            review.moderated_by = current_user.id if hasattr(current_user, 'id') else None
            review.moderated_at = datetime.utcnow()
        elif action == 'feature':
            review.is_featured = not review.is_featured
        db.session.commit()
        return jsonify({'message': f'Review {action}d'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


# ==========================================
# INSTITUTE SETTINGS
# ==========================================

@extended_admin_bp.route('/institute/settings', methods=['GET'])
@token_required
def get_institute_settings(current_user, user_role, institute_id=None, instructor_id=None):
    """Get institute settings"""
    from models.institute import InstituteSettings
    try:
        settings = InstituteSettings.query.filter_by(institute_id=institute_id).first()
        if settings:
            return jsonify({'settings': settings.to_dict()}), 200
        return jsonify({'settings': {}}), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@extended_admin_bp.route('/institute/settings', methods=['PUT'])
@token_required
def update_institute_settings(current_user, user_role, institute_id=None, instructor_id=None):
    """Update institute settings"""
    from models.institute import InstituteSettings
    data = request.get_json()
    try:
        settings = InstituteSettings.query.filter_by(institute_id=institute_id).first()
        if not settings:
            settings = InstituteSettings(institute_id=institute_id)
            db.session.add(settings)
        
        for key, value in data.items():
            if hasattr(settings, key) and key not in ('id', 'institute_id', 'created_at'):
                setattr(settings, key, value)
        
        db.session.commit()
        return jsonify({'message': 'Settings updated', 'settings': settings.to_dict()}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


# ==========================================
# INSTITUTE CUSTOM PAGES
# ==========================================

@extended_admin_bp.route('/institute/pages', methods=['GET'])
@token_required
def get_institute_pages(current_user, user_role, institute_id=None, instructor_id=None):
    """List custom pages"""
    from models.institute import InstitutePage
    try:
        query = InstitutePage.query
        if institute_id:
            query = query.filter_by(institute_id=institute_id)
        pages = query.order_by(InstitutePage.nav_order).all()
        return jsonify({'pages': [p.to_dict() for p in pages]}), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@extended_admin_bp.route('/institute/pages', methods=['POST'])
@token_required
def create_institute_page(current_user, user_role, institute_id=None, instructor_id=None):
    """Create a custom page"""
    from models.institute import InstitutePage
    data = request.get_json()
    try:
        page = InstitutePage(
            institute_id=institute_id,
            title=data['title'],
            slug=data.get('slug', data['title'].lower().replace(' ', '-')),
            content=data.get('content', ''),
            page_type=data.get('page_type', 'static'),
            is_published=data.get('is_published', False),
            show_in_nav=data.get('show_in_nav', False),
            meta_title=data.get('meta_title', ''),
        )
        db.session.add(page)
        db.session.commit()
        return jsonify({'message': 'Page created', 'page': page.to_dict()}), 201
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@extended_admin_bp.route('/institute/pages/<int:page_id>', methods=['PUT'])
@token_required
def update_institute_page(current_user, user_role, page_id, institute_id=None, instructor_id=None):
    """Update a custom page"""
    from models.institute import InstitutePage
    data = request.get_json()
    try:
        page = db.session.get(InstitutePage, page_id)
        if not page:
            return jsonify({'error': 'Page not found'}), 404
        for key, value in data.items():
            if hasattr(page, key) and key not in ('id', 'institute_id', 'created_at'):
                setattr(page, key, value)
        db.session.commit()
        return jsonify({'message': 'Page updated', 'page': page.to_dict()}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@extended_admin_bp.route('/institute/pages/<int:page_id>', methods=['DELETE'])
@token_required
def delete_institute_page(current_user, user_role, page_id, institute_id=None, instructor_id=None):
    """Delete a custom page"""
    from models.institute import InstitutePage
    try:
        page = db.session.get(InstitutePage, page_id)
        if not page:
            return jsonify({'error': 'Page not found'}), 404
        db.session.delete(page)
        db.session.commit()
        return jsonify({'message': 'Page deleted'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


# ==========================================
# BLOG MANAGEMENT
# ==========================================

@extended_admin_bp.route('/blog/posts', methods=['GET'])
@token_required
def get_blog_posts(current_user, user_role, institute_id=None, instructor_id=None):
    """List blog posts"""
    try:
        if institute_id:
            result = db.session.execute(db.text(
                "SELECT * FROM blog_posts WHERE institute_id = :institute_id ORDER BY created_at DESC LIMIT 50"
            ), {'institute_id': institute_id})
        else:
            result = db.session.execute(db.text(
                "SELECT * FROM blog_posts ORDER BY created_at DESC LIMIT 50"
            ))
        posts = []
        for row in result.mappings():
            posts.append(dict(row))
        return jsonify({'posts': posts}), 200
    except Exception as e:
        return jsonify({'posts': [], 'error': str(e)}), 200


@extended_admin_bp.route('/blog/posts', methods=['POST'])
@token_required
def create_blog_post(current_user, user_role, institute_id=None, instructor_id=None):
    """Create a blog post"""
    data = request.get_json()
    try:
        db.session.execute(db.text(
            """INSERT INTO blog_posts (title, slug, content, excerpt, image, category_id, 
               status, author_id, institute_id, created_at, updated_at)
               VALUES (:title, :slug, :content, :excerpt, :image, :category_id, 
               :status, :author_id, :institute_id, NOW(), NOW())"""
        ), {
            'title': data.get('title'),
            'slug': data.get('title', '').lower().replace(' ', '-'),
            'content': data.get('content', ''),
            'excerpt': data.get('excerpt', ''),
            'image': data.get('image', ''),
            'category_id': data.get('category_id'),
            'status': data.get('status', 'draft'),
            'author_id': current_user.id if hasattr(current_user, 'id') else None,
            'institute_id': institute_id,
        })
        db.session.commit()
        return jsonify({'message': 'Post created'}), 201
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@extended_admin_bp.route('/blog/posts/<int:post_id>', methods=['DELETE'])
@token_required
def delete_blog_post(current_user, user_role, post_id, institute_id=None, instructor_id=None):
    """Delete a blog post"""
    try:
        db.session.execute(db.text("DELETE FROM blog_posts WHERE id = :id"), {'id': post_id})
        db.session.commit()
        return jsonify({'message': 'Post deleted'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@extended_admin_bp.route('/blog/categories', methods=['GET'])
@token_required
def get_blog_categories(current_user, user_role, institute_id=None, instructor_id=None):
    """List blog categories"""
    try:
        result = db.session.execute(db.text("SELECT * FROM blog_categories ORDER BY name"))
        categories = [dict(row) for row in result.mappings()]
        return jsonify({'categories': categories}), 200
    except Exception as e:
        return jsonify({'categories': [], 'error': str(e)}), 200


@extended_admin_bp.route('/blog/categories', methods=['POST'])
@token_required
def create_blog_category(current_user, user_role, institute_id=None, instructor_id=None):
    """Create a blog category"""
    data = request.get_json()
    try:
        db.session.execute(db.text(
            "INSERT INTO blog_categories (name, slug, created_at) VALUES (:name, :slug, NOW())"
        ), {
            'name': data.get('name'),
            'slug': data.get('name', '').lower().replace(' ', '-'),
        })
        db.session.commit()
        return jsonify({'message': 'Category created'}), 201
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


# ==========================================
# USER MANAGEMENT (Roles & Verification)
# ==========================================

@extended_admin_bp.route('/users/update/<int:target_user_id>', methods=['PUT'])
@token_required
def update_user_admin(current_user, user_role, target_user_id, institute_id=None, instructor_id=None):
    """Update user details (roles, verification, institute)"""
    from models.user import User
    
    # Check permissions
    if user_role not in ['superadmin', 'institute_admin', 'institute_owner']:
        return jsonify({'error': 'Unauthorized'}), 403
        
    data = request.get_json()
    try:
        user = db.session.get(User, target_user_id)
        if not user:
            return jsonify({'error': 'User not found'}), 404
            
        # Ensure institute admins only modify their own users, unless they are superadmin
        if user_role != 'superadmin' and user.institute_id != institute_id and user.institute_id is not None:
            return jsonify({'error': 'Unauthorized to modify this user'}), 403

        # Update allowed fields
        if 'user_type' in data:
            user.user_type = data['user_type']
        if 'institute_id' in data and user_role == 'superadmin':
            user.institute_id = data['institute_id']
        if 'is_verified' in data:
            user.is_verified = bool(data['is_verified'])

        return jsonify({'message': 'User updated successfully', 'user': user.to_dict()}), 200
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500
