"""Tests for tasks skill handler."""

import os

import pytest

from fliiq.runtime.package_data import bundled_skills_dir
from fliiq.runtime.skills.base import SkillBase

SKILLS_DIR = str(bundled_skills_dir())


def _load_skill(name: str) -> SkillBase:
    return SkillBase(os.path.join(SKILLS_DIR, name))


def test_tasks_skill_loads():
    skill = _load_skill("tasks")
    assert skill.name == "tasks"
    schema = skill.schema()
    assert "action" in schema["parameters"]["properties"]
    assert "create" in schema["parameters"]["properties"]["action"]["enum"]


def _setup_fliiq(tmp_path, monkeypatch):
    """Set up a temp .fliiq/ directory."""
    monkeypatch.chdir(tmp_path)
    fliiq_dir = tmp_path / ".fliiq"
    fliiq_dir.mkdir()
    return fliiq_dir


async def test_create_task(tmp_path, monkeypatch):
    _setup_fliiq(tmp_path, monkeypatch)
    from fliiq.data.skills.core.tasks.main import handler

    result = await handler({"action": "create", "title": "Buy groceries", "priority": "high"})
    assert result["success"] is True
    assert result["task"]["title"] == "Buy groceries"
    assert result["task"]["priority"] == "high"
    assert result["task"]["status"] == "todo"
    assert result["task"]["id"].startswith("t_")


async def test_create_task_requires_title(tmp_path, monkeypatch):
    _setup_fliiq(tmp_path, monkeypatch)
    from fliiq.data.skills.core.tasks.main import handler

    with pytest.raises(ValueError, match="title is required"):
        await handler({"action": "create"})


async def test_list_tasks_default_active(tmp_path, monkeypatch):
    _setup_fliiq(tmp_path, monkeypatch)
    from fliiq.data.skills.core.tasks.main import handler

    await handler({"action": "create", "title": "Task A"})
    await handler({"action": "create", "title": "Task B"})

    result = await handler({"action": "list"})
    assert result["success"] is True
    assert result["count"] == 2


async def test_list_tasks_filter_status(tmp_path, monkeypatch):
    _setup_fliiq(tmp_path, monkeypatch)
    from fliiq.data.skills.core.tasks.main import handler

    r = await handler({"action": "create", "title": "Task A"})
    task_id = r["task"]["id"]
    await handler({"action": "create", "title": "Task B"})
    await handler({"action": "complete", "task_id": task_id})

    # Active should only show Task B
    result = await handler({"action": "list", "filter_status": "active"})
    assert result["count"] == 1
    assert result["tasks"][0]["title"] == "Task B"

    # Done should only show Task A
    result = await handler({"action": "list", "filter_status": "done"})
    assert result["count"] == 1
    assert result["tasks"][0]["title"] == "Task A"


async def test_list_tasks_filter_priority(tmp_path, monkeypatch):
    _setup_fliiq(tmp_path, monkeypatch)
    from fliiq.data.skills.core.tasks.main import handler

    await handler({"action": "create", "title": "Low task", "priority": "low"})
    await handler({"action": "create", "title": "High task", "priority": "high"})

    result = await handler({"action": "list", "filter_priority": "high"})
    assert result["count"] == 1
    assert result["tasks"][0]["title"] == "High task"


async def test_list_tasks_filter_due_before(tmp_path, monkeypatch):
    _setup_fliiq(tmp_path, monkeypatch)
    from fliiq.data.skills.core.tasks.main import handler

    await handler({"action": "create", "title": "Soon", "due": "2026-03-01"})
    await handler({"action": "create", "title": "Later", "due": "2026-06-01"})

    result = await handler({"action": "list", "filter_due_before": "2026-04-01"})
    assert result["count"] == 1
    assert result["tasks"][0]["title"] == "Soon"


async def test_list_tasks_filter_project(tmp_path, monkeypatch):
    _setup_fliiq(tmp_path, monkeypatch)
    from fliiq.data.skills.core.tasks.main import handler

    await handler({"action": "create", "title": "T1", "project": "alpha"})
    await handler({"action": "create", "title": "T2", "project": "beta"})

    result = await handler({"action": "list", "project": "alpha"})
    assert result["count"] == 1
    assert result["tasks"][0]["title"] == "T1"


async def test_list_tasks_filter_tags(tmp_path, monkeypatch):
    _setup_fliiq(tmp_path, monkeypatch)
    from fliiq.data.skills.core.tasks.main import handler

    await handler({"action": "create", "title": "T1", "tags": ["sales", "q1"]})
    await handler({"action": "create", "title": "T2", "tags": ["dev"]})

    result = await handler({"action": "list", "tags": ["sales"]})
    assert result["count"] == 1
    assert result["tasks"][0]["title"] == "T1"


async def test_update_task(tmp_path, monkeypatch):
    _setup_fliiq(tmp_path, monkeypatch)
    from fliiq.data.skills.core.tasks.main import handler

    r = await handler({"action": "create", "title": "Original"})
    task_id = r["task"]["id"]

    result = await handler({"action": "update", "task_id": task_id, "title": "Updated", "priority": "urgent"})
    assert result["success"] is True
    assert result["task"]["title"] == "Updated"
    assert result["task"]["priority"] == "urgent"


async def test_update_task_not_found(tmp_path, monkeypatch):
    _setup_fliiq(tmp_path, monkeypatch)
    from fliiq.data.skills.core.tasks.main import handler

    with pytest.raises(ValueError, match="Task not found"):
        await handler({"action": "update", "task_id": "t_nonexistent", "title": "X"})


async def test_complete_task(tmp_path, monkeypatch):
    _setup_fliiq(tmp_path, monkeypatch)
    from fliiq.data.skills.core.tasks.main import handler

    r = await handler({"action": "create", "title": "Finish report"})
    task_id = r["task"]["id"]

    result = await handler({"action": "complete", "task_id": task_id})
    assert result["success"] is True
    assert result["task"]["status"] == "done"
    assert result["task"]["completed_at"] is not None


async def test_delete_task(tmp_path, monkeypatch):
    _setup_fliiq(tmp_path, monkeypatch)
    from fliiq.data.skills.core.tasks.main import handler

    r = await handler({"action": "create", "title": "Delete me"})
    task_id = r["task"]["id"]

    result = await handler({"action": "delete", "task_id": task_id})
    assert result["success"] is True

    # Verify it's gone
    result = await handler({"action": "list", "filter_status": "active"})
    assert result["count"] == 0


async def test_list_sorted_by_priority_then_due(tmp_path, monkeypatch):
    _setup_fliiq(tmp_path, monkeypatch)
    from fliiq.data.skills.core.tasks.main import handler

    await handler({"action": "create", "title": "Low", "priority": "low", "due": "2026-03-01"})
    await handler({"action": "create", "title": "Urgent", "priority": "urgent", "due": "2026-03-15"})
    await handler({"action": "create", "title": "High early", "priority": "high", "due": "2026-02-01"})

    result = await handler({"action": "list"})
    titles = [t["title"] for t in result["tasks"]]
    assert titles == ["Urgent", "High early", "Low"]
