from __future__ import annotations

from typing import Any

import pytest
from pydantic import BaseModel

from sync_state_machine.common.sync_node import SyncNode
from sync_state_machine.domain.material_detail.api_handler import MaterialDetailApiHandler
from sync_state_machine.datasource.task_result import TaskStatus


class _MaterialDetailSchema(BaseModel):
    id: str
    parent_id: str
    quantity: float
    remark: str | None = None


class _MaterialDetailNode(SyncNode[_MaterialDetailSchema]):
    node_type = "material_detail"
    schema = _MaterialDetailSchema


class _MockApiClient:
    def __init__(self) -> None:
        self.requests: list[dict[str, Any]] = []

    async def request(self, method: str, endpoint: str, **kwargs: Any) -> dict[str, Any]:
        self.requests.append({"method": method, "endpoint": endpoint, **kwargs})
        return {"code": 200, "message": "OK", "data": {"biz_id": kwargs.get("data", {}).get("biz_id")}}


@pytest.mark.asyncio
async def test_material_detail_update_returns_in_progress_with_shared_push_id() -> None:
    handler = MaterialDetailApiHandler()
    handler.api_client = _MockApiClient()

    node = _MaterialDetailNode(
        node_id="detail-node-1",
        data_id="detail-1",
        data={
            "id": "detail-1",
            "parent_id": "material-1",
            "quantity": 10.0,
            "remark": "new",
        },
        origin_data={
            "id": "detail-1",
            "parent_id": "material-1",
            "quantity": 5.0,
            "remark": None,
        },
        context={"material_id": "material-1"},
    )

    results = await handler.update_all([node])

    assert len(results) == 1
    assert results[0].status == TaskStatus.IN_PROGRESS
    assert results[0].task_id
    assert handler.api_client.requests[0]["endpoint"] == "/material/detail/update"
