from __future__ import annotations

import re

from sqlalchemy import text

from app.core.common.identifiers import new_governance_uid
from app.core.events.outbox import enqueue_outbox


WORKFLOW_STATES = {"draft", "validating", "active", "superseded", "activation_failed"}


def activation_error(error: Exception) -> str:
    message = re.sub(
        r"(?i)(api[-_ ]?key|authorization|bearer|password|token)(?:[=: ]+\S+)?",
        "[redacted]",
        str(error),
    )
    return message[:1000]


def activate_version(session, *, version_id: str, actor_id: str, n8n_client) -> dict:
    row = session.execute(
        text(
            "SELECT id::text, dataflow_uid::text, environment, n8n_workflow_id, status "
            "FROM public.dataflow_workflow_versions WHERE id = CAST(:id AS uuid) FOR UPDATE"
        ),
        {"id": version_id},
    ).one_or_none()
    if not row:
        raise ValueError("workflow version not found")
    if row[4] == "active":
        return {"id": row[0], "status": "active", "idempotent": True}
    session.execute(text("SELECT pg_advisory_xact_lock(hashtext(:key))"), {"key": f"{row[1]}:{row[2]}"})
    correlation_id = new_governance_uid()
    session.execute(
        text("UPDATE public.dataflow_workflow_versions SET status = 'validating', activation_error = NULL, activation_correlation_id = CAST(:correlation AS uuid) WHERE id = CAST(:id AS uuid)"),
        {"id": version_id, "correlation": correlation_id},
    )
    active_ids = session.execute(
        text("SELECT n8n_workflow_id FROM public.dataflow_workflow_versions WHERE dataflow_uid = CAST(:uid AS uuid) AND environment = :environment AND status = 'active' FOR UPDATE"),
        {"uid": row[1], "environment": row[2]},
    ).scalars().all()
    try:
        for active_id in active_ids:
            if active_id != row[3]:
                n8n_client.deactivate_workflow(active_id)
        n8n_client.activate_workflow(row[3])
    except Exception as exc:
        message = activation_error(exc)
        session.execute(
            text("UPDATE public.dataflow_workflow_versions SET status = 'activation_failed', activation_error = :error, updated_at = CURRENT_TIMESTAMP WHERE id = CAST(:id AS uuid)"),
            {"id": version_id, "error": message},
        )
        session.commit()
        raise RuntimeError(message) from exc
    session.execute(
        text("UPDATE public.dataflow_workflow_versions SET status = 'superseded', updated_at = CURRENT_TIMESTAMP WHERE dataflow_uid = CAST(:uid AS uuid) AND environment = :environment AND status = 'active' AND id <> CAST(:id AS uuid)"),
        {"uid": row[1], "environment": row[2], "id": version_id},
    )
    session.execute(
        text("UPDATE public.dataflow_workflow_versions SET status = 'active', activated_by = CAST(:actor AS uuid), activated_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP WHERE id = CAST(:id AS uuid)"),
        {"id": version_id, "actor": actor_id},
    )
    enqueue_outbox(
        session, aggregate_type="dataflow", aggregate_id=row[1],
        event_type="dataflow.workflow_version_activated",
        payload={"dataflow_uid": row[1], "workflow_version_id": version_id, "environment": row[2]},
        correlation_id=correlation_id,
    )
    session.commit()
    return {"id": version_id, "status": "active", "correlation_id": correlation_id}
