"""Flow drift detection — deterministic, no AI.

Validates flow step sequences against the current Maeris API registry.
Reports:
  - FLOW_STEP_STALE              : step references an API ID that no longer exists
  - FLOW_STEP_METHOD_MISMATCH    : step's expected method differs from the API's method
"""

from __future__ import annotations

from .models import DriftIssue, DriftKind, DriftReport, DriftSeverity


async def detect_flow_drift(client) -> DriftReport:
    """Deterministic flow drift detection.

    Fetches all flows and all APIs from Maeris. For each flow step,
    checks that the referenced API still exists and that the method
    hasn't changed. No filesystem scan needed — pure API data comparison.

    Args:
        client: An active MaerisClient instance.

    Returns:
        DriftReport with FLOW_STEP_STALE / FLOW_STEP_METHOD_MISMATCH issues.
    """
    import asyncio

    flows, all_apis = await asyncio.gather(
        client.get_api_flows(),
        client.get_all_apis(),
    )

    # Build lookup: api_id → api dict
    api_by_id: dict[str, dict] = {}
    for api in all_apis:
        for key in ("api_id", "id", "_id"):
            aid = str(api.get(key) or "")
            if aid:
                api_by_id[aid] = api
                break

    issues: list[DriftIssue] = []
    steps_checked = 0

    for flow in flows:
        flow_id = str(
            flow.get("flow_id") or flow.get("id") or flow.get("_id") or ""
        )
        flow_name = flow.get("name") or flow_id

        # flow_map is the ordered list of steps
        steps: list[dict] = flow.get("flow_map") or flow.get("steps") or []

        for idx, step in enumerate(steps):
            api_id = str(
                step.get("api_id") or step.get("child_id") or step.get("id") or ""
            )
            if not api_id:
                continue

            steps_checked += 1

            if api_id not in api_by_id:
                issues.append(DriftIssue(
                    kind=DriftKind.FLOW_STEP_STALE,
                    severity=DriftSeverity.HIGH,
                    description=(
                        f"Flow '{flow_name}' step {idx + 1} references API ID "
                        f"'{api_id}' which no longer exists in Maeris."
                    ),
                    resource_type="flow",
                    resource_id=flow_id,
                    resource_name=flow_name,
                    detail={
                        "step_index": idx,
                        "missing_api_id": api_id,
                        "step": step,
                    },
                ))
                continue

            # Check method consistency if the step carries an expected method
            step_method = (
                step.get("method") or step.get("request_method") or ""
            ).upper()
            if not step_method:
                continue

            api = api_by_id[api_id]
            api_method = (
                api.get("type") or api.get("method") or api.get("request_type") or ""
            ).upper()
            if api_method and step_method != api_method and step_method != "*":
                issues.append(DriftIssue(
                    kind=DriftKind.FLOW_STEP_METHOD_MISMATCH,
                    severity=DriftSeverity.MEDIUM,
                    description=(
                        f"Flow '{flow_name}' step {idx + 1}: expects {step_method} "
                        f"but API '{api.get('name', api_id)}' is now {api_method}."
                    ),
                    resource_type="flow",
                    resource_id=flow_id,
                    resource_name=flow_name,
                    detail={
                        "step_index": idx,
                        "api_id": api_id,
                        "api_name": api.get("name", api_id),
                        "step_method": step_method,
                        "api_method": api_method,
                        "step": step,
                    },
                ))

    return DriftReport(
        domain="flow",
        issues=issues,
        meta={
            "flows_checked": len(flows),
            "apis_in_registry": len(all_apis),
            "steps_checked": steps_checked,
        },
    )
