from __future__ import annotations

from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
from typing import Any, Dict, List


def _to_decimal(value: Any, default: Decimal = Decimal("0")) -> Decimal:
    if value is None:
        return default
    if isinstance(value, Decimal):
        return value
    if isinstance(value, (int, float)):
        return Decimal(str(value))
    if isinstance(value, str):
        s = value.strip()
        if not s:
            return default
        if "e" in s.lower():
            raise ValueError("Scientific notation is not allowed.")
        if "," in s and "." in s:
            last_dot = s.rfind(".")
            last_comma = s.rfind(",")
            if last_comma > last_dot:
                s = s.replace(".", "").replace(",", ".")
            else:
                s = s.replace(",", "")
        else:
            s = s.replace(",", ".")
        try:
            return Decimal(s)
        except InvalidOperation:
            return default
    try:
        return Decimal(str(value))
    except Exception:
        return default


def _money(value: Decimal) -> Decimal:
    return value.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)


def _normalize_rate(rate: Any) -> Decimal:
    raw = _to_decimal(rate, default=Decimal("0"))
    if raw < 0:
        return Decimal("0")
    if raw > 1:
        raw = raw / Decimal("100")
    return raw


def hesapla(
    miktar: Any,
    fiyat: Any,
    vergi: Any = 0,
    iskonto: Any = 0,
) -> Dict[str, float]:
    """
    Tek merkezli tutar hesaplama:
    net = miktar * fiyat
    vergi_tutar = net * vergi_orani
    iskonto_tutar = net * iskonto_orani
    toplam = net + vergi_tutar - iskonto_tutar
    """
    qty = _to_decimal(miktar, default=Decimal("0"))
    unit = _to_decimal(fiyat, default=Decimal("0"))
    tax_rate = _normalize_rate(vergi)
    discount_rate = _normalize_rate(iskonto)

    net = qty * unit
    tax_amount = net * tax_rate
    discount_amount = net * discount_rate
    total = net + tax_amount - discount_amount

    net_m = _money(net)
    tax_m = _money(tax_amount)
    discount_m = _money(discount_amount)
    total_m = _money(total)

    return {
        "miktar": float(qty),
        "fiyat": float(_money(unit)),
        "net": float(net_m),
        "vergi": float(tax_m),
        "iskonto": float(discount_m),
        "toplam": float(total_m),
    }


def grid_to_json(rows: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
    clean_rows: List[Dict[str, Any]] = []
    for row in rows or []:
        if not isinstance(row, dict):
            continue
        clean_row: Dict[str, Any] = {}
        for k, v in row.items():
            if isinstance(k, str):
                clean_row[k] = v
        if clean_row:
            clean_rows.append(clean_row)
    return clean_rows


def parse_decimal_input(raw_text: str, *, allow_zero: bool = True) -> float:
    value = float(_to_decimal(raw_text, default=Decimal("0")))
    if not allow_zero and value <= 0:
        raise ValueError("Value must be greater than zero.")
    if value < 0:
        raise ValueError("Negative values are not allowed.")
    if value > 999_999_999:
        raise ValueError("Value is too large.")
    return value


def log_islem(tip: str, miktar: Any, tutar: Any, vergi: Any, net: Any) -> None:
    print("İşlem:", tip, miktar, tutar, vergi, net)




