"""OPC 创业基因测评 · 计分逻辑（移植自 website/server/opcTest.js）"""
from . import opc_data

QUESTIONS = opc_data.QUESTIONS
RULES = opc_data.RULES
PROFILES = opc_data.PROFILES

RULE_MAP = {r["id"]: r for r in RULES}
ADAPT_DIMS = ["IND", "RISK", "DRIVE", "SOLO", "AI", "STABLE"]
ADAPT_LABELS = {"IND": "独立自主", "RISK": "风险承受", "DRIVE": "自驱动力", "SOLO": "单兵多面", "AI": "AI 意愿", "STABLE": "安全垫"}
AXIS_PAIRS = [("E", "I"), ("V", "G"), ("R", "T"), ("P", "F")]
AXIS_NAMES = {"EI": "能量", "VG": "视野", "RT": "价值", "PF": "节奏"}
SECTIONS = {
    "P1": "第一部分 · 创业内核（独立 / 风险 / 自驱 / 单兵 / AI / 安全垫）",
    "P2": "第二部分 · 特质倾向（能量 / 视野 / 价值 / 节奏）",
    "P3": "第三部分 · 赛道偏好（文旅 / 内容IP / 咨询 / 电商 / 跨境 / 本地）",
    "P4": "第四部分 · 角色偏向（产品 / 内容 / 商务 / 运营 / 架构）",
    "P5": "第五部分 · 人机协作（对话 / 自动化 / 智能体 / 外包）",
}


def current_questions(version):
    return [q for q in QUESTIONS if q["quick"]] if version == "quick" else QUESTIONS


def _get_ans(answers, qid):
    """兼容：answers 键可能是字符串或数字"""
    if qid in answers:
        return answers[qid]
    if str(qid) in answers:
        return answers[str(qid)]
    return None


def calculate(answers, version="full"):
    ids = [q["id"] for q in current_questions(version)]
    counts = {}
    for qid in ids:
        ans = _get_ans(answers, qid)
        if ans not in ("A", "B"):
            continue
        rule = RULE_MAP.get(qid)
        if not rule:
            continue
        code = rule["A"] if ans == "A" else rule["B"]
        if code:
            counts[code] = counts.get(code, 0) + 1

    adapt_dims = []
    adapt_sum = 0
    for dim in ADAPT_DIMS:
        mx = sum(1 for qid in ids for r in [RULE_MAP.get(qid)] if r and (r.get("A") == dim or r.get("B") == dim))
        votes = counts.get(dim, 0)
        score = round(votes / mx * 100) if mx > 0 else 0
        adapt_sum += score
        adapt_dims.append({"code": dim, "label": ADAPT_LABELS[dim], "score": score, "votes": votes, "max": mx})

    adapt_index = round(adapt_sum / len(ADAPT_DIMS))
    adapt_level = next((lv for lv in PROFILES["adaptLevels"] if lv["range"][0] <= adapt_index <= lv["range"][1]), None)
    weakest_dims = sorted(adapt_dims, key=lambda d: d["score"])[:2]

    type_code = ""
    axes_detail = []
    for left, right in AXIS_PAIRS:
        l = counts.get(left, 0)
        r = counts.get(right, 0)
        total = l + r
        letter = left if l >= r else right
        type_code += letter
        axes_detail.append({
            "pair": left + right, "left": l, "right": r,
            "leftPct": round(l / total * 100) if total > 0 else 50,
            "rightPct": round(r / total * 100) if total > 0 else 50,
            "winner": letter, "lCount": l, "rCount": r,
        })

    persona = next((p for p in PROFILES["personas"] if p["code"] == type_code), None)

    def rank(dims):
        total = sum(counts.get(d, 0) for d in dims)
        res = []
        for d in dims:
            v = counts.get(d, 0)
            res.append({"code": d, "votes": v, "pct": round(v / total * 100) if total > 0 else 0})
        res.sort(key=lambda x: (-x["votes"], x["code"]))
        return res

    tracks = [t for t in rank([t["code"] for t in PROFILES["tracks"]]) if t["pct"] >= 10][:3]
    roles = [x for x in rank([x["code"] for x in PROFILES["roles"]]) if x["pct"] >= 5][:2]
    tools = [t for t in rank([t["code"] for t in PROFILES["toolModes"]]) if t["pct"] >= 5][:2]

    answered_count = sum(1 for qid in ids if _get_ans(answers, qid) in ("A", "B"))

    return {
        "version": version, "answeredCount": answered_count, "typeCode": type_code, "persona": persona,
        "adaptIndex": adapt_index, "adaptLevel": adapt_level, "adaptDims": adapt_dims, "weakestDims": weakest_dims,
        "axesDetail": axes_detail, "tracks": tracks, "roles": roles, "tools": tools,
    }


def expand_result(r):
    def find(lst, code):
        return next((x for x in lst if x["code"] == code), {})

    return {
        **r,
        "tracks": [{**t, **find(PROFILES["tracks"], t["code"])} for t in r["tracks"]],
        "roles": [{**x, **find(PROFILES["roles"], x["code"])} for x in r["roles"]],
        "tools": [{**x, **find(PROFILES["toolModes"], x["code"])} for x in r["tools"]],
    }
