"""
Admin Routes for RateRight Australian Construction Marketplace
Provides super admin endpoints for system oversight and management
"""
from flask import request, jsonify, render_template
from flask_login import current_user
from datetime import datetime, timedelta
from sqlalchemy import func, or_, and_

from . import admin_bp
from ...extensions import db
from ...models import (
    User, Job, Application, Contract, Payment, Invoice,
    Rating, Category, AuditLog, WHSAssessment, Dispute
)
from ...models.notification import NotificationPreference
from ...models.message import Message
from ...models.file_upload import FileUpload
from ...utils.auth_decorators import super_admin_required, admin_api_key_required
from ...services.sms_service import SMSService


@admin_bp.route('/dashboard', methods=['GET'])
@super_admin_required
def admin_dashboard():
    """
    Admin dashboard overview with system statistics
    Matches the style of worker/contractor dashboards
    """
    try:
        # System-wide statistics
        stats = {
            'total_users': User.query.count(),
            'active_users': User.query.filter_by(is_active=True).count(),
            'total_workers': User.query.filter_by(role='worker').count(),
            'total_contractors': User.query.filter_by(role='contractor').count(),
            'total_jobs': Job.query.count(),
            'open_jobs': Job.query.filter_by(status='open').count(),
            'active_contracts': Contract.query.filter(
                Contract.status.in_(['active', 'pending_agreement', 'contractor_signed', 'worker_signed'])
            ).count(),
            'total_payments': Payment.query.count(),
            'pending_disputes': Dispute.query.filter_by(status='open').count(),
        }
        
        # Recent activity
        recent_users = User.query.order_by(User.date_created.desc()).limit(10).all()
        recent_jobs = Job.query.order_by(Job.date_posted.desc()).limit(10).all()
        recent_disputes = Dispute.query.order_by(Dispute.created_at.desc()).limit(5).all()
        
        # Financial overview
        total_payment_volume = db.session.query(
            func.sum(Payment.gross_amount)
        ).filter(Payment.status == 'completed').scalar() or 0
        
        pending_payment_volume = db.session.query(
            func.sum(Payment.gross_amount)
        ).filter(Payment.status.in_(['pending', 'held_escrow'])).scalar() or 0
        
        return jsonify({
            'stats': stats,
            'recent_users': [{
                'id': u.id,
                'email': u.email,
                'name': f"{u.first_name} {u.last_name}",
                'role': u.role,
                'date_created': u.date_created.isoformat() if u.date_created else None
            } for u in recent_users],
            'recent_jobs': [{
                'id': j.id,
                'title': j.title,
                'contractor_id': j.contractor_id,
                'status': j.status,
                'date_posted': j.date_posted.isoformat() if j.date_posted else None
            } for j in recent_jobs],
            'recent_disputes': [{
                'id': d.id,
                'contract_id': d.contract_id,
                'raised_by': d.raised_by,
                'status': d.status,
                'created_at': d.created_at.isoformat() if d.created_at else None
            } for d in recent_disputes],
            'financial': {
                'total_payment_volume': float(total_payment_volume),
                'pending_payment_volume': float(pending_payment_volume)
            }
        }), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/users', methods=['GET'])
@super_admin_required
def list_users():
    """
    List all users with pagination and filtering
    Supports search by email, name, role, and status
    """
    try:
        # Pagination
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 50, type=int), 100)
        
        # Filtering
        role_filter = request.args.get('role')
        status_filter = request.args.get('status')
        search_query = request.args.get('search')
        
        # Build query
        query = User.query
        
        if role_filter:
            query = query.filter_by(role=role_filter)
        
        if status_filter:
            if status_filter == 'active':
                query = query.filter_by(is_active=True)
            elif status_filter == 'inactive':
                query = query.filter_by(is_active=False)
        
        if search_query:
            query = query.filter(
                or_(
                    User.email.ilike(f'%{search_query}%'),
                    User.first_name.ilike(f'%{search_query}%'),
                    User.last_name.ilike(f'%{search_query}%'),
                    User.business_name.ilike(f'%{search_query}%')
                )
            )
        
        # Order by creation date (newest first)
        query = query.order_by(User.date_created.desc())
        
        # Paginate
        users = query.paginate(page=page, per_page=per_page, error_out=False)
        
        return jsonify({
            'users': [u.to_dict() for u in users.items],
            'total': users.total,
            'pages': users.pages,
            'current_page': page,
            'per_page': per_page
        }), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/users', methods=['POST'])
