"""AI Agent LOG feedback receipt dry-run.

Transforms the LOG intelligence runtime sample readback into structured
candidate receipts for KM, RAG, PlayBook, MCP audit, verifier feedback, and AI
Agent decision context. This module is deliberately dry-run only: no KM writes,
no vector indexing, no PlayBook trust update, no MCP tool call, and no runtime
repair.
"""

from __future__ import annotations

from typing import Any

from src.services.ai_agent_log_intelligence_integration_readback import (
    load_latest_ai_agent_log_intelligence_integration_readback,
)

_SCHEMA_VERSION = "ai_agent_log_feedback_receipt_dry_run_v1"

_PIPELINE_NODES: tuple[dict[str, Any], ...] = (
    {
        "node_id": "collect_labeled_runtime_logs",
        "stage": "ingest",
        "target": "runtime_log_sample",
        "produces": "metadata_only_log_receipt",
    },
    {
        "node_id": "normalize_service_package_tool_labels",
        "stage": "label",
        "target": "label_taxonomy",
        "produces": "project_product_service_package_tool_labels",
    },
    {
        "node_id": "classify_signal_for_agent_context",
        "stage": "classify",
        "target": "agent_context",
        "produces": "signal_kind_and_risk_context",
    },
    {
        "node_id": "build_km_memory_candidates",
        "stage": "candidate",
        "target": "km",
        "produces": "km_memory_receipt_candidate",
    },
    {
        "node_id": "build_rag_chunk_candidates",
        "stage": "candidate",
        "target": "rag",
        "produces": "rag_chunk_receipt_candidate",
    },
    {
        "node_id": "build_playbook_trust_candidates",
        "stage": "candidate",
        "target": "playbook",
        "produces": "playbook_trust_receipt_candidate",
    },
    {
        "node_id": "build_mcp_audit_feedback_candidates",
        "stage": "candidate",
        "target": "mcp",
        "produces": "mcp_audit_feedback_candidate",
    },
    {
        "node_id": "bind_post_apply_verifier_feedback",
        "stage": "verify",
        "target": "verifier",
        "produces": "post_apply_verifier_feedback_receipt",
    },
    {
        "node_id": "publish_agent_decision_context_dry_run",
        "stage": "agent_context",
        "target": "ai_agent",
        "produces": "agent_decision_context_dry_run",
    },
)

_TARGETS = ("km", "rag", "playbook", "mcp", "verifier", "ai_agent")


def load_latest_ai_agent_log_feedback_receipt_dry_run() -> dict[str, Any]:
    """Return a dry-run receipt plan derived from runtime LOG samples."""
    source = load_latest_ai_agent_log_intelligence_integration_readback()
    rollups = source.get("rollups") or {}
    runtime_sample = source.get("runtime_e2e_verifier") or {}
    samples = _sample_rows(runtime_sample)
    runtime_ready = rollups.get("runtime_e2e_log_sample_readback_present") is True
    source_ready = (
        source.get("status") == "controlled_apply_ready_for_trusted_feedback_receipt"
        and rollups.get("ready_lane_count") == rollups.get("lane_count")
    )
    candidate_receipts = _candidate_receipts(samples)
    active_blockers = []
    if not source_ready:
        active_blockers.append("log_intelligence_source_readback_not_ready")
    if not runtime_ready:
        active_blockers.append("runtime_sample_receipt_missing")

    return {
        "schema_version": _SCHEMA_VERSION,
        "priority": "P1-LOG-KM-RAG-MCP-PLAYBOOK",
        "scope": "ai_agent_log_feedback_receipt_dry_run",
        "status": (
            "trusted_feedback_receipt_dry_run_ready"
            if not active_blockers
            else "blocked_waiting_log_intelligence_runtime_receipt"
        ),
        "readback": {
            "workplan_id": "P1-LOG-FEEDBACK-DRY-RUN",
            "workplan_title": "LOG 貼標後產出 KM / RAG / MCP / PlayBook / AI Agent dry-run receipt",
            "source_schema_version": source.get("schema_version"),
            "source_status": source.get("status"),
            "safe_next_step": "enable_post_write_verifier_for_km_rag_playbook_trust_receipts",
        },
        "pipeline_nodes": _pipeline_nodes(source_ready=source_ready, runtime_ready=runtime_ready),
        "candidate_receipts": candidate_receipts,
        "rollups": {
            "pipeline_node_count": len(_PIPELINE_NODES),
            "completed_node_count": len(_PIPELINE_NODES) if not active_blockers else 0,
            "target_count": len(_TARGETS),
            "candidate_receipt_count": len(candidate_receipts),
            "runtime_sample_count": len(samples),
            "source_lane_count": rollups.get("lane_count", 0),
            "source_ready_lane_count": rollups.get("ready_lane_count", 0),
            "dry_run_ready": not active_blockers,
            "km_candidate_count": _count_target(candidate_receipts, "km"),
            "rag_candidate_count": _count_target(candidate_receipts, "rag"),
            "playbook_candidate_count": _count_target(candidate_receipts, "playbook"),
            "mcp_candidate_count": _count_target(candidate_receipts, "mcp"),
            "verifier_candidate_count": _count_target(candidate_receipts, "verifier"),
            "ai_agent_context_candidate_count": _count_target(candidate_receipts, "ai_agent"),
        },
        "active_blockers": active_blockers,
        "operation_boundaries": {
            "dry_run_only": True,
            "km_write_performed": False,
            "rag_index_write_performed": False,
            "playbook_trust_write_performed": False,
            "mcp_tool_call_performed": False,
            "agent_runtime_action_performed": False,
            "post_apply_verifier_executed": False,
            "raw_log_payload_persisted": False,
            "secret_value_collection_allowed": False,
            "workflow_trigger_performed": False,
            "github_api_used": False,
        },
    }


