﻿"""REST API routes for messaging system - RateRight Australian Construction Marketplace"""
import logging
from datetime import datetime, timezone
from flask import Blueprint, request, jsonify, current_app
from flask_login import login_required, current_user

from ...services.message_service import message_service
from ...models import User
from ...extensions import db, limiter

logger = logging.getLogger(__name__)

messages_bp = Blueprint('messages', __name__, url_prefix='/api/messages')


@messages_bp.route('/', methods=['POST'])
@login_required
def send_message():
    """Send a new message to another user"""
    try:
        data = request.get_json()
        if not data:
            return jsonify({
            'current_user_id': current_user.id,'error': 'No data provided'}), 400
        
        # Validate required fields
        receiver_id = data.get('receiver_id')
        text = data.get('text', '').strip()
        file_ids = data.get('file_ids', [])  # Get file IDs if provided
        
        if not receiver_id:
            return jsonify({
            'current_user_id': current_user.id,'error': 'receiver_id is required'}), 400
        
        # Allow empty text if files are provided
        if not text and not file_ids:
            return jsonify({
            'current_user_id': current_user.id,'error': 'Message must have text or files'}), 400
        
        if text and len(text) > 2000:
            return jsonify({
            'current_user_id': current_user.id,'error': 'Message text too long (max 2000 characters)'}), 400
        
        # Optional context fields
        contract_id = data.get('contract_id')
        job_id = data.get('job_id')
        
        # Check if receiver exists and is not deleted
        receiver = User.query.get(receiver_id)
        if not receiver:
            return jsonify({
                'current_user_id': current_user.id,
                'error': 'Recipient not found'
            }), 404
        
        if receiver.is_deleted:
            return jsonify({
                'current_user_id': current_user.id,
                'error': 'Cannot send messages to deleted accounts',
                'reason': 'account_deleted'
            }), 403
        
        # Send message
        message = message_service.send_message(
            sender_id=current_user.id,
            receiver_id=receiver_id,
            text=text,
            contract_id=contract_id,
            job_id=job_id
        )
        
        if message:
            # Link files to message if provided
            if file_ids:
                from ...models.file_upload import FileUpload
                for file_id in file_ids:
                    file_upload = FileUpload.query.get(file_id)
                    if file_upload and file_upload.user_id == current_user.id:
                        file_upload.message_id = message.id
                db.session.commit()
            
            return jsonify({
            'current_user_id': current_user.id,
                'success': True,
                'message': 'Message sent successfully',
                'data': message.to_dict(include_sender_info=True, include_receiver_info=True)
            }), 201
        else:
            return jsonify({
            'current_user_id': current_user.id,'error': 'Failed to send message'}), 500
        
    except Exception as e:
        logger.error(f"Error sending message: {e}")
        return jsonify({
            'current_user_id': current_user.id,'error': 'Internal server error'}), 500


@messages_bp.route('/', methods=['GET'])
@login_required
def get_conversations():
    """Get list of conversations for current user"""
    try:
        limit = min(int(request.args.get('limit', 20)), 50)  # Max 50 conversations
        
        conversations = message_service.get_user_conversations(
            user_id=current_user.id,
            limit=limit
        )
        
        return jsonify({
            'current_user_id': current_user.id,
            'success': True,
            'conversations': conversations,
            'total_conversations': len(conversations)
        }), 200
        
    except Exception as e:
        logger.error(f"Error getting conversations: {e}")
        return jsonify({
            'current_user_id': current_user.id,'error': 'Internal server error'}), 500


@messages_bp.route('/<int:user_id>', methods=['GET'])
@login_required
def get_conversation_with_user(user_id):
    """Get messages in conversation with specific user"""
    try:
        # Get pagination parameters
        limit = min(int(request.args.get('limit', 50)), 100)  # Max 100 messages
        offset = int(request.args.get('offset', 0))
        
        # Check if conversation can send messages
        from ...models.message import Conversation
        conversation = Conversation(current_user.id, user_id)
        can_send = conversation.can_send_messages()
        deleted_info = conversation.get_deleted_user_info()
        
        # Get conversation messages
        result = message_service.get_conversation_messages(
            user_id=current_user.id,
            partner_id=user_id,
            limit=limit,
            offset=offset
        )
        
        if 'error' in result:
            return jsonify(result), 404
        
        # Add conversation status to result
        result['can_send_messages'] = can_send
        result['conversation_status'] = deleted_info
        
        return jsonify({
            'current_user_id': current_user.id,
            'success': True,
            **result
        }), 200
        
    except Exception as e:
        logger.error(f"Error getting conversation messages: {e}")
        return jsonify({
            'current_user_id': current_user.id,'error': 'Internal server error'}), 500


@messages_bp.route('/unread-count', methods=['GET'])
@limiter.exempt  # Exempt from rate limiting - polled frequently
@login_required
def get_unread_count():
    """Get count of unread messages for current user"""
    try:
        count = message_service.get_unread_message_count(current_user.id)
        return jsonify({
            'current_user_id': current_user.id,
            'success': True,
            'unread_count': count
        }), 200
        
    except Exception as e:
        logger.error(f"Error getting unread count: {e}")
        return jsonify({
            'current_user_id': current_user.id,'error': 'Internal server error'}), 500


@messages_bp.route('/<int:message_id>/read', methods=['POST'])
@login_required
def mark_message_read(message_id):
    """Mark specific message as read"""
    try:
        success = message_service.mark_message_as_read(message_id, current_user.id)
        
        if success:
            return jsonify({
            'current_user_id': current_user.id,
                'success': True,
                'message': 'Message marked as read'
            }), 200
        else:
            return jsonify({
            'current_user_id': current_user.id,'error': 'Message not found or not authorized'}), 404
            
    except Exception as e:
        logger.error(f"Error marking message as read: {e}")
        return jsonify({
            'current_user_id': current_user.id,'error': 'Internal server error'}), 500


