# standard
import time

# third party
# custom
from ...conftest import ok, err
from sunwaee.cli import app

WS = "personal"
_BASE = ["--workspace", WS]


def _create(runner, title, **kwargs):
    args = ["tasks", "create", "--title", title, *_BASE]
    for k, v in kwargs.items():
        args += [f"--{k.replace('_', '-')}", str(v)]
    return runner.invoke(app, args)


def test_update_title(runner, ws):
    _create(runner, "Old title")
    data = ok(
        runner.invoke(
            app, ["tasks", "update", "Old title", "--title", "New title", *_BASE]
        )
    )
    assert data["title"] == "New title"


def test_update_status(runner, ws):
    _create(runner, "Status task")
    data = ok(
        runner.invoke(
            app,
            ["tasks", "update", "Status task", "--status", "in_progress", *_BASE],
        )
    )
    assert data["status"] == "in_progress"


def test_update_status_done_keeps_completed_at(runner, ws):
    _create(runner, "Done task")
    data = ok(
        runner.invoke(
            app, ["tasks", "update", "Done task", "--status", "done", *_BASE]
        )
    )
    # completed_at not auto-set by update (unlike complete command); status is done
    assert data["status"] == "done"


def test_update_status_not_done_clears_completed_at(runner, ws):
    _create(runner, "Reset task")
    ok(
        runner.invoke(
            app, ["tasks", "update", "Reset task", "--status", "done", *_BASE]
        )
    )
    data = ok(
        runner.invoke(
            app, ["tasks", "update", "Reset task", "--status", "todo", *_BASE]
        )
    )
    assert data["completed_at"] is None


def test_update_priority(runner, ws):
    _create(runner, "Priority task")
    data = ok(
        runner.invoke(
            app, ["tasks", "update", "Priority task", "--priority", "high", *_BASE]
        )
    )
    assert data["priority"] == "high"


def test_update_due(runner, ws):
    _create(runner, "Due task")
    data = ok(
        runner.invoke(
            app, ["tasks", "update", "Due task", "--due", "2026-12-31", *_BASE]
        )
    )
    assert data["due_date"] == "2026-12-31"


def test_update_clear_due(runner, ws):
    _create(runner, "Clear due", due="2026-12-31")
    data = ok(
        runner.invoke(
            app, ["tasks", "update", "Clear due", "--clear-due", *_BASE]
        )
    )
    assert data["due_date"] is None


def test_update_tags(runner, ws):
    _create(runner, "Tag task")
    data = ok(
        runner.invoke(
            app, ["tasks", "update", "Tag task", "--tags", "x,y", *_BASE]
        )
    )
    assert data["tags"] == ["x", "y"]


def test_update_body(runner, ws):
    _create(runner, "Body task", body="original")
    data = ok(
        runner.invoke(
            app, ["tasks", "update", "Body task", "--body", "updated", *_BASE]
        )
    )
    assert data["body"] == "updated"


def test_update_not_found(runner, ws):
    e = err(
        runner.invoke(app, ["tasks", "update", "ghost", "--title", "x", *_BASE])
    )
    assert e["code"] == "NOT_FOUND"


def test_update_no_changes_still_commits(runner, ws):
    _create(runner, "No change")
    # In API mode, no flags and no editor → changed=False, still commits (empty diff ok)
    data = ok(runner.invoke(app, ["tasks", "update", "No change", *_BASE]))
    assert data["title"] == "No change"


def test_update_updates_updated_at(runner, ws):
    _create(runner, "Timestamp task")
    d1 = ok(runner.invoke(app, ["tasks", "read", "Timestamp task", *_BASE]))
    time.sleep(0.01)
    ok(
        runner.invoke(
            app, ["tasks", "update", "Timestamp task", "--body", "v2", *_BASE]
        )
    )
    d2 = ok(runner.invoke(app, ["tasks", "read", "Timestamp task", *_BASE]))
    assert d2["updated_at"] >= d1["updated_at"]
