"""
gherkin_playwright.py — Agents 2 → 3 → 4 pipeline.

Generates Gherkin, Playwright tests, and writes output to the Helix repo.
Delegates to: qa-gherkin-generator, qa-playwright-generator, qa-helix-writer.
The agent servers own all generation logic; this module only defines the task
sequence and the stop conditions the LLM must respect.
"""
from __future__ import annotations

import logging
import os

from ..agent_runner import run_agent_loop
from ..models import Platform, PipelineResult, WebhookEvent
from ._base import event_env, mcp_servers

logger = logging.getLogger("stlc.pipeline.gherkin_playwright")

_AGENTS = ("qa-gherkin-generator", "qa-playwright-generator", "qa-helix-writer")


def _task_prompt(event: WebhookEvent) -> str:
    wi_type = (event.work_item_type or "").lower()
    is_feature = wi_type == "feature"

    # ── Step 1: fetch ────────────────────────────────────────────────────────
    if event.platform == Platform.ADO:
        if is_feature:
            fetch_step   = f"1. fetch_feature_hierarchy({event.work_item_id})"
            attach_tool  = "attach_gherkin_to_feature"
            platform_ctx = (
                f"  Organisation: {event.organization_url}\n"
                f"  Project:      {event.project_name}\n"
            )
        else:
            fetch_step  = f"1. fetch_work_item_for_gherkin({event.work_item_id})"
            attach_tool = "attach_gherkin_to_work_item"
            platform_ctx = (
                f"  Organisation: {event.organization_url}\n"
                f"  Project:      {event.project_name}\n"
            )
    else:
        fetch_step   = f"1. fetch_work_item_for_gherkin({event.work_item_id})"
        attach_tool  = "attach_gherkin_to_work_item"
        platform_ctx = (
            f"  Cloud ID:    {event.cloud_id}\n"
            f"  Project:     {event.project_key}\n"
        )

    # ── Step 2: gherkin ──────────────────────────────────────────────────────
    gherkin_step = f"2. generate_and_attach_gherkin — generate BDD scenarios and attach via {attach_tool}"

    # ── Step 3: optional live capture ───────────────────────────────────────
    app_url      = os.environ.get("APP_BASE_URL", "")
    app_username = os.environ.get("APP_USERNAME", "")
    app_password = os.environ.get("APP_PASSWORD", "")

    if app_url:
        capture_step = (
            f"3. capture_app_context("
            f"app_url={app_url!r}, "
            f"app_username={app_username!r}, "
            f"app_password={app_password!r}, "
            f"gherkin_content=<gherkin from step 2>)\n"
            f"   STOP if result contains locator_source='gherkin-inferred' — "
            f"the Playwright MCP server must be reachable. Do not proceed with inferred selectors.\n"
        )
        pw_step     = "4. generate_playwright_code(gherkin_content=<gherkin>, context_map=<from step 3>)"
        step_offset = 4
    else:
        # No APP_BASE_URL — cannot capture live selectors; pipeline must not produce placeholder output.
        capture_step = (
            "3. STOP — APP_BASE_URL is not configured.\n"
            "   Context mapping is required to generate correct locators. Placeholder selectors\n"
            "   are not acceptable output. To unblock this pipeline:\n"
            "     a) Set APP_BASE_URL (and optionally APP_USERNAME / APP_PASSWORD) in .env\n"
            "     b) Start the Playwright MCP server: npx @playwright/mcp@latest --port 8931\n"
            "     c) Re-trigger the webhook.\n"
            "   Do NOT call generate_playwright_code without a verified context_map.\n"
        )
        pw_step     = ""
        step_offset = 3

    # ── Helix steps (optional) ───────────────────────────────────────────────
    helix_root = event.helix_project_root
    if helix_root:
        n = step_offset
        helix_steps = (
            f"{n+1}. inspect_helix_project(helix_root={helix_root!r})\n"
            f"   NOTE: inspect result is for context only — proceed to the next steps regardless of\n"
            f"   framework_state or missing_infra. Do NOT stop after inspect.\n"
            f"{n+2}. write_helix_files(helix_root={helix_root!r}, cache_key=<cache_key from step {step_offset}>)\n"
            f"   Pass cache_key directly — do NOT pass a files dict, do NOT call get_generated_files first.\n"
            f"   This step is MANDATORY — the pipeline is not complete until write_helix_files succeeds.\n"
        )
    else:
        helix_steps = ""

    # ── Deduplication pre-flight (only when helix_root is set) ──────────────
    wi_id = event.work_item_id
    if helix_root:
        dedup_preflight = (
            f"DEDUPLICATION PRE-FLIGHT — run this BEFORE the steps below:\n"
            f"  Call list_helix_tree(helix_root={helix_root!r}).\n"
            f"  If files matching '*{wi_id}*' already exist in BOTH the 'features' AND 'steps'\n"
            f"  categories, this work item has already been fully processed.\n"
            f"  STOP immediately and report the existing file paths — do not regenerate.\n\n"
        )
        dedup_stop = (
            f"  - Deduplication pre-flight found existing .feature and .steps.ts files for WI #{wi_id}\n"
        )
    else:
        dedup_preflight = ""
        dedup_stop = ""

    stop_conditions = (
        f"\nStop immediately if:\n"
        f"  - fetch returns epic_not_supported or an error\n"
        f"  - generate_and_attach_gherkin returns status='duplicate' or 'already_attached'\n"
        f"{dedup_stop}"
    )

    return (
        f"You are a QA automation agent running in webhook mode — auto-confirm all prompts.\n\n"
        f"Task: Run the full STLC generation pipeline for "
        f"{'ADO' if event.platform == Platform.ADO else 'Jira'} work item {wi_id}.\n"
        f"  Type:  {event.work_item_type}\n"
        f"  State: {event.state}\n"
        f"{platform_ctx}\n"
        f"{dedup_preflight}"
        f"Steps:\n"
        f"{fetch_step}\n"
        f"{gherkin_step}\n"
        f"{capture_step}"
        f"{pw_step}\n"
        f"{helix_steps}"
        f"{stop_conditions}"
    )


async def run(event: WebhookEvent) -> PipelineResult:
    label = f"gherkin-playwright: wi={event.work_item_id}"
    success, error = await run_agent_loop(
        mcp_config=mcp_servers(*_AGENTS),
        prompt=_task_prompt(event),
        llm_provider=event.llm_provider,
        llm_model=event.llm_model,
        llm_api_key=event.llm_api_key,
        llm_base_url=event.llm_base_url,
        env=event_env(event),
        work_item_id=event.work_item_id,
    )
    if not success:
        return PipelineResult(success=False, steps=[label], error=error)
    return PipelineResult(success=True, steps=[label, "completed"])
