from datetime import datetime, timezone
from typing import Dict, List, Optional, Tuple
from uuid import UUID
from decimal import Decimal

from fastapi import HTTPException, status
from sqlalchemy import and_, func, or_
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session, aliased
from sqlalchemy.sql.expression import nullslast

from src.apps.currency.models.currency import CurrencyRate, Currency
from src.core.config import settings
from src.core.exceptions import APIException
from src.utils.constants import API_PREFIXES
from src.utils.pagination import QueryPaginator
from src.utils.constants import SYSTEM_BASE_CURRENCY


async def get_rates(
    db: Session
) -> Dict[str, Decimal]:
    """
    Fetches currency rates based on the system base currency.

    Args:
        session (Session): SQLAlchemy session for database interaction.

    Returns:
        Dict[str, Decimal]: A dictionary mapping currency codes and their aliases to rates.
    """
    try:
        currency_rates = {}

        # Query all rates with the base currency matching SYSTEM_BASE_CURRENCY
        rates = db.query(CurrencyRate).filter(CurrencyRate.base == SYSTEM_BASE_CURRENCY, CurrencyRate.deleted_at.is_(None)).all()

        for rate in rates:
            currency_rates[rate.currency] = rate.rate

            # Fetch aliases for the currency
            currency = db.query(Currency).filter(Currency.code == rate.currency).first()
            if currency and currency.aliases:
                for alias in currency.aliases:
                    currency_rates[alias] = rate.rate

        return currency_rates
    
    except Exception as e:
        raise APIException(
            module="get_rates",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            error={"exception": str(e)},
            message="Failed to fetch currency rates"
        )


