# geney/visualization/_transcription.py — Transcription card data for frontend.
#
# Produces a JSON-serializable dict with:
#   - Per-tissue log2 fold-changes (sorted by magnitude, top N)
#   - Max affected tissue
#   - Count of affected tissues
#
# The frontend draws: horizontal bar chart of tissue fold-changes.
from __future__ import annotations

from ..results import TranscriptionResult

# Max tissues to include in card data (keeps payload small)
_MAX_TISSUES = 20
_LFC_THRESHOLD = 0.152  # Same as prediction.py


def transcription_card(transcription: TranscriptionResult | None) -> dict:
    """Build transcription card data for frontend rendering.

    Returns:
        JSON-serializable dict with tissue fold-change data.
    """
    if transcription is None:
        return {"type": "transcription", "score": 0.0, "status": "not_run"}

    if transcription.status != "completed":
        return {
            "type": "transcription",
            "score": 0.0,
            "status": transcription.status,
            "reason": transcription.reason,
        }

    # Build tissue list sorted by |log2FC|
    tissues = []
    for name, lfc in transcription.tissue_fold_changes.items():
        tissues.append({
            "name": name,
            "log2fc": round(float(lfc), 4),
            "affected": abs(float(lfc)) >= _LFC_THRESHOLD,
        })

    tissues.sort(key=lambda t: abs(t["log2fc"]), reverse=True)
    tissues = tissues[:_MAX_TISSUES]

    return {
        "type": "transcription",
        "score": round(min(10.0, transcription.score), 1),
        "status": "completed",
        "max_tissue": transcription.max_lfc_tissue,
        "max_lfc": round(transcription.max_lfc_value, 4),
        "max_abs_lfc": round(transcription.max_abs_lfc, 4),
        "num_affected": transcription.num_affected_tissues,
        "tissues": tissues,
    }