@super_admin_required
def create_user():
    """
    Create a new user account (admin only)
    Allows admins to create worker or contractor accounts
    """
    try:
        data = request.get_json()
        
        # Validate required fields
        required_fields = ['email', 'password', 'first_name', 'last_name', 'role', 'phone_number', 'location']
        for field in required_fields:
            if field not in data:
                return jsonify({'error': f'Missing required field: {field}'}), 400
        
        # Validate role
        if data['role'] not in ['worker', 'contractor', 'super_admin']:
            return jsonify({'error': 'Invalid role. Must be worker, contractor, or super_admin'}), 400
        
        # Check if email already exists
        existing_user = User.query.filter_by(email=data['email']).first()
        if existing_user:
            return jsonify({'error': 'Email already exists'}), 400
        
        # Create new user
        new_user = User(
            email=data['email'],
            first_name=data['first_name'],
            last_name=data['last_name'],
            role=data['role'],
            phone_number=data['phone_number'],
            location=data['location'],
            abn_number=data.get('abn_number', '00000000000'),
            business_name=data.get('business_name'),
            primary_trade=data.get('primary_trade'),
            secondary_trade=data.get('secondary_trade'),
            gst_registered=data.get('gst_registered', False),
            privacy_consent=True,
            terms_accepted=True,
            terms_accepted_date=datetime.utcnow(),
            is_active=data.get('is_active', True),
            account_status=data.get('account_status', 'active'),
            email_verified=data.get('email_verified', True)  # Admin-created users are pre-verified
        )
        
        # Set password
        new_user.set_password(data['password'])
        
        # Add to database
        db.session.add(new_user)
        db.session.commit()
        
        # Log the action
        log = AuditLog(
            user_id=current_user.id,
            action_type='create_user',
            resource_type='users',
            resource_id=new_user.id,
            action_description=f"Created user: {new_user.email} ({new_user.role})"
        )
        db.session.add(log)
        db.session.commit()
        
        return jsonify({
            'message': 'User created successfully',
            'user': new_user.to_dict()
        }), 201
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/users/<int:user_id>', methods=['GET'])
@super_admin_required
def get_user(user_id):
    """
    Get detailed information about a specific user
    Includes related data: jobs, contracts, ratings
    """
    try:
        user = User.query.get_or_404(user_id)
        
        # Get related data based on role
        related_data = {}
        
        if user.role == 'worker':
            related_data['applications'] = Application.query.filter_by(
                worker_id=user.id
            ).count()
            related_data['contracts'] = Contract.query.filter_by(
                worker_id=user.id
            ).count()
            
        elif user.role == 'contractor':
            related_data['jobs_posted'] = Job.query.filter_by(
                contractor_id=user.id
            ).count()
            related_data['contracts'] = Contract.query.filter_by(
                contractor_id=user.id
            ).count()
        
        # Ratings
        related_data['ratings_received'] = Rating.query.filter_by(
            rated_id=user.id
        ).count()
        
        # Disputes
        related_data['disputes_filed'] = Dispute.query.filter_by(
            raised_by=user.id
        ).count()
        
        return jsonify({
            'user': user.to_dict(),
            'related_data': related_data
        }), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/users/<int:user_id>', methods=['PUT'])
