from typing import Optional
from sqlmodel import Session, select, func
from app.models.models import QuestionVote, Question


def find_vote(
    session: Session, user_id: int, question_id: int
) -> Optional[QuestionVote]:
    stmt = select(QuestionVote).where(
        QuestionVote.user_id == user_id,
        QuestionVote.question_id == question_id,
    )
    return session.exec(stmt).one_or_none()


def upsert_vote(
    session: Session, user_id: int, question_id: int, value: int
) -> QuestionVote:
    existing = find_vote(session, user_id, question_id)
    if existing:
        existing.value = value
        session.add(existing)
    else:
        existing = QuestionVote(user_id=user_id, question_id=question_id, value=value)
        session.add(existing)
    session.commit()
    return existing


def remove_vote(session: Session, user_id: int, question_id: int) -> None:
    existing = find_vote(session, user_id, question_id)
    if existing:
        session.delete(existing)
        session.commit()


def get_aggregate_score(session: Session, question_id: int) -> int:
    stmt = select(func.coalesce(func.sum(QuestionVote.value), 0)).where(
        QuestionVote.question_id == question_id
    )
    return session.exec(stmt).one()


def question_exists(session: Session, question_id: int) -> bool:
    return session.get(Question, question_id) is not None