@messages_bp.route('/<int:message_id>', methods=['DELETE'])
@login_required
def delete_message(message_id):
    """Delete a message (only sender can delete)"""
    try:
        success = message_service.delete_message(message_id, current_user.id)
        
        if success:
            return jsonify({
            'current_user_id': current_user.id,
                'success': True,
                'message': 'Message deleted successfully'
            }), 200
        else:
            return jsonify({
            'current_user_id': current_user.id,'error': 'Message not found or not authorized'}), 404
            
    except Exception as e:
        logger.error(f"Error deleting message: {e}")
        return jsonify({
            'current_user_id': current_user.id,'error': 'Internal server error'}), 500


@messages_bp.route('/search', methods=['GET'])
@login_required
def search_messages():
    """Search messages for current user"""
    try:
        query = request.args.get('q', '').strip()
        limit = min(int(request.args.get('limit', 20)), 50)  # Max 50 results
        
        if not query:
            return jsonify({
            'current_user_id': current_user.id,'error': 'Search query is required'}), 400
        
        if len(query) < 2:
            return jsonify({
            'current_user_id': current_user.id,'error': 'Search query must be at least 2 characters'}), 400
        
        results = message_service.search_messages(
            user_id=current_user.id,
            query=query,
            limit=limit
        )
        
        return jsonify({
            'current_user_id': current_user.id,
            'success': True,
            'query': query,
            'results': results,
            'total_results': len(results)
        }), 200
        
    except Exception as e:
        logger.error(f"Error searching messages: {e}")
        return jsonify({
            'current_user_id': current_user.id,'error': 'Internal server error'}), 500


@messages_bp.route('/users', methods=['GET'])
@login_required
def get_messageable_users():
    """Get list of users that can be messaged (exclude self)"""
    try:
        # Get users excluding current user
        users = User.query.filter(User.id != current_user.id, User.is_active == True).all()
        
        user_list = []
        for user in users:
            user_list.append({
                'id': user.id,
                'name': f"{user.first_name} {user.last_name}",
                'role': user.role,
                'average_rating': float(user.average_rating) if user.average_rating else 0.0
            })
        
        # Sort by name
        user_list.sort(key=lambda x: x['name'])
        
        return jsonify({
            'current_user_id': current_user.id,
            'success': True,
            'users': user_list,
            'total_users': len(user_list)
        }), 200
        
    except Exception as e:
        logger.error(f"Error getting messageable users: {e}")
        return jsonify({
            'current_user_id': current_user.id,'error': 'Internal server error'}), 500


@messages_bp.route('/poll', methods=['GET'])
@limiter.exempt  # Exempt from rate limiting - polled every 5 seconds
@login_required
def poll_new_messages():
    """Polling endpoint to check for new messages (for 5-second polling)"""
    try:
        # Get timestamp from last poll
        since_timestamp = request.args.get('since')
        
        # Get recent conversations
        conversations = message_service.get_user_conversations(
            user_id=current_user.id,
            limit=20
        )
        
        # Get unread count
        unread_count = message_service.get_unread_message_count(current_user.id)
        
        # If since_timestamp is provided, filter for newer conversations
        if since_timestamp:
            try:
                since_dt = datetime.fromisoformat(since_timestamp.replace('Z', '+00:00'))
                
                # Filter conversations with messages newer than since_timestamp
                filtered_conversations = []
                for conv in conversations:
                    last_msg_time = datetime.fromisoformat(conv['last_message']['created_at'])
                    if last_msg_time > since_dt:
                        filtered_conversations.append(conv)
                
                conversations = filtered_conversations
                
            except (ValueError, KeyError) as e:
                logger.warning(f"Invalid since_timestamp format: {since_timestamp}, error: {e}")
        
        return jsonify({
            'current_user_id': current_user.id,
            'success': True,
            'conversations': conversations,
            'unread_count': unread_count,
            'has_new_messages': len(conversations) > 0 or unread_count > 0,
            'poll_timestamp': datetime.now(timezone.utc).isoformat()
        }), 200
        
    except Exception as e:
        logger.error(f"Error polling messages: {e}")
        return jsonify({
            'current_user_id': current_user.id,'error': 'Internal server error'}), 500


# Health check endpoint for messaging system
@messages_bp.route('/health', methods=['GET'])
def health_check():
    """Health check for messaging system"""
    try:
        # Test database connectivity
        from ...models.message import Message
        message_count = Message.query.count()
        
        return jsonify({
            'current_user_id': current_user.id,
            'status': 'healthy',
            'service': 'RateRight Messaging System',
            'total_messages': message_count,
            'features': {
                'send_messages': True,
                'conversations': True,
                'unread_tracking': True,
                'message_search': True,
                'polling_support': True,
                'notification_integration': True
            }
        }), 200
        
    except Exception as e:
        logger.error(f"Messaging health check failed: {e}")
        return jsonify({
            'current_user_id': current_user.id,
            'status': 'unhealthy',
            'error': str(e)
        }), 500


@messages_bp.errorhandler(404)
def not_found(error):
    """Handle 404 errors for message routes."""
    return jsonify({
            'current_user_id': current_user.id,'error': 'Resource not found'}), 404


@messages_bp.errorhandler(500)
def internal_error(error):
    """Handle 500 errors for message routes."""
    return jsonify({
            'current_user_id': current_user.id,'error': 'Internal server error'}), 500
