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

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


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


def test_list_notes_empty(runner, ws):
    data = ok(runner.invoke(app, ["notes", "list", *_BASE]))
    assert data == []


def test_list_notes(runner, ws):
    _create(runner, "Note A", body="a")
    _create(runner, "Note B", body="b")
    data = ok(runner.invoke(app, ["notes", "list", *_BASE]))
    assert len(data) == 2


def test_list_notes_all_workspaces(runner, ws):
    _create(runner, "In personal", body="a")
    data = ok(runner.invoke(app, ["notes", "list"]))
    assert any(n["title"] == "In personal" for n in data)
    assert all("workspace" in n for n in data)


def test_list_notes_filter_by_tag(runner, ws):
    _create(runner, "Tagged", tags="work")
    _create(runner, "Untagged")
    data = ok(runner.invoke(app, ["notes", "list", "--tags", "work", *_BASE]))
    assert len(data) == 1
    assert data[0]["title"] == "Tagged"


def test_list_notes_includes_path(runner, ws):
    _create(runner, "Path check", body="x")
    data = ok(runner.invoke(app, ["notes", "list", *_BASE]))
    assert all("path" in n for n in data)


def test_list_notes_query_by_title(runner, ws):
    _create(runner, "Python tips")
    _create(runner, "Rust notes")
    data = ok(runner.invoke(app, ["notes", "list", "--query", "python", *_BASE]))
    assert len(data) == 1
    assert data[0]["title"] == "Python tips"


def test_list_notes_query_by_body(runner, ws):
    _create(runner, "A", body="async await syntax")
    _create(runner, "B", body="nothing relevant")
    data = ok(runner.invoke(app, ["notes", "list", "--query", "async", *_BASE]))
    assert len(data) == 1


def test_list_notes_query_no_match(runner, ws):
    _create(runner, "Something")
    data = ok(runner.invoke(app, ["notes", "list", "--query", "zzznomatch", *_BASE]))
    assert data == []


def test_list_notes_sort_by_title(runner, ws):
    _create(runner, "Zebra")
    _create(runner, "Alpha")
    data = ok(runner.invoke(app, ["notes", "list", "--sort", "title", *_BASE]))
    titles = [n["title"] for n in data]
    assert titles == sorted(titles, key=str.lower)


def test_list_notes_sort_by_created(runner, ws):
    _create(runner, "First")
    _create(runner, "Second")
    data = ok(runner.invoke(app, ["notes", "list", "--sort", "created", *_BASE]))
    assert len(data) == 2


def test_list_notes_sort_invalid(runner, ws):
    e = err(runner.invoke(app, ["notes", "list", "--sort", "banana", *_BASE]))
    assert e["code"] == "VALIDATION_ERROR"
