import re

# edited by glg

_IDENTIFIER_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")


def _to_bool(value, default=True):
    if isinstance(value, bool):
        return value
    if value is None:
        return bool(default)
    text = str(value).strip().lower()
    if text in {"1", "true", "yes", "on"}:
        return True
    if text in {"0", "false", "no", "off"}:
        return False
    return bool(default)


def _resolve_strict_mode(strict=None):
    if strict is not None:
        return bool(strict)
    try:
        from pypos.core.utils.config_utils import is_sql_identifier_strict_mode_enabled

        return bool(is_sql_identifier_strict_mode_enabled())
    except (ImportError, ModuleNotFoundError, RuntimeError, ValueError, TypeError):
        return True


def _normalize_identifier_segment(segment, strict=None):
    ident = str(segment or "").strip()
    if not ident:
        raise ValueError("Identifier SQL kosong.")
    if _IDENTIFIER_RE.match(ident):
        return ident
    if _resolve_strict_mode(strict):
        raise ValueError(f"Identifier SQL tidak valid: {segment}")

    # Compat mode: tetap normalize aman saat strict-mode dimatikan.
    fallback = re.sub(r"[^A-Za-z0-9_]", "", ident)
    if not fallback:
        raise ValueError(f"Identifier SQL tidak valid: {segment}")
    if fallback[0].isdigit():
        fallback = f"_{fallback}"
    if not _IDENTIFIER_RE.match(fallback):
        raise ValueError(f"Identifier SQL tidak valid: {segment}")
    return fallback


def normalize_sql_identifier(name, strict=None):
    ident = str(name or "").strip()
    if not ident:
        raise ValueError("Identifier SQL kosong.")

    # edited by glg
    # Dukung identifier qualified (alias.kolom) dengan validasi ketat per segmen.
    segments = [part.strip() for part in ident.split(".")]
    if not segments or any(not part for part in segments):
        raise ValueError(f"Identifier SQL tidak valid: {name}")

    normalized_segments = []
    for segment in segments:
        try:
            normalized_segments.append(_normalize_identifier_segment(segment, strict=strict))
        except ValueError as exc:
            if str(exc) == "Identifier SQL kosong.":
                raise
            raise ValueError(f"Identifier SQL tidak valid: {name}") from exc
    return ".".join(normalized_segments)


def is_sql_identifier_valid(name, strict=None):
    try:
        normalize_sql_identifier(name, strict=strict)
        return True
    except ValueError:
        return False


def quote_sql_identifier(name, strict=None):
    normalized = normalize_sql_identifier(name, strict=strict)
    segments = normalized.split(".")
    return ".".join(f'"{segment}"' for segment in segments)
