#!/usr/bin/env python3
"""todo-manager.py CLI 테스트"""

import json
import subprocess
import sys
from pathlib import Path

import pytest

WORKSPACE = Path(__file__).parent.parent
TODO_FILE = WORKSPACE / "todo.json"
MANAGER = WORKSPACE / "todo-manager.py"


@pytest.fixture(autouse=True)
def backup_todo():
    """테스트 전후 todo.json 백업/복원"""
    backup = None
    if TODO_FILE.exists():
        backup = TODO_FILE.read_text(encoding="utf-8")
    yield
    if backup is not None:
        TODO_FILE.write_text(backup, encoding="utf-8")
    elif TODO_FILE.exists():
        TODO_FILE.unlink()


def run_cli(*args: str) -> subprocess.CompletedProcess:
    return subprocess.run(
        [sys.executable, str(MANAGER), *args],
        capture_output=True,
        text=True,
        timeout=10,
    )


def load_todo() -> dict:
    return json.loads(TODO_FILE.read_text(encoding="utf-8"))


class TestAdd:
    def test_add_basic(self):
        result = run_cli("add", "--project", "TestProject", "--title", "테스트 안건", "--priority", "high")
        assert result.returncode == 0
        assert "추가 완료" in result.stdout
        data = load_todo()
        added = [i for i in data["issues"] if i["title"] == "테스트 안건"]
        assert len(added) == 1
        assert added[0]["project"] == "TestProject"
        assert added[0]["priority"] == "high"
        assert added[0]["status"] == "pending"

    def test_add_with_sub_items(self):
        result = run_cli(
            "add",
            "--project",
            "TestProject",
            "--title",
            "서브 테스트",
            "--priority",
            "medium",
            "--sub",
            "항목A",
            "--sub",
            "항목B",
        )
        assert result.returncode == 0
        data = load_todo()
        added = [i for i in data["issues"] if i["title"] == "서브 테스트"]
        assert len(added) == 1
        assert len(added[0]["sub_items"]) == 2
        assert added[0]["sub_items"][0]["title"] == "항목A"
        assert added[0]["sub_items"][0]["done"] is False


class TestDone:
    def test_done_sub_item(self):
        run_cli("add", "--project", "T", "--title", "Done테스트", "--sub", "A", "--sub", "B")
        data = load_todo()
        issue_id = [i for i in data["issues"] if i["title"] == "Done테스트"][0]["id"]

        result = run_cli("done", "--issue", issue_id, "--sub", "A")
        assert result.returncode == 0
        data = load_todo()
        issue = [i for i in data["issues"] if i["id"] == issue_id][0]
        assert issue["sub_items"][0]["done"] is True
        assert issue["sub_items"][1]["done"] is False
        assert issue["status"] != "completed"

    def test_auto_complete(self):
        run_cli("add", "--project", "T", "--title", "자동완료", "--sub", "X")
        data = load_todo()
        issue_id = [i for i in data["issues"] if i["title"] == "자동완료"][0]["id"]

        run_cli("done", "--issue", issue_id, "--sub", "X")
        data = load_todo()
        issue = [i for i in data["issues"] if i["id"] == issue_id][0]
        assert issue["status"] == "completed"
        assert issue["completed_at"] is not None

    def test_done_invalid_issue(self):
        result = run_cli("done", "--issue", "issue-999", "--sub", "없는항목")
        assert result.returncode != 0


class TestLink:
    def test_link_task(self):
        run_cli("add", "--project", "T", "--title", "링크테스트")
        data = load_todo()
        issue_id = [i for i in data["issues"] if i["title"] == "링크테스트"][0]["id"]

        result = run_cli("link", "--issue", issue_id, "--task", "task-999.1")
        assert result.returncode == 0
        data = load_todo()
        issue = [i for i in data["issues"] if i["id"] == issue_id][0]
        assert "task-999.1" in issue["linked_tasks"]


class TestList:
    def test_list_all(self):
        result = run_cli("list")
        assert result.returncode == 0

    def test_list_with_filters(self):
        result = run_cli("list", "--project", "InsuRo", "--status", "in_progress")
        assert result.returncode == 0


class TestComplete:
    def test_manual_complete(self):
        run_cli("add", "--project", "T", "--title", "수동완료")
        data = load_todo()
        issue_id = [i for i in data["issues"] if i["title"] == "수동완료"][0]["id"]

        result = run_cli("complete", "--issue", issue_id)
        assert result.returncode == 0
        data = load_todo()
        issue = [i for i in data["issues"] if i["id"] == issue_id][0]
        assert issue["status"] == "completed"


class TestDelete:
    def test_delete(self):
        run_cli("add", "--project", "T", "--title", "삭제대상")
        data = load_todo()
        issue_id = [i for i in data["issues"] if i["title"] == "삭제대상"][0]["id"]

        result = run_cli("delete", "--issue", issue_id)
        assert result.returncode == 0
        data = load_todo()
        remaining = [i for i in data["issues"] if i["id"] == issue_id]
        assert len(remaining) == 0

    def test_delete_invalid(self):
        result = run_cli("delete", "--issue", "issue-999")
        assert result.returncode != 0