@super_admin_required
def update_user(user_id):
    """
    Update user account (activate, suspend, modify status)
    Logs all admin actions for audit trail
    """
    try:
        user = User.query.get_or_404(user_id)
        data = request.get_json()
        
        # Track what changed for audit log
        changes = []
        
        # Update allowed fields
        updatable_fields = [
            'first_name', 'last_name', 'email', 'phone_number', 'location',
            'business_name', 'primary_trade', 'abn_number', 'gst_registered',
            'role', 'is_active', 'email_verified',
            'public_liability_insurance', 'public_liability_amount',
            'workers_comp_insurance', 'insurance_expiry_date',
            'white_card_number', 'white_card_expiry'
        ]
        
        for field in updatable_fields:
            if field in data:
                old_value = getattr(user, field, None)
                new_value = data[field]
                
                # Convert string booleans to actual booleans
                if field in ['is_active', 'email_verified', 'gst_registered', 
                            'public_liability_insurance', 'workers_comp_insurance'] and isinstance(new_value, str):
                    new_value = new_value.lower() == 'true'
                
                # Handle empty strings for date fields
                if field in ['insurance_expiry_date', 'white_card_expiry']:
                    if new_value == '' or new_value is None:
                        new_value = None
                    elif isinstance(new_value, str):
                        from datetime import datetime
                        try:
                            new_value = datetime.strptime(new_value, '%Y-%m-%d').date()
                        except:
                            new_value = None
                
                # Handle numeric fields - convert empty strings to None
                if field == 'public_liability_amount':
                    if new_value == '' or new_value is None:
                        new_value = None
                    else:
                        try:
                            new_value = float(new_value)
                        except:
                            new_value = None
                
                # Handle string fields - convert empty strings to None for optional fields
                if field in ['white_card_number', 'primary_trade', 'business_name', 'location'] and new_value == '':
                    new_value = None
                
                if old_value != new_value:
                    setattr(user, field, new_value)
                    changes.append(f"{field}: {old_value} → {new_value}")
        
        # Handle 'phone' from form as 'phone_number' in model
        if 'phone' in data and 'phone_number' not in data:
            old_value = user.phone_number
            new_value = data['phone']
            if old_value != new_value:
                user.phone_number = new_value
                changes.append(f"phone_number: {old_value} → {new_value}")
        
        db.session.commit()
        
        return jsonify({
            'message': 'User updated successfully',
            'user': user.to_dict() if hasattr(user, 'to_dict') else {'id': user.id, 'email': user.email},
            'changes': changes
        }), 200
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/users/<int:user_id>', methods=['DELETE'])
@super_admin_required
def delete_user(user_id):
    """
    Delete a user account (soft delete with anonymisation)
    Retains transaction records for 7 years for tax compliance
    """
    from app.services.user_deletion_service import UserDeletionService
    
    try:
        # Prevent deleting yourself
        if user_id == current_user.id:
            return jsonify({'error': 'Cannot delete your own account'}), 400
        
        # Perform soft delete with anonymisation
        success, message = UserDeletionService.soft_delete_user(
            user_id=user_id,
            deleted_by_admin=True,
            admin_user_id=current_user.id
        )
        
        if success:
            return jsonify({
                'message': message
            }), 200
        else:
            return jsonify({'error': message}), 400
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/users/<int:user_id>/hard-delete', methods=['DELETE'])
@super_admin_required
def hard_delete_user(user_id):
    """
    Permanently delete a user account (hard delete)
    Only allowed after 7-year retention period has passed
    """
    from app.services.user_deletion_service import UserDeletionService
    
    try:
        # Prevent deleting yourself
        if user_id == current_user.id:
            return jsonify({'error': 'Cannot delete your own account'}), 400
        
        # Perform hard delete
        success, message = UserDeletionService.hard_delete_user(user_id=user_id)
        
        if success:
            return jsonify({
                'success': True,
                'message': message
            }), 200
        else:
            return jsonify({'error': message}), 400
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/jobs', methods=['GET'])
@super_admin_required
def list_jobs():
    """
    List all jobs in the system with filtering
    Admin oversight of all job postings
    """
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 50, type=int), 100)
        
        # Filtering
        status_filter = request.args.get('status')
        contractor_id = request.args.get('contractor_id', type=int)
        
        query = Job.query
        
        if status_filter:
            query = query.filter_by(status=status_filter)
        
        if contractor_id:
            query = query.filter_by(contractor_id=contractor_id)
        
        query = query.order_by(Job.date_posted.desc())
        
        jobs = query.paginate(page=page, per_page=per_page, error_out=False)
        
        return jsonify({
            'jobs': [{
                'id': j.id,
                'title': j.title,
                'contractor_id': j.contractor_id,
                'contractor_name': f"{j.contractor.first_name} {j.contractor.last_name}" if j.contractor else None,
                'status': j.status,
                'budget_min': float(j.budget_min) if j.budget_min else None,
                'budget_max': float(j.budget_max) if j.budget_max else None,
                'date_posted': j.date_posted.isoformat() if j.date_posted else None,
                'applications_count': j.applications_count
            } for j in jobs.items],
            'total': jobs.total,
            'pages': jobs.pages,
            'current_page': page
        }), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/contracts', methods=['GET'])
@super_admin_required
def list_contracts():
    """
    List all contracts with filtering
    Monitor all contractual relationships
    """
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 50, type=int), 100)
        
        status_filter = request.args.get('status')
        
        query = Contract.query
        
        if status_filter:
            query = query.filter_by(status=status_filter)
        
        query = query.order_by(Contract.created_at.desc())
        
        contracts = query.paginate(page=page, per_page=per_page, error_out=False)
        
        return jsonify({
            'contracts': [{
                'id': c.id,
                'job_id': c.job_id,
                'contractor_id': c.contractor_id,
                'worker_id': c.worker_id,
                'status': c.status,
                'agreed_rate': float(c.agreed_rate) if c.agreed_rate else None,
                'created_at': c.created_at.isoformat() if c.created_at else None
            } for c in contracts.items],
            'total': contracts.total,
            'pages': contracts.pages,
            'current_page': page
        }), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/payments', methods=['GET'])
