"""Internal: convert Python values to json-five model nodes with double-quoted strings.

This module provides ``_modelize_json``, a custom modelizer that creates
``DoubleQuotedString`` nodes (instead of ``SingleQuotedString`` from
``json5.dumper.modelize``), so that ``ModelDumper`` output is valid JSON
or valid JSONC (JSON with comments) rather than JSON5 syntax.

This is the key difference that makes the output parseable by stdlib
``json`` while still preserving the model structure needed for comment
preservation via ``ModelDumper``.
"""

from __future__ import annotations

import json as stdlib_json
from typing import Any

from json5.dumper import modelize
from json5.model import (
    BooleanLiteral,
    DoubleQuotedString,
    Float,
    Integer,
    JSONArray,
    JSONObject,
    NullLiteral,
)


def modelize_json(value: Any, indent_level: int = 1) -> Any:
    """Convert a Python value to a json-five model with double-quoted strings.

    Unlike ``json5.dumper.modelize()`` (which creates ``SingleQuotedString``
    for all strings), this creates ``DoubleQuotedString`` nodes so
    ``ModelDumper`` output is valid JSON / JSONC rather than JSON5.

    Args:
        value: Any Python value (dict, list, str, int, float, bool, None).
        indent_level: Current indentation level (for whitespace before keys).

    Returns:
        A json-five model node.
    """
    indent = "  " * indent_level
    if value is None:
        return NullLiteral()
    if isinstance(value, bool):
        return BooleanLiteral(value=value)
    if isinstance(value, int):
        return Integer(raw_value=str(value), is_hex=False, is_octal=False)
    if isinstance(value, float):
        return Float(raw_value=str(value), value=value)
    if isinstance(value, str):
        raw = stdlib_json.dumps(value)
        return DoubleQuotedString(characters=value, raw_value=raw)
    if isinstance(value, list):
        arr = JSONArray(trailing_comma=None)
        for item in value:
            arr.values.append(modelize_json(item, indent_level + 1))
        return arr
    if isinstance(value, dict):
        obj = JSONObject(trailing_comma=None)
        for k, v in value.items():
            key_str = str(k)
            key = DoubleQuotedString(
                characters=key_str,
                raw_value=stdlib_json.dumps(key_str),
            )
            key.wsc_before = [f"\n{indent}"]
            obj.keys.append(key)
            obj.values.append(modelize_json(v, indent_level + 1))
        return obj
    # Fallback to modelize for any type not handled above
    return modelize(value)
