"""
Decimal manipulation functions.

.. deprecated:: 0.13.0
   This module is deprecated. Use `std.numbers` instead.

This module provides functions for working with decimal numbers including
type construction, parsing from strings, and querying decimal properties.
"""
from __future__ import annotations

from ..frontend.base import Concept, NumberConcept, Expression, Variable
from relationalai.util.docutils import include_in_docs

from . import NumberValue, StringValue, numbers, _deprecated_library

__include_in_docs__ = True


#--------------------------------------------------
# Constructors
#--------------------------------------------------

@include_in_docs
def decimal(value: NumberValue, precision:int=38, scale:int=14) -> Variable:
    """
    Create a decimal with specified precision and scale.

    .. deprecated:: 0.13.0
       Use `numbers.number(value, precision, scale) <std.numbers.number>` instead.

    Parameters
    ----------
    value: NumberValue
        The numeric value.
    precision: int
        The precision (total number of digits).
    scale: int
        The scale (number of decimal places).

    Returns
    -------
    Variable
        A Variable representing the decimal value.
    """
    _warning(f"numbers.number({value}, {precision}, {scale})")
    return numbers.number(value, precision, scale)

@include_in_docs
def parse_decimal(value: StringValue, precision:int=38, scale:int=14) -> Expression:
    """
    Parse a string into a decimal with specified precision and scale.

    .. deprecated:: 0.13.0
       Use `numbers.parse_number(value, precision, scale) <std.numbers.parse_number>` instead.

    Parameters
    ----------
    value: StringValue
        The string value to parse.
    precision: int
        The precision (total number of digits).
    scale: int
        The scale (number of decimal places).

    Returns
    -------
    Expression
        An Expression computing the parsed decimal.
    """
    _warning(f"numbers.parse_number({value}, {precision}, {scale})")
    return numbers.parse_number(value, precision, scale)

@include_in_docs
def parse(value: StringValue, decimal: Concept) -> Expression:
    """
    Parse a string into a decimal with the type specified by decimal concept.

    .. deprecated:: 0.13.0
       Use `numbers.parse(value, decimal) <std.numbers.parse>` instead.

    Parameters
    ----------
    value: StringValue
        The string value to parse.
    decimal: Concept
        The NumberConcept specifying the decimal type.

    Returns
    -------
    Expression
        An Expression computing the parsed decimal.
    """
    assert isinstance(decimal, NumberConcept)
    _warning(f"numbers.parse({value}, {decimal})")
    return numbers.parse(value, decimal)

#--------------------------------------------------
# Decimal information
#--------------------------------------------------

@include_in_docs
def is_decimal(decimal: Concept) -> bool:
    """
    Check if a concept represents a decimal number.

    .. deprecated:: 0.13.0
       Use `numbers.is_number(decimal) <std.numbers.is_number>` instead.

    Parameters
    ----------
    decimal: Concept
        The NumberConcept to check.

    Returns
    -------
    bool
        True if the concept is a decimal number.
    """
    assert isinstance(decimal, NumberConcept)
    _warning(f"numbers.is_number({decimal})")
    return numbers.is_number(decimal)

@include_in_docs
def precision(decimal: Concept) -> int:
    """
    Get the precision (total number of digits) of a decimal concept.

    .. deprecated:: 0.13.0
       Use `numbers.precision(decimal) <std.numbers.precision>` instead.

    Parameters
    ----------
    decimal: Concept
        The NumberConcept to query.

    Returns
    -------
    int
        The precision of the decimal.
    """
    assert isinstance(decimal, NumberConcept)
    _warning(f"numbers.precision({decimal})")
    return numbers.precision(decimal)

@include_in_docs
def scale(decimal: Concept) -> int:
    """
    Get the scale (number of decimal places) of a decimal concept.

    .. deprecated:: 0.13.0
       Use `numbers.scale(decimal) <std.numbers.scale>` instead.

    Parameters
    ----------
    decimal: Concept
        The NumberConcept to query.

    Returns
    -------
    int
        The scale of the decimal.
    """
    assert isinstance(decimal, NumberConcept)
    _warning(f"numbers.scale({decimal})")
    return numbers.scale(decimal)

@include_in_docs
def size(decimal: Concept) -> int:
    """
    Get the size (in bytes) of a decimal concept.

    .. deprecated:: 0.13.0
       Use `numbers.size(decimal) <std.numbers.size>` instead.

    Parameters
    ----------
    decimal: Concept
        The NumberConcept to query.

    Returns
    -------
    int
        The size in bytes of the decimal.
    """
    assert isinstance(decimal, NumberConcept)
    _warning(f"numbers.size({decimal})")
    return numbers.size(decimal)


#--------------------------------------------------
# Implementation
#--------------------------------------------------

def _warning(example: str):
    _deprecated_library("std.decimals", "std.numbers", example)
