"""Tests for MCP server tools (mcp_server.py)."""

from __future__ import annotations

import json
import pytest

from review_mcp import db
from review_mcp.mcp_server import (
    get_review_summary,
    get_reviews,
    add_review,
    resolve_review,
    reopen_review,
    batch_resolve,
    get_pending_work,
    get_annotated_reviews,
    find_source_file_tool,
)


@pytest.fixture(autouse=True)
async def _init(tmp_db):
    await db.init_db()


# --------------- get_review_summary ---------------


async def test_summary_empty():
    result = await get_review_summary()
    assert "No reviews" in result


async def test_summary_with_data():
    await db.insert_review("page-a", "alice", "comment")
    result = await get_review_summary()
    assert "page-a" in result
    assert "1" in result  # open count


# --------------- get_reviews ---------------


async def test_get_reviews_empty():
    result = await get_reviews()
    assert "No reviews" in result


async def test_get_reviews_all():
    await db.insert_review("p1", "a", "t1")
    await db.insert_review("p2", "b", "t2")
    result = await get_reviews()
    assert "p1" in result
    assert "p2" in result


async def test_get_reviews_filtered():
    await db.insert_review("p1", "a", "t1")
    await db.insert_review("p2", "b", "t2")
    result = await get_reviews("p1")
    assert "p1" in result
    assert "p2" not in result


async def test_get_reviews_empty_page():
    result = await get_reviews("nonexistent")
    assert "No reviews" in result
    assert "nonexistent" in result


# --------------- add_review ---------------


async def test_add_review():
    result = await add_review("page-x", "tester", "Nice work")
    assert "Created review #1" in result
    assert "page-x" in result
    assert "tester" in result


# --------------- resolve_review ---------------


async def test_resolve_review():
    await db.insert_review("p1", "a", "t1")
    result = await resolve_review(1, "bot")
    assert "resolved" in result.lower()
    assert "bot" in result

    rows = await db.get_reviews("p1")
    assert rows[0]["status"] == "resolved"


async def test_resolve_review_not_found():
    result = await resolve_review(999)
    assert "not found" in result.lower()


# --------------- reopen_review ---------------


async def test_reopen_review():
    await db.insert_review("p1", "a", "t1")
    await resolve_review(1)
    result = await reopen_review(1)
    assert "reopened" in result.lower()

    rows = await db.get_reviews("p1")
    assert rows[0]["status"] == "open"


async def test_reopen_review_not_found():
    result = await reopen_review(999)
    assert "not found" in result.lower()


# --------------- batch_resolve ---------------


async def test_batch_resolve():
    await db.insert_review("p1", "a", "t1")
    await db.insert_review("p1", "a", "t2")
    await db.insert_review("p2", "b", "t3")

    result = await batch_resolve("p1", "agent")
    assert "2" in result

    rows = await db.get_reviews("p1")
    assert all(r["status"] == "resolved" for r in rows)

    rows_p2 = await db.get_reviews("p2")
    assert rows_p2[0]["status"] == "open"


async def test_batch_resolve_nothing():
    result = await batch_resolve("empty-page")
    assert "0" in result


# --------------- get_pending_work ---------------


async def test_pending_work_empty():
    result = await get_pending_work()
    assert "All clear" in result


async def test_pending_work_with_data():
    await db.insert_review("p1", "a", "fix header")
    await db.insert_review("p2", "b", "fix footer")

    result = await get_pending_work()
    assert "p1" in result
    assert "p2" in result
    assert "fix header" in result
    assert "fix footer" in result


async def test_pending_work_excludes_resolved():
    await db.insert_review("p1", "a", "done")
    await db.batch_resolve("p1")

    result = await get_pending_work()
    assert "All clear" in result


# --------------- find_source_file_tool ---------------


async def test_find_source_file_no_project_root(monkeypatch):
    import review_mcp.mcp_server as ms
    monkeypatch.setattr(ms, "PROJECT_ROOT", "")
    result = await find_source_file_tool("some-page")
    assert "not set" in result.lower()


async def test_find_source_file_with_results(monkeypatch, project_tree):
    import review_mcp.mcp_server as ms
    monkeypatch.setattr(ms, "PROJECT_ROOT", str(project_tree))
    result = await find_source_file_tool("user-profile")
    assert "Found" in result
    assert "user-profile" in result


async def test_find_source_file_no_match(monkeypatch, project_tree):
    import review_mcp.mcp_server as ms
    monkeypatch.setattr(ms, "PROJECT_ROOT", str(project_tree))
    result = await find_source_file_tool("nonexistent-xyz")
    assert "No source files" in result


# --------------- metadata / annotations ---------------


async def test_get_reviews_shows_element_context():
    meta = json.dumps({"element": "Button 'Submit'", "selector": "#submit-btn"})
    await db.insert_review("p1", "a", "fix button", meta)
    result = await get_reviews("p1")
    assert "Button 'Submit'" in result
    assert "#submit-btn" in result


async def test_get_pending_work_shows_element_context():
    meta = json.dumps({"element": "Input[email]", "selector": ".email"})
    await db.insert_review("p1", "a", "fix input", meta)
    result = await get_pending_work()
    assert "Input[email]" in result
    assert ".email" in result


async def test_add_review_with_metadata():
    meta = json.dumps({"element": "Heading 1", "selector": "h1.title"})
    result = await add_review("p1", "a", "fix heading", meta)
    assert "Created review #1" in result

    # Verify metadata is stored
    rows = await db.get_reviews("p1")
    assert rows[0]["metadata"] == meta


async def test_get_annotated_reviews_empty():
    result = await get_annotated_reviews()
    assert "No annotated reviews" in result


async def test_get_annotated_reviews_filters():
    # Insert one with metadata, one without
    meta = json.dumps({
        "element": "Button 'Save'",
        "selector": "#save-btn",
        "fullPath": "body > form > button#save-btn",
        "accessibility": "role=\"button\"",
    })
    await db.insert_review("p1", "a", "annotated review", meta)
    await db.insert_review("p1", "b", "plain review")

    result = await get_annotated_reviews("p1")
    assert "annotated review" in result
    assert "Button 'Save'" in result
    assert "#save-btn" in result
    assert "body > form > button#save-btn" in result
    assert "plain review" not in result


async def test_get_annotated_reviews_no_page_filter():
    meta = json.dumps({"element": "Link", "selector": "a.nav"})
    await db.insert_review("p1", "a", "fix link", meta)
    await db.insert_review("p2", "b", "other", json.dumps({"element": "Div", "selector": ".card"}))

    result = await get_annotated_reviews()
    assert "fix link" in result
    assert "other" in result
