from .asset_map import get_request_path
import json
from ..util import Template


def _extract_raw_fields(kwargs):
    """Separate values that would break JSON-in-Jinja2 rendering.
    
    Multi-line strings or strings with quotes cannot be safely embedded
    inside a Jinja2 template that is itself JSON. These are replaced
    with sentinel placeholders, then restored after JSON parsing.
    """
    raw_fields = {}
    for key in list(kwargs.keys()):
        val = kwargs[key]
        if isinstance(val, str) and ('\n' in val or '\r' in val or '"' in val):
            raw_fields[key] = val
            kwargs[key] = f"__RAW_{key}__"
    return raw_fields


def _restore_raw_fields(data, raw_fields):
    for key, val in raw_fields.items():
        placeholder = f"__RAW_{key}__"
        for k, v in data.items():
            if v == placeholder:
                # Try to parse as JSON if it looks like a JSON value
                if val.startswith(('[', '{')):
                    try:
                        data[k] = json.loads(val)
                    except json.JSONDecodeError:
                        data[k] = val
                else:
                    data[k] = val


def update_asset_request(asset_type, operation_type="update", name=None, data=None, **kwargs):
    path, method, example = get_request_path(asset_type, operation_type)
    if method.lower() == "update":
        method = "put"
    example = json.dumps(example, ensure_ascii=False)
    if name is not None and "name" not in kwargs:
        kwargs.update({"name": name})
    path = Template(path).render(**kwargs)

    raw_fields = _extract_raw_fields(kwargs)
    example = Template(example).render(**kwargs)
    example = json.loads(example)
    _restore_raw_fields(example, raw_fields)
    _restore_raw_fields(kwargs, raw_fields)

    if not data:
        data = example
    else:
        data = {**example, **data, **kwargs}
    return {
        "path": path,
        "query_params": {},
        # list 操作用不到的内容
        "method": method,
        "data": data,
        "custom_headers": {},
    }
