import pytest

pytestmark = pytest.mark.requires_postgres


def _admin_headers() -> dict:
    return {"Authorization": "Bearer test-admin-token"}


def test_create_ingredient_returns_201_with_id(client):
    body = {
        "name": "Test Chicken Thighs",
        "aliases": ["chicken thigh", "BSL chicken thighs"],
        "aisle": "meat_seafood",
        "unit": "lb",
    }
    r = client.post("/api/admin/ingredients", json=body, headers=_admin_headers())
    assert r.status_code == 201, r.text
    data = r.json()
    assert data["id"]
    assert data["aliases"] == ["chicken thigh", "BSL chicken thighs"]


def test_create_ingredient_rejects_duplicate_name(client):
    body = {"name": "Test Garlic Bulb", "aliases": [], "aisle": "produce", "unit": "clove"}
    r1 = client.post("/api/admin/ingredients", json=body, headers=_admin_headers())
    assert r1.status_code == 201
    r2 = client.post("/api/admin/ingredients", json=body, headers=_admin_headers())
    assert r2.status_code == 409


def test_list_ingredients_supports_search(client):
    client.post(
        "/api/admin/ingredients",
        json={"name": "Test Avocado Oil", "aliases": ["EVOO-test"], "aisle": "pantry", "unit": "tbsp"},
        headers=_admin_headers(),
    )
    r = client.get("/api/ingredients?q=avocado")
    assert r.status_code == 200
    names = {row["name"] for row in r.json()}
    assert "Test Avocado Oil" in names


def test_create_ingredient_requires_admin_token(client):
    body = {"name": "Test Meyer Lemon", "aisle": "produce", "unit": "ea", "aliases": []}
    r = client.post("/api/admin/ingredients", json=body)
    assert r.status_code == 401


def test_update_ingredient_replaces_aliases(client):
    create = client.post(
        "/api/admin/ingredients",
        json={"name": "Onion, Yellow", "aliases": ["yellow onion"], "aisle": "produce", "unit": "ea"},
        headers=_admin_headers(),
    )
    iid = create.json()["id"]
    r = client.patch(
        f"/api/admin/ingredients/{iid}",
        json={"aliases": ["yellow onion", "spanish onion"]},
        headers=_admin_headers(),
    )
    assert r.status_code == 200
    assert r.json()["aliases"] == ["yellow onion", "spanish onion"]


def _seed_grocery(db_session, name: str) -> str:
    from datetime import datetime, timezone
    from decimal import Decimal
    from uuid import uuid4

    from app.models import GroceryItem

    gid = uuid4()
    db_session.add(
        GroceryItem(
            id=gid,
            name=name,
            source="lucky_california",
            external_id=f"ext-{gid}",
            current_price=Decimal("4.99"),
            regular_price=Decimal("4.99"),
            is_on_sale=False,
            scraped_at=datetime.now(timezone.utc),
        )
    )
    db_session.commit()
    return str(gid)


def test_pin_manual_match(client, db_session):
    create = client.post(
        "/api/admin/ingredients",
        json={"name": "Test Manual Pin Veggie", "aliases": [], "aisle": "produce", "unit": "ea"},
        headers=_admin_headers(),
    )
    iid = create.json()["id"]
    gid = _seed_grocery(db_session, "Some Other Veggie Brand Test")

    r = client.post(
        f"/api/admin/ingredients/{iid}/matches",
        json={"grocery_item_id": gid, "confidence": 1.0},
        headers=_admin_headers(),
    )
    assert r.status_code == 201, r.text
    body = r.json()
    assert body["source"] == "manual"
    assert body["grocery_item_id"] == gid


def test_unpin_manual_match(client, db_session):
    create = client.post(
        "/api/admin/ingredients",
        json={"name": "Test Unpin Test Item", "aliases": [], "aisle": "produce", "unit": "ea"},
        headers=_admin_headers(),
    )
    iid = create.json()["id"]
    gid = _seed_grocery(db_session, "Brand X Test Product")
    pin = client.post(
        f"/api/admin/ingredients/{iid}/matches",
        json={"grocery_item_id": gid, "confidence": 1.0},
        headers=_admin_headers(),
    )
    match_id = pin.json()["id"]
    r = client.delete(f"/api/admin/ingredient-matches/{match_id}", headers=_admin_headers())
    assert r.status_code == 204


def test_delete_ingredient_removes_row(client):
    create = client.post(
        "/api/admin/ingredients",
        json={"name": "Sage", "aliases": [], "aisle": "produce", "unit": "tsp"},
        headers=_admin_headers(),
    )
    iid = create.json()["id"]
    r = client.delete(f"/api/admin/ingredients/{iid}", headers=_admin_headers())
    assert r.status_code == 204
    r2 = client.get(f"/api/ingredients/{iid}")
    assert r2.status_code == 404