@super_admin_required
def list_payments():
    """
    List all payments for financial oversight
    Monitor payment flow and detect issues
    """
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 50, type=int), 100)
        
        status_filter = request.args.get('status')
        
        query = Payment.query
        
        if status_filter:
            query = query.filter_by(status=status_filter)
        
        query = query.order_by(Payment.date_initiated.desc())
        
        payments = query.paginate(page=page, per_page=per_page, error_out=False)
        
        return jsonify({
            'payments': [{
                'id': p.id,
                'contract_id': p.contract_id,
                'status': p.status,
                'total_amount': float(p.total_amount) if p.total_amount else None,
                'platform_fee': float(p.platform_fee) if p.platform_fee else None,
                'net_to_worker': float(p.net_to_worker) if p.net_to_worker else None,
                'date_initiated': p.date_initiated.isoformat() if p.date_initiated else None,
                'stripe_payment_intent_id': p.stripe_payment_intent_id
            } for p in payments.items],
            'total': payments.total,
            'pages': payments.pages,
            'current_page': page
        }), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/disputes', methods=['GET'])
@super_admin_required
def list_disputes():
    """
    List all disputes for resolution oversight
    Critical for maintaining platform integrity
    """
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 50, type=int), 100)
        
        status_filter = request.args.get('status')
        
        query = Dispute.query
        
        if status_filter:
            query = query.filter_by(status=status_filter)
        
        query = query.order_by(Dispute.created_at.desc())
        
        disputes = query.paginate(page=page, per_page=per_page, error_out=False)
        
        return jsonify({
            'disputes': [{
                'id': d.id,
                'contract_id': d.contract_id,
                'raised_by': d.raised_by,
                'dispute_type': d.dispute_type,
                'status': d.status,
                'created_at': d.created_at.isoformat() if d.created_at else None,
                'resolved_at': d.resolved_at.isoformat() if d.resolved_at else None
            } for d in disputes.items],
            'total': disputes.total,
            'pages': disputes.pages,
            'current_page': page
        }), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/disputes/<int:dispute_id>/resolve', methods=['POST'])
@super_admin_required
def resolve_dispute(dispute_id):
    """
    Resolve a dispute with admin decision
    Logs resolution for audit trail
    """
    try:
        dispute = Dispute.query.get_or_404(dispute_id)
        data = request.get_json()
        
        if not data.get('resolution'):
            return jsonify({'error': 'Resolution details required'}), 400
        
        dispute.status = 'resolved'
        dispute.resolved_at = datetime.utcnow()
        dispute.resolution = data['resolution']
        dispute.resolved_by = current_user.id
        
        # Create audit log
        audit_log = AuditLog(
            user_id=current_user.id,
            action='dispute_resolved',
            target_type='Dispute',
            target_id=dispute_id,
            details=f"Admin {current_user.email} resolved dispute #{dispute_id}: {data['resolution']}",
            timestamp=datetime.utcnow()
        )
        db.session.add(audit_log)
        
        db.session.commit()
        
        return jsonify({
            'message': 'Dispute resolved successfully',
            'dispute': {
                'id': dispute.id,
                'status': dispute.status,
                'resolved_at': dispute.resolved_at.isoformat()
            }
        }), 200
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/audit-logs', methods=['GET'])
@super_admin_required
def list_audit_logs():
    """
    View system audit logs
    Track all administrative actions
    """
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 100, type=int), 200)
        
        action_filter = request.args.get('action')
        user_id = request.args.get('user_id', type=int)
        
        query = AuditLog.query
        
        if action_filter:
            query = query.filter_by(action=action_filter)
        
        if user_id:
            query = query.filter_by(user_id=user_id)
        
        query = query.order_by(AuditLog.timestamp.desc())
        
        logs = query.paginate(page=page, per_page=per_page, error_out=False)
        
        return jsonify({
            'logs': [{
                'id': log.id,
                'user_id': log.user_id,
                'action': log.action,
                'target_type': log.target_type,
                'target_id': log.target_id,
                'details': log.details,
                'timestamp': log.timestamp.isoformat() if log.timestamp else None
            } for log in logs.items],
            'total': logs.total,
            'pages': logs.pages,
            'current_page': page
        }), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/stats', methods=['GET'])
