"""Profile service for user self-service operations."""
import os
from flask import current_app
from werkzeug.utils import secure_filename
from app import db
from app.models import User
from app.utils import validate_email, validate_password, validate_name


def get_own_profile(user_id):
    """
    Get authenticated user's full private profile.
    
    Args:
        user_id: User ID from JWT token
        
    Returns:
        dict: {'success': bool, 'message': str, 'data': dict/None}
    """
    try:
        user = User.query.filter_by(id=str(user_id)).first()
        
        if not user:
            return {'success': False, 'message': 'User not found', 'data': None}
        
        return {
            'success': True,
            'message': 'Profile retrieved successfully',
            'data': user.to_dict_private()
        }
        
    except Exception as e:
        current_app.logger.error(f"Get profile error: {str(e)}")
        return {'success': False, 'message': 'Failed to retrieve profile', 'data': None}


def update_profile(user_id, data):
    """
    Update user's profile information.
    
    Args:
        user_id: User ID from JWT token
        data: Dictionary with fields to update
        
    Allowed fields: first_name, last_name, phone_number, date_of_birth, 
                   address, city, country
    
    Returns:
        dict: {'success': bool, 'message': str, 'data': dict/None}
    """
    try:
        user = User.query.filter_by(id=str(user_id)).first()
        
        if not user:
            return {'success': False, 'message': 'User not found', 'data': None}
        
        # Validate and update first_name
        if 'first_name' in data:
            is_valid, error = validate_name(data['first_name'], "First name")
            if not is_valid:
                return {'success': False, 'message': error, 'data': None}
            user.first_name = data['first_name']
        
        # Validate and update last_name
        if 'last_name' in data:
            is_valid, error = validate_name(data['last_name'], "Last name")
            if not is_valid:
                return {'success': False, 'message': error, 'data': None}
            user.last_name = data['last_name']
        
        # Update phone_number
        if 'phone_number' in data:
            phone = data['phone_number']
            if phone:  # If not empty, check uniqueness
                existing = User.query.filter(
                    User.phone_number == phone,
                    User.id != str(user_id)
                ).first()
                if existing:
                    return {'success': False, 'message': 'Phone number already in use', 'data': None}
            user.phone_number = phone if phone else None
        
        # Update date_of_birth
            
        if 'date_of_birth' in data:
            date_value = data['date_of_birth']
            if date_value and date_value.strip():  # If not empty/whitespace
                try:
                    # Parse ISO format string to date object
                    from datetime import datetime
                    user.date_of_birth = datetime.fromisoformat(date_value).date()
                except (ValueError, AttributeError) as e:
                    return {'success': False, 'message': 'Invalid date format. Use YYYY-MM-DD', 'data': None}
            else:
                user.date_of_birth = None  # Clear the date if empty string sent
        
        # Update address fields
        if 'address' in data:
            user.address = data['address']
        
        if 'city' in data:
            user.city = data['city']
        
        if 'country' in data:
            user.country = data['country']
        
        db.session.commit()
        
        return {
            'success': True,
            'message': 'Profile updated successfully',
            'data': user.to_dict_private()
        }
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"Update profile error: {str(e)}")
        return {'success': False, 'message': 'Failed to update profile', 'data': None}


