from __future__ import annotations

from urllib.parse import urlparse

from app.modules.agent.engine.orchestrator.actions.common import ActionSupport
from app.modules.agent.engine.orchestrator.execution_context import ExecutionContext
from app.modules.agent.engine.orchestrator.models import ArtifactType


class ReviewActions(ActionSupport):
    def fetch_source_doc(self, ctx: ExecutionContext) -> list[str]:
        attachment = next((a for a in ctx.task.attachments if a.value), None)
        if attachment is None:
            text = ctx.task.user_message
            source_ref = "inline:message"
        else:
            parsed = urlparse(attachment.value)
            source_ref = attachment.value
            text = f"Source: {parsed.netloc}\nPath: {parsed.path}\nRequest: {ctx.task.user_message}"
        evidence_id = self.add_evidence(
            ctx,
            source_type="external_doc",
            source_ref=source_ref,
            snippet=text,
            score=0.75,
        )
        return [
            self.put(
                ctx,
                "source_doc_raw",
                ArtifactType.TEXT,
                text,
                meta={"source_ref": source_ref, "evidence_ids": [evidence_id]},
            )
        ]

    def normalize_document(self, ctx: ExecutionContext) -> list[str]:
        raw = str(self.get(ctx, "source_doc_raw", "") or "")
        normalized = "\n".join(line.rstrip() for line in raw.splitlines()).strip()
        return [self.put(ctx, "source_doc_text", ArtifactType.TEXT, normalized)]

    def structural_check(self, ctx: ExecutionContext) -> list[str]:
        text = str(self.get(ctx, "source_doc_text", "") or "")
        required = ["цель", "границ", "риски", "api", "данные"]
        found = [token for token in required if token in text.lower()]
        findings = {
            "required_sections": required,
            "found_markers": found,
            "missing_markers": [token for token in required if token not in found],
        }
        return [self.put(ctx, "structural_findings", ArtifactType.STRUCTURED_JSON, findings)]

    def semantic_consistency_check(self, ctx: ExecutionContext) -> list[str]:
        text = str(self.get(ctx, "source_doc_text", "") or "")
        contradictions = []
        if "без изменений" in text.lower() and "новый" in text.lower():
            contradictions.append("Contains both 'no changes' and 'new behavior' markers.")
        payload = {"contradictions": contradictions, "status": "ok" if not contradictions else "needs_attention"}
        return [self.put(ctx, "semantic_findings", ArtifactType.STRUCTURED_JSON, payload)]

    def architecture_fit_check(self, ctx: ExecutionContext) -> list[str]:
        text = str(self.get(ctx, "source_doc_text", "") or "")
        files_count = len(dict(ctx.task.metadata.get("files_map", {}) or {}))
        payload = {
            "architecture_fit": "medium" if files_count == 0 else "high",
            "notes": "Evaluate fit against existing docs and interfaces.",
            "markers": ["integration"] if "integr" in text.lower() else [],
        }
        return [self.put(ctx, "architecture_findings", ArtifactType.STRUCTURED_JSON, payload)]

    def optimization_check(self, ctx: ExecutionContext) -> list[str]:
        text = str(self.get(ctx, "source_doc_text", "") or "")
        has_perf = any(token in text.lower() for token in ("latency", "performance", "оптим"))
        payload = {
            "optimization_considered": has_perf,
            "recommendation": "Add explicit non-functional targets." if not has_perf else "Optimization criteria present.",
        }
        return [self.put(ctx, "optimization_findings", ArtifactType.STRUCTURED_JSON, payload)]

    def compose_review_report(self, ctx: ExecutionContext) -> list[str]:
        structural = self.get(ctx, "structural_findings", {}) or {}
        semantic = self.get(ctx, "semantic_findings", {}) or {}
        architecture = self.get(ctx, "architecture_findings", {}) or {}
        optimization = self.get(ctx, "optimization_findings", {}) or {}
        report = "\n".join(
            [
                "## Findings",
                f"- Missing structure markers: {', '.join(structural.get('missing_markers', [])) or 'none'}",
                f"- Contradictions: {len(semantic.get('contradictions', []))}",
                f"- Architecture fit: {architecture.get('architecture_fit', 'unknown')}",
                f"- Optimization: {optimization.get('recommendation', 'n/a')}",
                "",
                "## Recommendations",
                "- Clarify boundaries and data contracts.",
                "- Add explicit error and rollback behavior.",
                "- Add measurable non-functional requirements.",
            ]
        )
        return [
            self.put(ctx, "review_report", ArtifactType.REVIEW_REPORT, report),
            self.put(ctx, "final_answer", ArtifactType.TEXT, report),
        ]
