from __future__ import annotations

import re
from typing import Optional


def parse_price_fr(text: str | None) -> Optional[float]:
    if not text:
        return None
    # Exemple: "1 249,99 €" -> 1249.99 (gère espaces insécables)
    match = re.search(r"([0-9][0-9\s\.\u00a0\u202f]*(?:[,.][0-9]{2})?)", text)
    if not match:
        return None
    cleaned = match.group(1).replace(" ", "").replace("\u00a0", "").replace("\u202f", "")
    if "," in cleaned:
        cleaned = cleaned.replace(".", "").replace(",", ".")
    elif cleaned.count(".") == 1 and len(cleaned.split(".")[-1]) == 2:
        # conserve le point comme séparateur décimal
        pass
    else:
        cleaned = cleaned.replace(".", "")
    try:
        return float(cleaned)
    except ValueError:
        return None


def parse_rating_value(text: str | None) -> Optional[float]:
    if not text:
        return None
    match = re.search(r"([0-9]+(?:[\.,][0-9]+)?)", text)
    if not match:
        return None
    try:
        return float(match.group(1).replace(",", "."))
    except ValueError:
        return None


def parse_rating_count(text: str | None) -> Optional[int]:
    if not text:
        return None
    digits = re.sub(r"[^0-9]", "", text)
    if not digits:
        return None
    try:
        return int(digits)
    except ValueError:
        return None


def parse_stock_status(text: str | None) -> tuple[Optional[bool], Optional[str]]:
    if not text:
        return None, None
    cleaned = " ".join(text.split())
    lowered = cleaned.lower()
    if "en stock" in lowered or "disponible" in lowered:
        return True, cleaned
    if "indisponible" in lowered or "rupture" in lowered:
        return False, cleaned
    return None, cleaned
