from sqlalchemy.orm import Session
from app.models.advertisement import Advertisement
from app.models.advertisement_click_record import AdvertisementClickRecord
from app.models.point_transaction import PointTransaction
from app.models.user_points import UserPoints
from app.core.time import now

def process_advertisement_click(db: Session, user_id: int, ad_id: int):
    """
    광고 클릭 시 포인트를 지급하고, 광고 상태와 사용자 포인트를 업데이트합니다.
    
    Steps:
    1. 광고(Advertisement)를 조회하여 존재 여부와 클릭 여부를 확인합니다.
    2. 새로 만든 AdvertisementClickRecord 테이블을 통해, 해당 유저가 이미 광고를 클릭했는지 검사합니다.
    3. 기록이 없으면 새 AdvertisementClickRecord를 생성합니다.
    4. 광고의 포인트(ad_video_points)를 이용해 PointTransaction 기록을 추가합니다.
    5. UserPoints 테이블에서 해당 사용자의 총 포인트를 업데이트하거나, 없으면 생성합니다.
    6. 모든 변경을 DB에 커밋합니다.
    
    Returns a dictionary with advertisement, point_transaction and user_points.
    """
    # 광고 조회
    ad = db.query(Advertisement).filter(Advertisement.id == ad_id).first()
    if not ad:
        raise Exception("Advertisement not found")
    
    # 유저별 클릭 기록 체크 (이미 클릭한 경우 중복 지급 방지)
    existing_click = db.query(AdvertisementClickRecord).filter(
        AdvertisementClickRecord.user_id == user_id,
        AdvertisementClickRecord.advertisement_id == ad_id
    ).first()
    if existing_click:
        raise Exception("Advertisement already clicked by this user")
    
    # 사용자별 광고 클릭 기록 추가
    ad_click_record = AdvertisementClickRecord(
        user_id=user_id,
        advertisement_id=ad_id
    )
    db.add(ad_click_record)
    
    # 지급할 포인트
    points = ad.ad_video_points

    # 포인트 트랜잭션 기록 생성
    point_tx = PointTransaction(
        user_id=user_id,
        transaction_type="etc",
        amount=points,
        description="Advertisement click reward"
    )
    db.add(point_tx)
    
    # 사용자의 포인트 업데이트
    user_points = db.query(UserPoints).filter(UserPoints.user_id == user_id).first()
    if user_points:
        user_points.total_points += points
    else:
        user_points = UserPoints(user_id=user_id, total_points=points)
        db.add(user_points)
    
    # flush() 호출해서 DB에 쿼리가 정상적으로 발생하는지 확인 (문제가 있으면 여기서 에러 발생)
    db.flush()
    # 로그 등으로 확인하고 싶다면
    print("Flushed records: ad_click_record, point_tx, user_points")

    # 커밋
    db.commit()
    db.refresh(ad_click_record)
    db.refresh(point_tx)
    db.refresh(user_points)
    
    return {
        "advertisement": ad,
        "ad_click_record": ad_click_record,
        "point_transaction": point_tx,
        "user_points": user_points
    } 