"""Upload workflow command tests for cron sync branches in managing.py."""

from __future__ import annotations
from pathlib import Path
from types import SimpleNamespace
import pytest
from orcheo_sdk.cli.config import CLISettings
from orcheo_sdk.cli.state import CLIState
from orcheo_sdk.cli.workflow.commands import managing


class _FakeConsole:
    def __init__(self) -> None:
        self.messages: list[str] = []

    def print(self, message: str) -> None:
        self.messages.append(message)


class _FakeContext:
    def __init__(self, state: CLIState) -> None:
        self._state = state

    def ensure_object(self, _obj_type: type) -> CLIState:
        return self._state


def _make_state(*, offline: bool = False, human: bool = True) -> CLIState:
    settings = CLISettings(
        api_url="http://api",
        service_token=None,
        profile="default",
        offline=offline,
    )
    return CLIState(
        settings=settings,
        client=SimpleNamespace(),  # type: ignore[arg-type]
        cache=SimpleNamespace(),  # type: ignore[arg-type]
        console=_FakeConsole(),  # type: ignore[arg-type]
        human=human,
    )


def _context(state: CLIState) -> _FakeContext:
    return _FakeContext(state)


def test_upload_workflow_no_resolved_id_skips_cron_sync(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    """When upload returns no id and workflow_id is None, cron sync is skipped."""
    cron_sync_called: list[bool] = []

    monkeypatch.setattr(
        managing,
        "upload_workflow_data",
        lambda *_args, **_kwargs: {},  # no "id" key → resolved_id is None
    )
    monkeypatch.setattr(
        managing,
        "sync_cron_schedule_if_changed",
        lambda *_args, **_kwargs: cron_sync_called.append(True) or {},
    )
    monkeypatch.setattr(
        managing,
        "render_json",
        lambda *_args, **_kwargs: None,
    )

    state = _make_state()
    ctx = _context(state)
    py_file = tmp_path / "wf.py"
    py_file.write_text("# empty", encoding="utf-8")

    managing.upload_workflow(ctx, py_file)

    # Cron sync must not be invoked when resolved_id is falsy (branch 99->105)
    assert not cron_sync_called
    # identifier falls back to "workflow" when resolved_id is None
    assert any("workflow" in msg for msg in state.console.messages)


def test_upload_workflow_machine_mode_includes_cron_schedule_when_updated(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    """Machine mode upload includes cron_schedule in output when cron was updated."""
    monkeypatch.setattr(
        managing,
        "upload_workflow_data",
        lambda *_args, **_kwargs: {"id": "wf-1", "name": "my-wf"},
    )
    monkeypatch.setattr(
        managing,
        "sync_cron_schedule_if_changed",
        lambda *_args, **_kwargs: {
            "status": "updated",
            "message": "Cron schedule updated for workflow 'wf-1'.",
            "config": {"expression": "0 * * * *"},
        },
    )
    printed: list[dict[str, object]] = []
    monkeypatch.setattr(managing, "print_json", lambda data: printed.append(data))

    state = _make_state(human=False)
    ctx = _context(state)
    py_file = tmp_path / "wf.py"
    py_file.write_text("# empty", encoding="utf-8")

    managing.upload_workflow(ctx, py_file)

    # Line 107: result["cron_schedule"] = cron_sync is set before print_json
    assert len(printed) == 1
    output = printed[0]
    assert output["id"] == "wf-1"
    assert "cron_schedule" in output
    assert output["cron_schedule"]["status"] == "updated"  # type: ignore[index]


def test_upload_workflow_human_mode_prints_cron_message_when_updated(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    """Human mode upload prints cron update message and renders config."""
    monkeypatch.setattr(
        managing,
        "upload_workflow_data",
        lambda *_args, **_kwargs: {"id": "wf-1", "name": "my-wf"},
    )
    monkeypatch.setattr(
        managing,
        "sync_cron_schedule_if_changed",
        lambda *_args, **_kwargs: {
            "status": "updated",
            "message": "Cron schedule updated for workflow 'wf-1'.",
            "config": {"expression": "0 * * * *"},
        },
    )
    render_calls: list[dict[str, object]] = []
    monkeypatch.setattr(
        managing,
        "render_json",
        lambda _console, payload, *, title=None: render_calls.append(
            {"payload": payload, "title": title}
        ),
    )

    state = _make_state(human=True)
    ctx = _context(state)
    py_file = tmp_path / "wf.py"
    py_file.write_text("# empty", encoding="utf-8")

    managing.upload_workflow(ctx, py_file)

    # Line 116: cron message is printed in green
    cron_messages = [m for m in state.console.messages if "Cron schedule updated" in m]
    assert len(cron_messages) == 1
    assert "[green]" in cron_messages[0]

    # Line 117: cron config is rendered under "Cron trigger" title
    cron_renders = [c for c in render_calls if c.get("title") == "Cron trigger"]
    assert len(cron_renders) == 1
    assert cron_renders[0]["payload"] == {"expression": "0 * * * *"}
