"""Feedback labels and aggregate metrics for human-review decisions."""

import json
import os
from datetime import datetime

from backend.review.feedback import decision_to_label, write_label
from backend.review.metrics import aggregate_labels


def test_aggregate_redacts_text_by_default():
    labels = [{"decision": "reject", "reason_code": "missing_evidence", "comment": "secret", "payload": {"evidence": [{"source_text": "secret"}]}}]
    summary = aggregate_labels(labels)
    assert summary["reject"] == 1
    assert "secret" not in str(summary)


def test_aggregate_include_text_embeds_labels():
    labels = [{"decision": "reject", "reason_code": "missing_evidence", "comment": "secret"}]
    summary = aggregate_labels(labels, include_text=True)
    assert summary["labels"] == labels


def _queue_item() -> dict:
    return {
        "review_item_id": "finding:AGENT-0007",
        "kind": "finding",
        "blocking": True,
        "reasons": ["high_severity"],
        "payload": {
            "issue_id": "AGENT-0007",
            "source_stage": "conflict",
            "category": "elevation_disagreement",
            "severity": "high",
            "confidence": "medium",
            "location": "Room 204 / Level 2",
            "disciplines": ["Architectural", "Mechanical"],
            "sheets": ["A2.1", "M2.1"],
            "drawing_type": "floor_plan",
        },
    }


def test_decision_to_label_builds_spec_shape():
    decision = {"review_item_id": "finding:AGENT-0007", "decision": "reject",
                "reason_code": "same_value_different_representation"}
    job = {"job_id": "abc123", "pipeline_mode": "agent",
           "report": {"summary": {"models_used": ["google/gemini-2.5-pro"]}}}
    label = decision_to_label(_queue_item(), decision, job)
    assert label["review_item_id"] == "finding:AGENT-0007"
    assert label["job_id"] == "abc123"
    assert label["pipeline_mode"] == "agent"
    assert label["source_stage"] == "conflict"
    assert label["category"] == "elevation_disagreement"
    assert label["severity"] == "high"
    assert label["confidence"] == "medium"
    assert label["decision"] == "reject"
    assert label["reason_code"] == "same_value_different_representation"
    assert label["location"] == "Room 204 / Level 2"
    assert label["disciplines"] == ["Architectural", "Mechanical"]
    assert label["sheets"] == ["A2.1", "M2.1"]
    assert label["drawing_type"] == "floor_plan"
    assert label["models_used"] == ["google/gemini-2.5-pro"]
    datetime.fromisoformat(label["created_at"])


def test_decision_to_label_degrades_on_missing_fields():
    label = decision_to_label({"review_item_id": "finding:AGENT-0001"}, {}, {})
    assert label["review_item_id"] == "finding:AGENT-0001"
    assert label["job_id"] is None
    assert label["decision"] is None
    assert label["reason_code"] is None
    assert label["category"] is None
    assert label["source_stage"] is None
    assert label["models_used"] == []
    datetime.fromisoformat(label["created_at"])


def test_write_label_appends_json_lines(tmp_path):
    label1 = {"review_item_id": "finding:AGENT-0001", "decision": "confirm"}
    label2 = {"review_item_id": "finding:AGENT-0002", "decision": "reject"}
    write_label(str(tmp_path), label1)
    write_label(str(tmp_path), label2)
    path = os.path.join(str(tmp_path), "review", "feedback_labels.jsonl")
    with open(path, encoding="utf-8") as f:
        lines = [json.loads(line) for line in f if line.strip()]
    assert lines == [label1, label2]
