"""
접속 로그 기록을 위한 유틸리티 함수들
"""
from django.contrib.auth.models import User
from .models import AccessLog, Person


def get_client_ip(request):
    """클라이언트 IP 주소 가져오기"""
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0].strip()
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip


def get_user_agent(request):
    """사용자 에이전트 가져오기"""
    return request.META.get('HTTP_USER_AGENT', '')


def log_user_activity(request, action, description=None, user=None, metadata=None):
    """
    사용자 활동 로그 기록
    
    Args:
        request: Django request 객체
        action: 활동 유형 (AccessLog.ACTION_CHOICES 중 하나)
        description: 상세 설명 (선택사항)
        user: 사용자 객체 (선택사항, 없으면 request.user 사용)
        metadata: 추가 정보 딕셔너리 (선택사항)
    """
    try:
        # 사용자 정보 가져오기
        if user is None:
            user = request.user if request.user.is_authenticated else None
        
        # Person 객체 가져오기
        person = None
        if user:
            try:
                person = Person.objects.get(user=user)
            except Person.DoesNotExist:
                pass
        
        # 메타데이터 기본값 설정
        if metadata is None:
            metadata = {}
        
        # 요청 정보 추가
        metadata.update({
            'path': request.path,
            'method': request.method,
            'referer': request.META.get('HTTP_REFERER', ''),
        })
        
        # 로그 생성
        AccessLog.objects.create(
            user=user,
            person=person,
            action=action,
            description=description,
            ip_address=get_client_ip(request),
            user_agent=get_user_agent(request),
            session_key=request.session.session_key,
            metadata=metadata
        )
        
        print(f"[ACCESS_LOG] {action}: {user.username if user else 'Anonymous'} - {description}")
        
    except Exception as e:
        print(f"[ACCESS_LOG_ERROR] 로그 기록 실패: {e}")


def log_login(request, user):
    """로그인 로그 기록"""
    log_user_activity(
        request=request,
        action='LOGIN',
        description=f'사용자 로그인: {user.username}',
        user=user
    )


def log_logout(request, user):
    """로그아웃 로그 기록"""
    log_user_activity(
        request=request,
        action='LOGOUT',
        description=f'사용자 로그아웃: {user.username}',
        user=user
    )


def log_signup(request, user):
    """회원가입 로그 기록"""
    log_user_activity(
        request=request,
        action='SIGNUP',
        description=f'새 회원가입: {user.username}',
        user=user
    )


def log_profile_update(request, user, updated_fields=None, field_changes=None):
    """프로필 수정 로그 기록"""
    description = f'프로필 수정: {user.username}'
    if updated_fields:
        description += f' (수정된 필드: {", ".join(updated_fields)})'
    
    metadata = {}
    if updated_fields:
        metadata['updated_fields'] = updated_fields
    
    # 필드별 수정 전/후 값 기록
    if field_changes:
        metadata['field_changes'] = field_changes
        # 상세 설명에 변경사항 추가
        change_details = []
        for field_name, changes in field_changes.items():
            old_value = changes.get('old', '')
            new_value = changes.get('new', '')
            # 값이 너무 길면 자르기
            if len(str(old_value)) > 50:
                old_value = str(old_value)[:50] + '...'
            if len(str(new_value)) > 50:
                new_value = str(new_value)[:50] + '...'
            change_details.append(f"{field_name}: '{old_value}' → '{new_value}'")
        
        if change_details:
            description += f' | 변경사항: {" | ".join(change_details)}'
    
    log_user_activity(
        request=request,
        action='PROFILE_UPDATE',
        description=description,
        user=user,
        metadata=metadata
    )


def log_password_change(request, user):
    """비밀번호 변경 로그 기록"""
    log_user_activity(
        request=request,
        action='PASSWORD_CHANGE',
        description=f'비밀번호 변경: {user.username}',
        user=user
    )


def log_phone_verification(request, phone_number, user=None):
    """전화번호 인증 로그 기록"""
    log_user_activity(
        request=request,
        action='PHONE_VERIFICATION',
        description=f'전화번호 인증: {phone_number}',
        user=user,
        metadata={'phone_number': phone_number}
    )


def log_search(request, query, result_count=None):
    """검색 로그 기록"""
    description = f'검색 쿼리: {query}'
    if result_count is not None:
        description += f' (결과: {result_count}개)'
    
    metadata = {'query': query}
    if result_count is not None:
        metadata['result_count'] = result_count
    
    log_user_activity(
        request=request,
        action='SEARCH',
        description=description,
        metadata=metadata
    )


def log_main_access(request):
    """메인페이지 접속 로그 기록"""
    log_user_activity(
        request=request,
        action='MAIN_ACCESS',
        description='메인페이지 접속'
    )


def log_error(request, error_message, error_type=None):
    """에러 로그 기록"""
    metadata = {'error_message': error_message}
    if error_type:
        metadata['error_type'] = error_type
    
    log_user_activity(
        request=request,
        action='ERROR',
        description=f'에러 발생: {error_message}',
        metadata=metadata
    )


def log_withdrawal_request(request, user, withdrawal_request_id):
    """회원탈퇴 요청 로그 기록"""
    log_user_activity(
        request=request,
        action='OTHER',
        description=f'회원탈퇴 요청 제출: {user.username}',
        user=user,
        metadata={
            'withdrawal_request_id': withdrawal_request_id,
            'action_type': 'withdrawal_request'
        }
    )


def log_withdrawal_approval(request, approved_by, withdrawn_user, withdrawn_person, withdrawal_request_id):
    """회원탈퇴 승인 로그 기록"""
    log_user_activity(
        request=request,
        action='OTHER',
        description=f'회원탈퇴 승인 처리: {withdrawn_user} ({withdrawn_person})',
        user=approved_by,
        metadata={
            'withdrawal_request_id': withdrawal_request_id,
            'withdrawn_user': withdrawn_user,
            'withdrawn_person': withdrawn_person,
            'action_type': 'withdrawal_approval'
        }
    )
