from __future__ import annotations

from contextlib import contextmanager
import sys
import types

_fake_db = types.ModuleType("app.db")
_fake_db.engine = object()
sys.modules.setdefault("app.db", _fake_db)

import app.opportunity_action_task_materializer as materializer


class _Result:
    def __init__(self, *, first=None, scalar=None):
        self._first = first
        self._scalar = scalar

    def mappings(self):
        return self

    def first(self):
        return self._first

    def scalar(self):
        return self._scalar


class _Connection:
    def __init__(self):
        self.event_inserted = False

    def execute(self, statement, params=None):
        sql = str(statement)
        if "FROM opportunities" in sql:
            return _Result(first={
                "id": "3df9f447-ec74-4ee3-aabb-ed6632b2c280",
                "conversation_id": None,
                "contact_id": None,
                "customer_id": None,
                "local_customer_id": None,
                "customer_email": "geral@example.pt",
                "title": "DUNAS",
                "metadata": {},
            })
        if "status = 'pending'" in sql and "FROM tasks" in sql:
            return _Result(scalar=None)
        if "status IN ('skipped', 'ignored')" in sql and "FROM tasks" in sql:
            return _Result(first={
                "id": "c08934f6-ad69-4113-8c41-4d552287d76e",
                "status": "skipped",
                "action_code": "VALIDATE_PHYSICAL_ORDER",
                "metadata": {"materialized_from_next_action": True},
            })
        if "UPDATE tasks" in sql:
            assert params["route"] == "logistica"
            assert params["action"] == "Validar encomenda física"
            assert params["metadata"]
            return _Result(scalar="c08934f6-ad69-4113-8c41-4d552287d76e")
        if "INSERT INTO task_events" in sql:
            self.event_inserted = True
            return _Result()
        raise AssertionError(f"SQL inesperado: {sql}")


class _Engine:
    def __init__(self, connection):
        self.connection = connection

    @contextmanager
    def begin(self):
        yield self.connection


def test_preinsert_reactivation_builds_payload_before_use(monkeypatch):
    connection = _Connection()
    monkeypatch.setattr(materializer, "engine", _Engine(connection))
    monkeypatch.setattr(materializer, "get_action_config", lambda _code: {})
    monkeypatch.setattr(materializer, "reconstructed_review_required", lambda _metadata: False)

    result = materializer.ensure_pending_task_for_next_action(
        "3df9f447-ec74-4ee3-aabb-ed6632b2c280",
        {
            "action_code": "VALIDATE_PHYSICAL_ORDER",
            "label": "Validar encomenda física",
            "description": "Confirmar fisicamente a preparação.",
            "priority": "alta",
        },
        source="manual_v132_2_reactivation_repair",
        actor="operator",
        reactivate_skipped=True,
    )

    assert result == {
        "created": False,
        "reactivated": True,
        "reason": "reactivated_after_blocker_preinsert",
        "task_id": "c08934f6-ad69-4113-8c41-4d552287d76e",
        "action_code": "VALIDATE_PHYSICAL_ORDER",
    }
    assert connection.event_inserted is True
