"""Standards readiness scoring — composite 0-100 score predicting RFC proximity."""

from __future__ import annotations


def compute_readiness(db, draft_name: str) -> dict:
    """Compute 0-100 readiness score with component breakdown.

    Factors (each 0-1, weighted):
    - wg_adopted (0.25): name starts with 'draft-ietf-' = 1.0, else 0.0
    - revision_maturity (0.15): int(rev) normalized (0-5+ maps to 0-1)
    - reference_density (0.15): len(draft_refs) / max_refs across corpus
    - cited_by_count (0.15): how many OTHER drafts in corpus reference this one
    - author_experience (0.15): avg number of drafts per author in draft_authors
    - momentum_rating (0.15): momentum score from ratings (1-5 -> 0-1)

    Returns {score: 0-100, factors: {name: {value, weight, contribution}}}
    """
    draft = db.get_draft(draft_name)
    if not draft:
        return {"score": 0, "factors": {}}

    factors = {}

    # 1. WG Adopted (0.25)
    wg_val = 1.0 if draft_name.startswith("draft-ietf-") else 0.0
    factors["wg_adopted"] = {"value": wg_val, "weight": 0.25,
                             "label": "WG Adopted",
                             "detail": "draft-ietf-*" if wg_val else "individual"}

    # 2. Revision Maturity (0.15)
    try:
        rev_num = int(draft.rev) if draft.rev else 0
    except (ValueError, TypeError):
        rev_num = 0
    rev_val = min(rev_num / 5.0, 1.0)
    factors["revision_maturity"] = {"value": round(rev_val, 3), "weight": 0.15,
                                    "label": "Revision Maturity",
                                    "detail": f"rev {rev_num}"}

    # 3. Reference Density (0.15)
    refs = db.get_refs_for_draft(draft_name)
    ref_count = len(refs)
    # Get max refs across corpus
    max_refs = db.conn.execute(
        "SELECT MAX(cnt) FROM (SELECT COUNT(*) as cnt FROM draft_refs GROUP BY draft_name)"
    ).fetchone()[0] or 1
    ref_val = min(ref_count / max_refs, 1.0)
    factors["reference_density"] = {"value": round(ref_val, 3), "weight": 0.15,
                                    "label": "Reference Density",
                                    "detail": f"{ref_count} refs (max {max_refs})"}

    # 4. Cited By Count (0.15)
    cited_by = db.conn.execute(
        "SELECT COUNT(DISTINCT draft_name) FROM draft_refs WHERE ref_type = 'draft' AND ref_id = ?",
        (draft_name,),
    ).fetchone()[0]
    # Normalize: being cited by 5+ drafts = 1.0
    cited_val = min(cited_by / 5.0, 1.0)
    factors["cited_by_count"] = {"value": round(cited_val, 3), "weight": 0.15,
                                 "label": "Cited By Others",
                                 "detail": f"{cited_by} draft(s)"}

    # 5. Author Experience (0.15)
    authors = db.get_authors_for_draft(draft_name)
    if authors:
        author_draft_counts = []
        for a in authors:
            cnt = db.conn.execute(
                "SELECT COUNT(*) FROM draft_authors WHERE person_id = ?",
                (a.person_id,),
            ).fetchone()[0]
            author_draft_counts.append(cnt)
        avg_exp = sum(author_draft_counts) / len(author_draft_counts)
        # Normalize: avg 5+ drafts per author = 1.0
        exp_val = min(avg_exp / 5.0, 1.0)
    else:
        exp_val = 0.0
        avg_exp = 0
    factors["author_experience"] = {"value": round(exp_val, 3), "weight": 0.15,
                                    "label": "Author Experience",
                                    "detail": f"avg {avg_exp:.1f} drafts/author"}

    # 6. Momentum Rating (0.15)
    rating = db.get_rating(draft_name)
    if rating:
        mom_val = (rating.momentum - 1) / 4.0  # 1-5 -> 0-1
    else:
        mom_val = 0.0
    factors["momentum_rating"] = {"value": round(mom_val, 3), "weight": 0.15,
                                  "label": "Momentum",
                                  "detail": f"{rating.momentum}/5" if rating else "unrated"}

    # Compute weighted score
    total = sum(f["value"] * f["weight"] for f in factors.values())
    score = round(total * 100, 1)

    # Add contribution to each factor
    for f in factors.values():
        f["contribution"] = round(f["value"] * f["weight"] * 100, 1)

    return {"score": score, "factors": factors}


