"""Tests for the Price Tracker plugin."""

from __future__ import annotations

import pytest

from agent_scout.db.database import Database
from agent_scout.db.models import PriceSnapshot
from agent_scout.events import Event, EventBus, EventType
from agent_scout.plugins.price_tracker import PriceTrackerPlugin


@pytest.fixture
async def db(tmp_path):
    database = Database(str(tmp_path / "test.db"))
    await database.connect()
    yield database
    await database.close()


@pytest.fixture
def bus():
    return EventBus()


async def test_track_price(db: Database, bus: EventBus):
    plugin = PriceTrackerPlugin(db=db, event_bus=bus)
    await plugin.load()
    await plugin.enable()

    result = await plugin.execute(
        "track_price",
        {"item_name": "iPhone 16", "price": 999.99, "source": "Apple Store", "currency": "USD"},
    )
    assert "Tracked" in result
    assert "iPhone 16" in result
    assert "999.99" in result


async def test_track_price_missing_fields(db: Database):
    plugin = PriceTrackerPlugin(db=db)
    result = await plugin.execute("track_price", {"item_name": "", "source": ""})
    assert "Error" in result


async def test_get_price_history(db: Database):
    plugin = PriceTrackerPlugin(db=db)

    # Store some prices
    await db.store_price(PriceSnapshot(item_name="Laptop", price=1200, source="Amazon"))
    await db.store_price(PriceSnapshot(item_name="Laptop", price=1150, source="BestBuy"))

    result = await plugin.execute("get_price_history", {"item_name": "Laptop"})
    assert "Laptop" in result
    assert "2 entries" in result
    assert "Amazon" in result
    assert "BestBuy" in result


async def test_get_price_history_empty(db: Database):
    plugin = PriceTrackerPlugin(db=db)
    result = await plugin.execute("get_price_history", {"item_name": "Nonexistent"})
    assert "No price history" in result


async def test_compare_prices(db: Database):
    plugin = PriceTrackerPlugin(db=db)

    await db.store_price(PriceSnapshot(item_name="GPU", price=800, source="Amazon"))
    await db.store_price(PriceSnapshot(item_name="GPU", price=750, source="Newegg"))
    await db.store_price(PriceSnapshot(item_name="GPU", price=900, source="BestBuy"))

    result = await plugin.execute("compare_prices", {"item_name": "GPU"})
    assert "BEST" in result
    assert "Newegg" in result
    assert "Savings" in result


async def test_compare_prices_empty(db: Database):
    plugin = PriceTrackerPlugin(db=db)
    result = await plugin.execute("compare_prices", {"item_name": "Nonexistent"})
    assert "No price data" in result


async def test_check_price_drop_below_threshold(db: Database, bus: EventBus):
    plugin = PriceTrackerPlugin(db=db, event_bus=bus)

    received: list[Event] = []

    async def handler(event: Event):
        received.append(event)

    bus.subscribe(handler, EventType.BUDGET_WARNING)

    await db.store_price(PriceSnapshot(item_name="Book", price=9.99, source="Amazon"))

    result = await plugin.execute("check_price_drop", {"item_name": "Book", "threshold": 15.00})
    assert "ALERT" in result
    assert "9.99" in result
    assert len(received) == 1


async def test_check_price_drop_above_threshold(db: Database):
    plugin = PriceTrackerPlugin(db=db)

    await db.store_price(PriceSnapshot(item_name="Book", price=25.00, source="Amazon"))

    result = await plugin.execute("check_price_drop", {"item_name": "Book", "threshold": 15.00})
    assert "above threshold" in result


async def test_no_database():
    plugin = PriceTrackerPlugin(db=None)
    result = await plugin.execute("track_price", {"item_name": "X", "price": 10, "source": "Y"})
    assert "Database not available" in result


async def test_get_tools():
    plugin = PriceTrackerPlugin()
    tools = plugin.get_tools()
    names = {t.name for t in tools}
    assert "track_price" in names
    assert "get_price_history" in names
    assert "compare_prices" in names
    assert "check_price_drop" in names


async def test_unknown_tool():
    plugin = PriceTrackerPlugin()
    result = await plugin.execute("unknown", {})
    assert "Unknown tool" in result


async def test_track_price_emits_event(db: Database, bus: EventBus):
    received: list[Event] = []

    async def handler(event: Event):
        received.append(event)

    bus.subscribe(handler, EventType.COST_UPDATE)

    plugin = PriceTrackerPlugin(db=db, event_bus=bus)

    await plugin.execute(
        "track_price",
        {"item_name": "Phone", "price": 500, "source": "Store", "currency": "EUR"},
    )
    assert len(received) == 1
    assert received[0].data["item_name"] == "Phone"
    assert received[0].data["currency"] == "EUR"
