#!/usr/bin/env python3
"""Predict meeting-minutes evidence labels for a trained MiniLM bundle."""
from __future__ import annotations

import argparse
from pathlib import Path
import joblib
import numpy as np
from sentence_transformers import SentenceTransformer


def print_ranked(title, classes, probs, limit=5):
    print(title)
    order = np.argsort(-probs)
    for i in order[:limit]:
        print(f"  {classes[i]:30} {probs[i]:.3f}")


def main() -> int:
    ap = argparse.ArgumentParser()
    ap.add_argument("text", nargs="?", help="Text to classify")
    ap.add_argument("--text-file", help="Read text from file")
    ap.add_argument("--model", default="models/production/classifier.joblib")
    ap.add_argument("--top-signals", type=int, default=6)
    args = ap.parse_args()

    text = Path(args.text_file).read_text().strip() if args.text_file else (args.text or "").strip()
    if not text:
        print("Provide text as an argument or with --text-file")
        return 2

    bundle = joblib.load(args.model)
    embedder = SentenceTransformer(bundle["embedding_model"])
    X = embedder.encode([text], normalize_embeddings=True, convert_to_numpy=True, show_progress_bar=False)

    status_probs = bundle["status_classifier"].predict_proba(X)[0]
    print_ranked("Evidence type:", bundle["status_label_encoder"].classes_, status_probs)

    action_clf = bundle.get("action_state_classifier")
    action_le = bundle.get("action_state_label_encoder")
    if action_clf is not None and action_le is not None:
        action_probs = action_clf.predict_proba(X)[0]
        print()
        print_ranked("Commitment state:", action_le.classes_, action_probs)

    signal_clf = bundle.get("signal_classifier")
    mlb = bundle.get("signal_binarizer")
    threshold = float(bundle.get("signal_threshold", 0.5))
    print("\nSignals:")
    if signal_clf is None or mlb is None or not len(getattr(mlb, "classes_", [])):
        print("  signal model unavailable — add more signal-labelled data and retrain")
    else:
        signal_probs = np.asarray(signal_clf.predict_proba(X))[0]
        order = np.argsort(-signal_probs)
        predicted = [(mlb.classes_[i], signal_probs[i]) for i in order if signal_probs[i] >= threshold]
        if predicted:
            for label, prob in predicted:
                print(f"  {label:30} {prob:.3f}")
        else:
            print("  none above threshold")
        print("\nTop signal scores:")
        for i in order[: args.top_signals]:
            print(f"  {mlb.classes_[i]:30} {signal_probs[i]:.3f}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
