import json
import os


def normalize_points(raw_points):
    """Return route points as [(x, y), ...], dropping malformed entries."""
    points = []
    if not isinstance(raw_points, list):
        return points

    for point in raw_points:
        if not isinstance(point, (list, tuple)) or len(point) < 2:
            continue
        try:
            points.append((float(point[0]), float(point[1])))
        except (TypeError, ValueError):
            continue
    return points


def _looks_like_points(raw_value):
    if not isinstance(raw_value, list) or not raw_value:
        return False
    first = raw_value[0]
    if not isinstance(first, (list, tuple)) or len(first) < 2:
        return False
    try:
        float(first[0])
        float(first[1])
    except (TypeError, ValueError):
        return False
    return True


def normalize_route(raw_route, fallback_name=""):
    """Normalize {"name": ..., "points": ...} into a route dict."""
    if raw_route is None:
        return None

    if isinstance(raw_route, dict):
        name = str(raw_route.get("name") or fallback_name or "未命名路线").strip()
        raw_points = (
            raw_route.get("points")
            or raw_route.get("waypoints")
            or raw_route.get("path")
            or []
        )
    else:
        name = str(fallback_name or "未命名路线").strip()
        raw_points = raw_route

    points = normalize_points(raw_points)
    if not points:
        return None
    return {"name": name or fallback_name or "未命名路线", "points": points}


def normalize_route_list(raw_routes, fallback_prefix):
    routes = []
    if raw_routes is None:
        return routes

    if _looks_like_points(raw_routes):
        route = normalize_route(raw_routes, fallback_prefix)
        return [route] if route else []

    if isinstance(raw_routes, dict):
        raw_routes = raw_routes.get("routes") or raw_routes.get("items") or []

    if not isinstance(raw_routes, list):
        return routes

    for idx, raw_route in enumerate(raw_routes, start=1):
        route = normalize_route(raw_route, f"{fallback_prefix}{idx}")
        if route:
            routes.append(route)
    return routes


def normalize_route_profile(data, fallback_name=""):
    if not isinstance(data, dict):
        raise ValueError("路线方案 JSON 必须是对象格式")

    name = str(data.get("name") or fallback_name or "未命名方案").strip()
    patrol_routes = normalize_route_list(data.get("patrol_routes"), "巡逻路线")
    if not patrol_routes:
        raise ValueError("路线方案必须包含至少一条 patrol_routes")

    return {
        "name": name or fallback_name or "未命名方案",
        "prepare_route": normalize_route(data.get("prepare_route"), "准备路线"),
        "patrol_routes": patrol_routes,
        "resurrection_routes": normalize_route_list(data.get("resurrection_routes"), "复活路线"),
        "vendor_route": normalize_route(data.get("vendor_route"), "修理商路线"),
        "mailbox_route": normalize_route(data.get("mailbox_route"), "邮箱路线"),
    }


def load_route_profile(path):
    with open(path, "r", encoding="utf-8") as f:
        data = json.load(f)
    fallback_name = os.path.splitext(os.path.basename(path))[0]
    return normalize_route_profile(data, fallback_name=fallback_name)