def update_profile_image(user_id, image_file):
    """
    Update user's profile image.
    
    Args:
        user_id: User ID from JWT token
        image_file: File object from request.files
        
    Returns:
        dict: {'success': bool, 'message': str, 'data': dict/None}
    """
    try:
        user = User.query.filter_by(id=str(user_id)).first()
        
        if not user:
            return {'success': False, 'message': 'User not found', 'data': None}
        
        if not image_file:
            return {'success': False, 'message': 'No image file provided', 'data': None}
        
        # Validate file extension
        filename = secure_filename(image_file.filename)
        if not filename or '.' not in filename:
            return {'success': False, 'message': 'Invalid filename', 'data': None}
        
        extension = filename.rsplit('.', 1)[1].lower()
        if extension not in current_app.config['ALLOWED_EXTENSIONS']:
            return {'success': False, 'message': f'File type not allowed. Allowed types: {", ".join(current_app.config["ALLOWED_EXTENSIONS"])}', 'data': None}
        
        # Create profiles directory if it doesn't exist
        profiles_dir = os.path.join(current_app.config['UPLOAD_FOLDER'], 'profiles')
        os.makedirs(profiles_dir, exist_ok=True)
        
        # Generate unique filename: user_id.extension
        new_filename = f"{user_id}.{extension}"
        filepath = os.path.join(profiles_dir, new_filename)
        
        # Delete old profile image if exists and different extension
        if user.profile_image:
            old_filepath = os.path.join(current_app.root_path, user.profile_image.lstrip('/'))
            if os.path.exists(old_filepath) and old_filepath != filepath:
                try:
                    os.remove(old_filepath)
                except Exception as e:
                    current_app.logger.warning(f"Failed to delete old profile image: {str(e)}")
        
        # Save new image
        image_file.save(filepath)
        
        # Update user record with relative path
        user.profile_image = f"/static/uploads/profiles/{new_filename}"
        db.session.commit()
        
        return {
            'success': True,
            'message': 'Profile image updated successfully',
            'data': {'profile_image': user.profile_image}
        }
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"Update profile image error: {str(e)}")
        return {'success': False, 'message': 'Failed to update profile image', 'data': None}


def change_password(user_id, current_password, new_password):
    """
    Change user's password.
    
    Args:
        user_id: User ID from JWT token
        current_password: User's current password for verification
        new_password: New password to set
        
    Returns:
        dict: {'success': bool, 'message': str, 'data': dict/None}
    """
    try:
        user = User.query.filter_by(id=str(user_id)).first()
        
        if not user:
            return {'success': False, 'message': 'User not found', 'data': None}
        
        # Verify current password
        if not user.check_password(current_password):
            return {'success': False, 'message': 'Current password is incorrect', 'data': None}
        
        # Validate new password
        is_valid, error = validate_password(new_password)
        if not is_valid:
            return {'success': False, 'message': error, 'data': None}
        
        # Check if new password is same as current
        if user.check_password(new_password):
            return {'success': False, 'message': 'New password must be different from current password', 'data': None}
        
        # Update password
        user.set_password(new_password)
        db.session.commit()
        
        return {
            'success': True,
            'message': 'Password changed successfully',
            'data': None
        }
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"Change password error: {str(e)}")
        return {'success': False, 'message': 'Failed to change password', 'data': None}


def delete_own_account(user_id):
    """
    Soft delete user's account (set is_active=False).
    
    Args:
        user_id: User ID from JWT token
        
    Returns:
        dict: {'success': bool, 'message': str, 'data': dict/None}
    """
    try:
        user = User.query.filter_by(id=str(user_id)).first()
        
        if not user:
            return {'success': False, 'message': 'User not found', 'data': None}
        
        if not user.is_active:
            return {'success': False, 'message': 'Account is already deactivated', 'data': None}
        
        # Soft delete - just deactivate
        user.is_active = False
        db.session.commit()
        
        return {
            'success': True,
            'message': 'Account deactivated successfully',
            'data': None
        }
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"Delete account error: {str(e)}")
        return {'success': False, 'message': 'Failed to deactivate account', 'data': None}


def get_user_public(user_id):
    """
    Get public user profile (for displaying on listings).
    
    Args:
        user_id: User ID to fetch
        
    Returns:
        dict: {'success': bool, 'message': str, 'data': dict/None}
    """
    try:
        user = User.query.filter_by(id=str(user_id)).first()
        
        if not user:
            return {'success': False, 'message': 'User not found', 'data': None}
        
        return {
            'success': True,
            'message': 'User profile retrieved successfully',
            'data': user.to_dict_public()
        }
        
    except Exception as e:
        current_app.logger.error(f"Get public profile error: {str(e)}")
        return {'success': False, 'message': 'Failed to retrieve user profile', 'data': None}