"""Bernard Temporal workflows — PR review & Temporal health monitor."""
from __future__ import annotations

from datetime import timedelta

from temporalio import workflow

with workflow.unsafe.imports_passed_through():
    from bernard.temporal.activities import (
        analyze_failure_with_llm,
        fetch_failed_workflows,
        fetch_open_prs,
        fetch_pr_diff,
        fetch_workflow_failure_details,
        get_reviewed_prs,
        mark_pr_reviewed,
        persist_alert,
        post_pr_comment,
        review_pr_with_llm,
    )

_ACT_TIMEOUT = timedelta(minutes=10)
_REPO = "deepkoluguri/agentic-os"


# ---------------------------------------------------------------------------
# PR Review Workflow — scans open PRs, reviews any that haven't been reviewed
# ---------------------------------------------------------------------------

@workflow.defn
class PRReviewWorkflow:
    """Scan all open PRs in the agentic-os repo and post AI reviews."""

    @workflow.run
    async def run(self) -> dict:
        reviewed_keys = await workflow.execute_activity(
            get_reviewed_prs, start_to_close_timeout=_ACT_TIMEOUT
        )

        open_prs = await workflow.execute_activity(
            fetch_open_prs, _REPO, start_to_close_timeout=_ACT_TIMEOUT
        )

        results = []
        for pr in open_prs:
            pr_key = f"{_REPO}#{pr['number']}"
            if pr_key in reviewed_keys:
                continue

            diff_payload = await workflow.execute_activity(
                fetch_pr_diff,
                {"repo": _REPO, "pr_number": pr["number"]},
                start_to_close_timeout=_ACT_TIMEOUT,
            )

            review_payload = await workflow.execute_activity(
                review_pr_with_llm, diff_payload, start_to_close_timeout=_ACT_TIMEOUT
            )

            await workflow.execute_activity(
                post_pr_comment, review_payload, start_to_close_timeout=_ACT_TIMEOUT
            )

            alert_id = await workflow.execute_activity(
                persist_alert,
                {
                    "alert_type": "pr_review",
                    "title": f"PR #{pr['number']}: {pr.get('title', '')}",
                    "body": review_payload["review"],
                    "metadata": {
                        "repo": _REPO,
                        "pr_number": pr["number"],
                        "author": pr.get("user", {}).get("login", ""),
                    },
                },
                start_to_close_timeout=_ACT_TIMEOUT,
            )

            await workflow.execute_activity(
                mark_pr_reviewed, pr_key, start_to_close_timeout=_ACT_TIMEOUT
            )

            results.append({"pr_key": pr_key, "alert_id": alert_id})

        return {"reviewed": len(results), "prs": results}


# ---------------------------------------------------------------------------
# Temporal Monitor Workflow — runs on cron, scans for failed workflows
# ---------------------------------------------------------------------------

@workflow.defn
class TemporalMonitorWorkflow:
    """Check for failed Temporal workflows and post AI root-cause analysis."""

    @workflow.run
    async def run(self) -> dict:
        failed_workflows = await workflow.execute_activity(
            fetch_failed_workflows, start_to_close_timeout=_ACT_TIMEOUT
        )

        results = []
        for wf in failed_workflows:
            details = await workflow.execute_activity(
                fetch_workflow_failure_details, wf, start_to_close_timeout=_ACT_TIMEOUT
            )

            analysis = await workflow.execute_activity(
                analyze_failure_with_llm, details, start_to_close_timeout=_ACT_TIMEOUT
            )

            alert_id = await workflow.execute_activity(
                persist_alert,
                {
                    "alert_type": "workflow_failure",
                    "title": f"❌ Workflow Failed: {wf['workflow_type']} ({wf['workflow_id']})",
                    "body": analysis["analysis"],
                    "metadata": {
                        "workflow_id": wf["workflow_id"],
                        "run_id": wf["run_id"],
                        "workflow_type": wf["workflow_type"],
                        "error": details["error"],
                    },
                },
                start_to_close_timeout=_ACT_TIMEOUT,
            )

            results.append({
                "workflow_id": wf["workflow_id"],
                "alert_id": alert_id,
            })

        return {"failures_analyzed": len(results), "alerts": results}