@super_admin_required
def system_stats():
    """
    Comprehensive system statistics
    Used for monitoring and reporting
    """
    try:
        # Time range for stats
        days = request.args.get('days', 30, type=int)
        since_date = datetime.utcnow() - timedelta(days=days)
        
        stats = {
            # User statistics
            'users': {
                'total': User.query.count(),
                'active': User.query.filter_by(is_active=True).count(),
                'workers': User.query.filter_by(role='worker').count(),
                'contractors': User.query.filter_by(role='contractor').count(),
                'new_users_period': User.query.filter(
                    User.date_created >= since_date
                ).count()
            },
            
            # Job statistics
            'jobs': {
                'total': Job.query.count(),
                'open': Job.query.filter_by(status='open').count(),
                'assigned': Job.query.filter_by(status='assigned').count(),
                'completed': Job.query.filter_by(status='completed').count(),
                'posted_period': Job.query.filter(
                    Job.date_posted >= since_date
                ).count()
            },
            
            # Contract statistics
            'contracts': {
                'total': Contract.query.count(),
                'active': Contract.query.filter(
                    Contract.status.in_(['active', 'pending_agreement', 'contractor_signed', 'worker_signed'])
                ).count(),
                'completed': Contract.query.filter_by(status='completed').count(),
                'created_period': Contract.query.filter(
                    Contract.created_at >= since_date
                ).count()
            },
            
            # Payment statistics
            'payments': {
                'total': Payment.query.count(),
                'completed': Payment.query.filter_by(status='completed').count(),
                'pending': Payment.query.filter(
                    Payment.status.in_(['pending', 'held_escrow'])
                ).count(),
                'total_volume': float(
                    db.session.query(func.sum(Payment.gross_amount))
                    .filter(Payment.status == 'completed')
                    .scalar() or 0
                ),
                'platform_fees': float(
                    db.session.query(func.sum(Payment.platform_fee))
                    .filter(Payment.status == 'completed')
                    .scalar() or 0
                )
            },
            
            # Dispute statistics
            'disputes': {
                'total': Dispute.query.count(),
                'open': Dispute.query.filter_by(status='open').count(),
                'resolved': Dispute.query.filter_by(status='resolved').count()
            }
        }
        
        return jsonify(stats), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


# ============================================================================
# HTML Template Rendering Routes (for admin UI)
# ============================================================================

@admin_bp.route('/view/create-user', methods=['GET'])
@super_admin_required
def create_user_page():
    """Render create user page"""
    return render_template('admin/create_user.html')


@admin_bp.route('/view/users', methods=['GET'])
@super_admin_required
def admin_users():
    """Render users management page with HTML template"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = 50
        role_filter = request.args.get('role')
        status_filter = request.args.get('status')
        search_query = request.args.get('search')
        
        query = User.query
        
        if role_filter:
            query = query.filter_by(role=role_filter)
        
        if status_filter:
            if status_filter == 'active':
                query = query.filter_by(is_active=True)
            elif status_filter == 'inactive':
                query = query.filter_by(is_active=False)
        
        if search_query:
            query = query.filter(
                or_(
                    User.email.ilike(f'%{search_query}%'),
                    User.first_name.ilike(f'%{search_query}%'),
                    User.last_name.ilike(f'%{search_query}%'),
                    User.business_name.ilike(f'%{search_query}%')
                )
            )
        
        query = query.order_by(User.date_created.desc())
        pagination = query.paginate(page=page, per_page=per_page, error_out=False)
        
        return render_template('admin/users.html',
            users=pagination.items,
            total=pagination.total,
            pages=pagination.pages,
            current_page=page
        )
    except Exception as e:
        return f"Error: {str(e)}", 500


@admin_bp.route('/view/users/<int:user_id>', methods=['GET'])
@super_admin_required
def admin_user_detail(user_id):
    """Render user detail/edit page with HTML template"""
    try:
        user = User.query.get_or_404(user_id)
        
        # Get related data based on role
        related_data = {}
        
        if user.role == 'worker':
            related_data['applications'] = Application.query.filter_by(
                worker_id=user.id
            ).count()
            related_data['contracts'] = Contract.query.filter_by(
                worker_id=user.id
            ).count()
            
        elif user.role == 'contractor':
            related_data['jobs_posted'] = Job.query.filter_by(
                contractor_id=user.id
            ).count()
            related_data['contracts'] = Contract.query.filter_by(
                contractor_id=user.id
            ).count()
        
        # Ratings
        related_data['ratings_received'] = Rating.query.filter_by(
            rated_id=user.id
        ).count()
        
        # Disputes
        related_data['disputes_filed'] = Dispute.query.filter_by(
            raised_by=user.id
        ).count()
        
        # Pass current datetime to template for time calculations
        return render_template('admin/user_detail.html',
            user=user,
            related_data=related_data,
            now=datetime.utcnow()
        )
    except Exception as e:
        return f"Error: {str(e)}", 500


@admin_bp.route('/view/jobs', methods=['GET'])
@super_admin_required
def admin_jobs():
    """Render jobs management page with HTML template"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = 50
        status_filter = request.args.get('status')
        contractor_id = request.args.get('contractor_id', type=int)
        
        query = Job.query
        
        if status_filter:
            query = query.filter_by(status=status_filter)
        
        if contractor_id:
            query = query.filter_by(contractor_id=contractor_id)
        
        query = query.order_by(Job.date_posted.desc())
        pagination = query.paginate(page=page, per_page=per_page, error_out=False)
        
        return render_template('admin/jobs.html',
            jobs=pagination.items,
            total=pagination.total,
            pages=pagination.pages,
            current_page=page
        )
    except Exception as e:
        return f"Error: {str(e)}", 500


