from sqlalchemy.orm import Session
from fastapi import HTTPException
from typing import List, Optional

from app.models.user_address import UserAddress
from app.schemas.user_address import AddressCreate, AddressUpdate

def get_user_addresses(db: Session, user_id: int) -> List[UserAddress]:
    """사용자의 모든 주소를 조회합니다."""
    return db.query(UserAddress).filter(UserAddress.user_id == user_id).all()

def get_address(db: Session, address_id: int, user_id: int) -> Optional[UserAddress]:
    """특정 주소를 조회합니다. 주소가 사용자에게 속하는지 확인합니다."""
    return db.query(UserAddress).filter(
        UserAddress.id == address_id,
        UserAddress.user_id == user_id
    ).first()

def create_address(db: Session, address: AddressCreate, user_id: int) -> UserAddress:
    """
    새 주소를 생성합니다.
    
    만약 이 주소가 기본 주소로 설정된 경우, 다른 모든 주소의 기본 주소 설정을 해제합니다.
    """
    db_address = UserAddress(
        user_id=user_id,
        title=address.title,
        recipient_name=address.recipient_name,
        address_line1=address.address_line1,
        address_line2=address.address_line2,
        city=address.city,
        postal_code=address.postal_code,
        country=address.country,
        phone=address.phone,
        is_default=address.is_default
    )
    
    # 이 주소가 기본 주소로 설정되었다면 다른 주소들의 기본 주소 설정 해제
    if address.is_default:
        _reset_other_default_addresses(db, user_id)
    
    db.add(db_address)
    db.commit()
    db.refresh(db_address)
    return db_address

def update_address(
    db: Session, 
    address_id: int, 
    address: AddressUpdate, 
    user_id: int
) -> Optional[UserAddress]:
    """
    주소를 수정합니다.
    
    만약 이 주소가 기본 주소로 설정된 경우, 다른 모든 주소의 기본 주소 설정을 해제합니다.
    """
    db_address = get_address(db, address_id, user_id)
    if not db_address:
        return None
    
    # 업데이트할 필드만 설정
    update_data = address.dict(exclude_unset=True)
    
    # 기본 주소 설정 변경 확인
    if 'is_default' in update_data and update_data['is_default']:
        _reset_other_default_addresses(db, user_id)
    
    # 주소 업데이트
    for key, value in update_data.items():
        setattr(db_address, key, value)
    
    db.commit()
    db.refresh(db_address)
    return db_address

def delete_address(db: Session, address_id: int, user_id: int) -> bool:
    """
    주소를 삭제합니다.
    
    만약 삭제되는 주소가 기본 주소였다면, 다른 주소를 기본 주소로 설정합니다.
    (다른 주소가 있는 경우에만)
    """
    db_address = get_address(db, address_id, user_id)
    if not db_address:
        return False
    
    # 삭제될 주소가 기본 주소인지 확인
    was_default = db_address.is_default
    
    # 주소 삭제
    db.delete(db_address)
    
    # 삭제된 주소가 기본 주소였고, 다른 주소가 있다면 새 기본 주소 설정
    if was_default:
        other_address = db.query(UserAddress).filter(
            UserAddress.user_id == user_id
        ).first()
        
        if other_address:
            other_address.is_default = True
    
    db.commit()
    return True

def set_default_address(db: Session, address_id: int, user_id: int) -> Optional[UserAddress]:
    """특정 주소를 기본 주소로 설정합니다."""
    db_address = get_address(db, address_id, user_id)
    if not db_address:
        return None
    
    # 다른 모든 주소의 기본 주소 설정 해제
    _reset_other_default_addresses(db, user_id)
    
    # 이 주소를 기본 주소로 설정
    db_address.is_default = True
    db.commit()
    db.refresh(db_address)
    return db_address

def _reset_other_default_addresses(db: Session, user_id: int) -> None:
    """사용자의 모든 주소의 기본 주소 설정을 해제합니다."""
    db.query(UserAddress).filter(
        UserAddress.user_id == user_id,
        UserAddress.is_default == True
    ).update({"is_default": False}) 