from datetime import datetime, timezone

from sqlalchemy import select
from sqlalchemy.orm import Session

from app.core.verification import (
    generate_verification_code,
    hash_verification_code,
    verification_expiry,
    verify_verification_code,
)
from app.models.email_verification import EmailVerification
from app.models.user import User


def create_email_verification(
    db: Session,
    user: User,
) -> str:
    existing_records = db.scalars(
        select(EmailVerification).where(
            EmailVerification.user_id == user.id,
            EmailVerification.used_at.is_(None),
        )
    ).all()

    now = datetime.now(timezone.utc)

    for record in existing_records:
        record.used_at = now

    code = generate_verification_code()

    verification = EmailVerification(
        user_id=user.id,
        code_hash=hash_verification_code(code),
        expires_at=verification_expiry(),
    )

    db.add(verification)
    db.commit()

    return code


def verify_email_code(
    db: Session,
    user: User,
    code: str,
) -> bool:
    verification = db.scalar(
        select(EmailVerification)
        .where(
            EmailVerification.user_id == user.id,
            EmailVerification.used_at.is_(None),
        )
        .order_by(EmailVerification.created_at.desc())
    )

    if verification is None:
        return False

    now = datetime.now(timezone.utc)

    if verification.expires_at < now:
        return False

    if not verify_verification_code(
        code,
        verification.code_hash,
    ):
        return False

    verification.used_at = now
    user.is_email_verified = True

    db.commit()
    db.refresh(user)

    return True