@admin_bp.route('/view/jobs/<int:job_id>', methods=['GET'])
@super_admin_required
def admin_job_detail(job_id):
    """Render job detail/edit page with HTML template"""
    try:
        job = Job.query.get_or_404(job_id)
        applications_count = Application.query.filter_by(job_id=job.id).count()
        
        return render_template('admin/job_detail.html',
            job=job,
            applications_count=applications_count
        )
    except Exception as e:
        return f"Error: {str(e)}", 500


@admin_bp.route('/jobs/<int:job_id>', methods=['PUT'])
@super_admin_required
def update_job(job_id):
    """Update job details"""
    try:
        job = Job.query.get_or_404(job_id)
        data = request.get_json()
        
        updatable_fields = ['title', 'description', 'location', 'budget', 'status']
        for field in updatable_fields:
            if field in data:
                setattr(job, field, data[field])
        
        db.session.commit()
        return jsonify({'message': 'Job updated successfully'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/jobs/<int:job_id>', methods=['DELETE'])
@super_admin_required
def delete_job(job_id):
    """Delete a job permanently"""
    try:
        job = Job.query.get_or_404(job_id)
        db.session.delete(job)
        db.session.commit()
        return jsonify({'message': 'Job deleted successfully'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/view/contracts', methods=['GET'])
@super_admin_required
def admin_contracts():
    """Render contracts management page with HTML template"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = 50
        status_filter = request.args.get('status')
        
        query = Contract.query
        
        if status_filter:
            query = query.filter_by(status=status_filter)
        
        query = query.order_by(Contract.created_at.desc())
        pagination = query.paginate(page=page, per_page=per_page, error_out=False)
        
        return render_template('admin/contracts.html',
            contracts=pagination.items,
            total=pagination.total,
            pages=pagination.pages,
            current_page=page
        )
    except Exception as e:
        return f"Error: {str(e)}", 500


@admin_bp.route('/view/contracts/<int:contract_id>', methods=['GET'])
@super_admin_required
def admin_contract_detail(contract_id):
    """Render contract detail/edit page"""
    try:
        contract = Contract.query.get_or_404(contract_id)
        return render_template('admin/contract_detail.html', contract=contract)
    except Exception as e:
        return f"Error: {str(e)}", 500


@admin_bp.route('/contracts/<int:contract_id>', methods=['PUT'])
@super_admin_required
def update_contract(contract_id):
    """Update contract details"""
    try:
        contract = Contract.query.get_or_404(contract_id)
        data = request.get_json()
        
        if 'status' in data:
            contract.status = data['status']
        if 'agreed_rate' in data:
            contract.agreed_rate = data['agreed_rate']
        
        db.session.commit()
        return jsonify({'message': 'Contract updated successfully'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/contracts/<int:contract_id>', methods=['DELETE'])
@super_admin_required
def delete_contract(contract_id):
    """Delete a contract permanently"""
    try:
        contract = Contract.query.get_or_404(contract_id)
        db.session.delete(contract)
        db.session.commit()
        return jsonify({'message': 'Contract deleted successfully'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@admin_bp.route('/view/payments', methods=['GET'])
@super_admin_required
def admin_payments():
    """Render payments management page with HTML template"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = 50
        status_filter = request.args.get('status')
        
        query = Payment.query
        
        if status_filter:
            query = query.filter_by(status=status_filter)
        
        query = query.order_by(Payment.date_initiated.desc())
        pagination = query.paginate(page=page, per_page=per_page, error_out=False)
        
        return render_template('admin/payments.html',
            payments=pagination.items,
            total=pagination.total,
            pages=pagination.pages,
            current_page=page
        )
    except Exception as e:
        return f"Error: {str(e)}", 500


@admin_bp.route('/view/disputes', methods=['GET'])
@super_admin_required
def admin_disputes():
    """Render disputes management page with HTML template"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = 50
        status_filter = request.args.get('status')
        
        query = Dispute.query
        
        if status_filter:
            query = query.filter_by(status=status_filter)
        
        query = query.order_by(Dispute.created_at.desc())
        pagination = query.paginate(page=page, per_page=per_page, error_out=False)
        
        return render_template('admin/disputes.html',
            disputes=pagination.items,
            total=pagination.total,
            pages=pagination.pages,
            current_page=page
        )
    except Exception as e:
        return f"Error: {str(e)}", 500


@admin_bp.route('/view/audit-logs', methods=['GET'])
@super_admin_required
def admin_audit_logs():
    """Render audit logs page with HTML template"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = 100
        action_filter = request.args.get('action')
        user_id = request.args.get('user_id', type=int)
        
        query = AuditLog.query
        
        if action_filter:
            query = query.filter_by(action_type=action_filter)
        
        if user_id:
            query = query.filter_by(user_id=user_id)
        
        query = query.order_by(AuditLog.created_at.desc())
        pagination = query.paginate(page=page, per_page=per_page, error_out=False)
        
        return render_template('admin/audit_logs.html',
            logs=pagination.items,
            total=pagination.total,
            pages=pagination.pages,
            current_page=page
        )
    except Exception as e:
        return f"Error: {str(e)}", 500


# =============================================================================
# API Key Protected Endpoints (for CLI/automation access)
# =============================================================================

@admin_bp.route('/users/recent', methods=['GET'])
@admin_api_key_required
def list_recent_signups():
    """
    List users who signed up in the last 7 days (or custom days)
    Protected by admin API key for CLI access

    Query params:
        days: Number of days to look back (default: 7)
        role: Filter by role (worker, contractor)

    Headers required:
        X-Admin-API-Key: <admin_api_key>
    """
    try:
        days = request.args.get('days', 7, type=int)
        role_filter = request.args.get('role')

        cutoff_date = datetime.utcnow() - timedelta(days=days)

        query = User.query.filter(User.date_created >= cutoff_date)

        if role_filter:
            query = query.filter_by(role=role_filter)

        query = query.order_by(User.date_created.desc())
        users = query.all()

        return jsonify({
            'users': [{
                'id': u.id,
                'first_name': u.first_name,
                'last_name': u.last_name,
                'name': f"{u.first_name} {u.last_name}",
                'email': u.email,
                'phone_number': u.phone_number,
                'role': u.role,
                'signup_date': u.date_created.isoformat() if u.date_created else None,
                'email_verified': u.email_verified
            } for u in users],
            'total': len(users),
            'days': days,
            'as_of': datetime.utcnow().isoformat()
        }), 200

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


@admin_bp.route('/sms/send', methods=['POST'])
@admin_api_key_required
def send_sms_to_user():
    """
    Send SMS to a specific user
    Protected by admin API key for CLI access

    Request body (JSON):
        user_id: ID of user to send SMS to
        message: SMS message content (optional if using template)
        template: Template name - 'welcome_worker' or 'welcome_contractor' (optional)

    Headers required:
        X-Admin-API-Key: <admin_api_key>
        Content-Type: application/json
    """
    try:
        data = request.get_json()

        if not data:
            return jsonify({'error': 'Request body required'}), 400

        user_id = data.get('user_id')
        message = data.get('message')
        template = data.get('template')

        if not user_id:
            return jsonify({'error': 'user_id required'}), 400

        if not message and not template:
            return jsonify({'error': 'Either message or template required'}), 400

        user = User.query.get(user_id)
        if not user:
            return jsonify({'error': f'User {user_id} not found'}), 404

        if not user.phone_number:
            return jsonify({'error': f'User {user_id} has no phone number'}), 400

        # Use template if specified
        if template:
            if template == 'welcome_worker':
                success = SMSService.send_welcome_sms_worker(user)
            elif template == 'welcome_contractor':
                success = SMSService.send_welcome_sms_contractor(user)
            else:
                return jsonify({'error': f'Unknown template: {template}'}), 400
        else:
            success = SMSService.send_sms(user.phone_number, message)

        if success:
            return jsonify({
                'success': True,
                'message': f'SMS sent to {user.first_name} {user.last_name}',
                'phone': user.phone_number,
                'template': template if template else None
            }), 200
        else:
            return jsonify({
                'success': False,
                'message': 'SMS send failed - check logs for details',
                'note': 'If Twilio not configured, SMS was logged but not sent'
            }), 200

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


@admin_bp.route('/jobs/recent', methods=['GET'])
@admin_api_key_required
def list_recent_jobs():
    """
    List jobs posted in the last N days
    Protected by admin API key for CLI access

    Query params:
        days: Number of days to look back (default: 7)
        status: Filter by status (open, assigned, completed)

    Headers required:
        X-Admin-API-Key: <admin_api_key>
    """
    try:
        days = request.args.get('days', 7, type=int)
        status_filter = request.args.get('status')

        cutoff_date = datetime.utcnow() - timedelta(days=days)

        query = Job.query.filter(Job.date_posted >= cutoff_date)

        if status_filter:
            query = query.filter_by(status=status_filter)

        query = query.order_by(Job.date_posted.desc())
        jobs = query.all()

        return jsonify({
            'jobs': [{
                'id': j.id,
                'title': j.title,
                'category': j.category.name if j.category else None,
                'location': j.location,
                'contractor_id': j.contractor_id,
                'contractor_name': f"{j.contractor.first_name} {j.contractor.last_name}" if j.contractor else None,
                'status': j.status,
                'workers_needed': j.workers_needed,
                'accepted_workers': j.accepted_workers_count,
                'budget_min': float(j.budget_min) if j.budget_min else None,
                'budget_max': float(j.budget_max) if j.budget_max else None,
                'date_posted': j.date_posted.isoformat() if j.date_posted else None,
                'start_datetime': j.start_datetime.isoformat() if j.start_datetime else None
            } for j in jobs],
            'total': len(jobs),
            'days': days,
            'as_of': datetime.utcnow().isoformat()
        }), 200

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


@admin_bp.route('/workers/match', methods=['GET'])
@admin_api_key_required
def smart_match_workers():
    """
    Smart match workers to a job with scoring
    Protected by admin API key for CLI access

    Query params:
        job_id: ID of job to match workers for (required)
        limit: Max workers to return (default: 10)
        include_all: Include workers without matching trade (default: false)

    Scoring:
        - +50 points: Worked with this contractor before (completed contract)
        - +30 points max: Based on average rating (rating * 6)
        - +10 points: Valid compliance (white card + insurance current)
        - +5 points: Email verified
        - +5 points: Trade matches exactly

    Headers required:
        X-Admin-API-Key: <admin_api_key>
    """
    try:
        job_id = request.args.get('job_id', type=int)
        limit = request.args.get('limit', 10, type=int)
        include_all = request.args.get('include_all', 'false').lower() == 'true'

        if not job_id:
            return jsonify({'error': 'job_id required'}), 400

        job = Job.query.get(job_id)
        if not job:
            return jsonify({'error': f'Job {job_id} not found'}), 404

        # Get the job's category/trade name
        job_trade = job.category.name if job.category else None

        # Find workers who have completed contracts with this contractor
        past_workers_query = db.session.query(Contract.worker_id).filter(
            Contract.contractor_id == job.contractor_id,
            Contract.status == 'completed'
        ).distinct()
        past_worker_ids = set([r[0] for r in past_workers_query.all()])

        # Base query for workers
        query = User.query.filter(
            User.role == 'worker',
            User.is_active == True
        )

        # Filter by trade if not including all
        if not include_all and job_trade:
            query = query.filter(
                func.lower(User.primary_trade) == func.lower(job_trade)
            )

        workers = query.all()

        # Score each worker
        scored_workers = []
        today = datetime.utcnow().date()

        for w in workers:
            score = 0
            score_breakdown = {}

            # +50 for past work with contractor
            if w.id in past_worker_ids:
                score += 50
                score_breakdown['worked_before'] = 50

            # +30 max for rating (rating * 6, max 5 stars = 30)
            if w.average_rating:
                rating_score = min(float(w.average_rating) * 6, 30)
                score += rating_score
                score_breakdown['rating'] = round(rating_score, 1)

            # +10 for valid compliance
            compliance_valid = True
            if job.white_card_required:
                if not w.white_card_number or (w.white_card_expiry and w.white_card_expiry < today):
                    compliance_valid = False
            if job.insurance_required:
                if not w.public_liability_insurance or (w.insurance_expiry_date and w.insurance_expiry_date < today):
                    compliance_valid = False

            if compliance_valid:
                score += 10
                score_breakdown['compliance'] = 10

            # +5 for email verified
            if w.email_verified:
                score += 5
                score_breakdown['verified'] = 5

            # +5 for exact trade match
            if job_trade and w.primary_trade and w.primary_trade.lower() == job_trade.lower():
                score += 5
                score_breakdown['trade_match'] = 5

            scored_workers.append({
                'id': w.id,
                'name': f"{w.first_name} {w.last_name}",
                'phone': w.phone_number,
                'email': w.email,
                'trade': w.primary_trade,
                'location': w.location,
                'rating': float(w.average_rating) if w.average_rating else 0,
                'jobs_completed': w.jobs_completed,
                'worked_with_contractor': w.id in past_worker_ids,
                'compliance_valid': compliance_valid,
                'email_verified': w.email_verified,
                'score': score,
                'score_breakdown': score_breakdown
            })

        # Sort by score descending
        scored_workers.sort(key=lambda x: x['score'], reverse=True)

        # Limit results
        scored_workers = scored_workers[:limit]

        return jsonify({
            'job': {
                'id': job.id,
                'title': job.title,
                'trade': job_trade,
                'location': job.location,
                'contractor': f"{job.contractor.first_name} {job.contractor.last_name}" if job.contractor else None
            },
            'workers': scored_workers,
            'total_matches': len(scored_workers),
            'scoring': {
                'worked_before': 50,
                'rating_max': 30,
                'compliance': 10,
                'verified': 5,
                'trade_match': 5
            }
        }), 200

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