from __future__ import annotations

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 GherkinActions(ActionSupport):
    def extract_increment_scope(self, ctx: ExecutionContext) -> list[str]:
        text = str(self.get(ctx, "source_doc_text", "") or ctx.task.user_message)
        scope = {
            "title": "Increment scope",
            "summary": text[:220],
            "entities": ["User", "System"],
        }
        return [self.put(ctx, "increment_scope", ArtifactType.STRUCTURED_JSON, scope)]

    def partition_features(self, ctx: ExecutionContext) -> list[str]:
        scope = self.get(ctx, "increment_scope", {}) or {}
        groups = [
            {"feature": "Main flow", "goal": scope.get("summary", "")},
            {"feature": "Validation", "goal": "Input validation and error behavior"},
        ]
        return [self.put(ctx, "feature_groups", ArtifactType.STRUCTURED_JSON, groups)]

    def generate_gherkin_bundle(self, ctx: ExecutionContext) -> list[str]:
        groups = self.get(ctx, "feature_groups", []) or []
        files = []
        for idx, group in enumerate(groups, start=1):
            feature_name = str(group.get("feature", f"Feature {idx}"))
            content = "\n".join(
                [
                    f"Feature: {feature_name}",
                    "  Scenario: Happy path",
                    "    Given system is available",
                    "    When user performs increment action",
                    "    Then system applies expected increment behavior",
                ]
            )
            files.append({"path": f"tests/gherkin/feature_{idx}.feature", "content": content})
        return [self.put(ctx, "gherkin_bundle", ArtifactType.GHERKIN_BUNDLE, files)]

    def lint_gherkin(self, ctx: ExecutionContext) -> list[str]:
        bundle = self.get(ctx, "gherkin_bundle", []) or []
        invalid = []
        for item in bundle:
            content = str(item.get("content", "")) if isinstance(item, dict) else ""
            if "Feature:" not in content or "Scenario:" not in content:
                invalid.append(str(item.get("path", "unknown")))
        report = {"valid": len(invalid) == 0, "invalid_files": invalid}
        return [self.put(ctx, "gherkin_lint_report", ArtifactType.STRUCTURED_JSON, report)]

    def validate_coverage(self, ctx: ExecutionContext) -> list[str]:
        bundle = self.get(ctx, "gherkin_bundle", []) or []
        report = {"covered": len(bundle) > 0, "feature_files": len(bundle)}
        return [self.put(ctx, "coverage_report", ArtifactType.STRUCTURED_JSON, report)]

    def compose_test_model_summary(self, ctx: ExecutionContext) -> list[str]:
        bundle = self.get(ctx, "gherkin_bundle", []) or []
        summary = f"Prepared gherkin model with {len(bundle)} feature file(s)."
        changeset = [
            {
                "op": "create",
                "path": str(item.get("path", "")),
                "base_hash": None,
                "proposed_content": str(item.get("content", "")),
                "reason": "generated gherkin feature",
                "hunks": [],
            }
            for item in bundle
            if isinstance(item, dict)
        ]
        return [
            self.put(ctx, "final_answer", ArtifactType.TEXT, summary),
            self.put(ctx, "final_changeset", ArtifactType.CHANGESET, changeset),
        ]