def compute_readiness_batch(db, draft_names: list[str]) -> dict[str, dict]:
    """Batch-compute readiness for multiple drafts using bulk queries.

    Returns {draft_name: {score, factors}} — same format as compute_readiness.
    Reduces ~6 queries per draft to ~6 queries total.
    """
    if not draft_names:
        return {}

    # Batch-load drafts
    drafts_map = db.get_drafts_by_names(draft_names)

    # Batch-load ref counts per draft
    ref_counts: dict[str, int] = {}
    rows = db.conn.execute(
        "SELECT draft_name, COUNT(*) as cnt FROM draft_refs GROUP BY draft_name"
    ).fetchall()
    for r in rows:
        ref_counts[r["draft_name"]] = r["cnt"]

    # Max refs across corpus (single query)
    max_refs_row = db.conn.execute(
        "SELECT MAX(cnt) FROM (SELECT COUNT(*) as cnt FROM draft_refs GROUP BY draft_name)"
    ).fetchone()
    max_refs = (max_refs_row[0] or 1) if max_refs_row else 1

    # Batch-load cited-by counts
    cited_by_counts: dict[str, int] = {}
    rows = db.conn.execute(
        "SELECT ref_id, COUNT(DISTINCT draft_name) as cnt FROM draft_refs "
        "WHERE ref_type = 'draft' GROUP BY ref_id"
    ).fetchall()
    for r in rows:
        cited_by_counts[r["ref_id"]] = r["cnt"]

    # Batch-load author experience: person_id -> draft count
    author_draft_counts: dict[int, int] = {}
    rows = db.conn.execute(
        "SELECT person_id, COUNT(*) as cnt FROM draft_authors GROUP BY person_id"
    ).fetchall()
    for r in rows:
        author_draft_counts[r["person_id"]] = r["cnt"]

    # Batch-load draft->author mappings
    draft_authors: dict[str, list[int]] = {}
    rows = db.conn.execute(
        "SELECT draft_name, person_id FROM draft_authors"
    ).fetchall()
    for r in rows:
        draft_authors.setdefault(r["draft_name"], []).append(r["person_id"])

    # Batch-load ratings (momentum)
    ratings_map: dict[str, float] = {}
    rows = db.conn.execute(
        "SELECT draft_name, momentum FROM ratings"
    ).fetchall()
    for r in rows:
        ratings_map[r["draft_name"]] = r["momentum"]

    # Now compute readiness for each draft using pre-loaded data
    results = {}
    for name in draft_names:
        draft = drafts_map.get(name)
        if not draft:
            results[name] = {"score": 0, "factors": {}}
            continue

        factors = {}

        # 1. WG Adopted
        wg_val = 1.0 if name.startswith("draft-ietf-") else 0.0
        factors["wg_adopted"] = {"value": wg_val, "weight": 0.25,
                                 "label": "WG Adopted",
                                 "detail": "draft-ietf-*" if wg_val else "individual"}

        # 2. Revision Maturity
        try:
            rev_num = int(draft.rev) if draft.rev else 0
        except (ValueError, TypeError):
            rev_num = 0
        rev_val = min(rev_num / 5.0, 1.0)
        factors["revision_maturity"] = {"value": round(rev_val, 3), "weight": 0.15,
                                        "label": "Revision Maturity",
                                        "detail": f"rev {rev_num}"}

        # 3. Reference Density
        ref_count = ref_counts.get(name, 0)
        ref_val = min(ref_count / max_refs, 1.0)
        factors["reference_density"] = {"value": round(ref_val, 3), "weight": 0.15,
                                        "label": "Reference Density",
                                        "detail": f"{ref_count} refs (max {max_refs})"}

        # 4. Cited By Count
        cited_by = cited_by_counts.get(name, 0)
        cited_val = min(cited_by / 5.0, 1.0)
        factors["cited_by_count"] = {"value": round(cited_val, 3), "weight": 0.15,
                                     "label": "Cited By Others",
                                     "detail": f"{cited_by} draft(s)"}

        # 5. Author Experience
        person_ids = draft_authors.get(name, [])
        if person_ids:
            counts = [author_draft_counts.get(pid, 1) for pid in person_ids]
            avg_exp = sum(counts) / len(counts)
            exp_val = min(avg_exp / 5.0, 1.0)
        else:
            exp_val = 0.0
            avg_exp = 0
        factors["author_experience"] = {"value": round(exp_val, 3), "weight": 0.15,
                                        "label": "Author Experience",
                                        "detail": f"avg {avg_exp:.1f} drafts/author"}

        # 6. Momentum Rating
        momentum = ratings_map.get(name)
        if momentum is not None:
            mom_val = (momentum - 1) / 4.0
        else:
            mom_val = 0.0
        factors["momentum_rating"] = {"value": round(mom_val, 3), "weight": 0.15,
                                      "label": "Momentum",
                                      "detail": f"{momentum}/5" if momentum else "unrated"}

        # Compute weighted score
        total = sum(f["value"] * f["weight"] for f in factors.values())
        score = round(total * 100, 1)
        for f in factors.values():
            f["contribution"] = round(f["value"] * f["weight"] * 100, 1)

        results[name] = {"score": score, "factors": factors}

    return results