def _pipeline_nodes(*, source_ready: bool, runtime_ready: bool) -> list[dict[str, Any]]:
    status = "dry_run_ready" if source_ready and runtime_ready else "blocked_waiting_source_receipt"
    return [
        {
            **node,
            "status": status,
            "write_enabled": False,
            "requires_post_write_verifier": node["target"] in {"km", "rag", "playbook", "verifier"},
        }
        for node in _PIPELINE_NODES
    ]


def _sample_rows(runtime_sample: dict[str, Any]) -> list[dict[str, Any]]:
    samples = runtime_sample.get("samples")
    if not isinstance(samples, list):
        return []
    rows = []
    for sample in samples:
        if not isinstance(sample, dict):
            continue
        classification = sample.get("classification")
        if not isinstance(classification, dict):
            classification = {}
        rows.append(
            {
                "sample_id": str(sample.get("sample_id") or ""),
                "service": str(sample.get("service") or ""),
                "source_system": str(sample.get("source_system") or ""),
                "project_id": str(sample.get("project_id") or ""),
                "product": str(sample.get("product") or ""),
                "package": str(sample.get("package") or ""),
                "tool": str(sample.get("tool") or ""),
                "redaction_state": str(sample.get("redaction_state") or ""),
                "observed_events": [str(item) for item in sample.get("observed_events") or []],
                "observed_fields": [str(item) for item in sample.get("observed_fields") or []],
                "classification": dict(classification),
            }
        )
    return rows


def _candidate_receipts(samples: list[dict[str, Any]]) -> list[dict[str, Any]]:
    receipts: list[dict[str, Any]] = []
    for sample in samples:
        for target in _TARGETS:
            receipts.append(
                {
                    "receipt_id": f"{sample['sample_id']}::{target}",
                    "target": target,
                    "source_sample_id": sample["sample_id"],
                    "project_id": sample["project_id"],
                    "product": sample["product"],
                    "service": sample["service"],
                    "package": sample["package"],
                    "tool": sample["tool"],
                    "source_system": sample["source_system"],
                    "redaction_state": sample["redaction_state"],
                    "observed_event_count": len(sample["observed_events"]),
                    "observed_field_count": len(sample["observed_fields"]),
                    "classification": sample["classification"],
                    "dry_run_status": "candidate_ready",
                    "write_enabled": False,
                    "raw_log_payload_persisted": False,
                }
            )
    return receipts


def _count_target(receipts: list[dict[str, Any]], target: str) -> int:
    return sum(1 for receipt in receipts if receipt.get("target") == target)
