"""Slug feed paths must resolve to Magento human category registry rows."""

from __future__ import annotations

from datetime import datetime, timezone
from unittest.mock import MagicMock

from magento.category_paths import (
    humanize_slug_path,
    match_category_id,
    path_candidate_keys,
    segment_url_key,
)
from magento.sync_service import MagentoSyncService


def test_humanize_slug_path():
    assert humanize_slug_path("kitchen-cabinets/wall-cabinets") == "Kitchen Cabinets/Wall Cabinets"


def test_path_candidate_keys_include_human_and_default_root():
    keys = path_candidate_keys("kitchen-cabinets/wall-cabinets")
    assert "kitchencabinetswallcabinets" in keys
    assert "defaultcategorykitchencabinetswallcabinets" in keys


def test_match_category_id_resolves_slug_to_human_registry_path():
    rows = [
        {
            "category_id": 41,
            "name": "Wall Cabinets",
            "path_names": "Default Category/Kitchen Cabinets/Wall Cabinets",
        }
    ]
    assert match_category_id(rows, "kitchen-cabinets/wall-cabinets") == 41


def test_match_category_id_unique_leaf_fallback():
    rows = [
        {"category_id": 9, "name": "Open Wall Cabinet", "path_names": "Kitchen Cabinets/Wall Cabinets/Open Wall Cabinet"},
    ]
    assert match_category_id(rows, "kitchen-cabinets/wall-cabinets/open-wall-cabinet") == 9


def test_match_category_id_ambiguous_leaf_returns_none():
    rows = [
        {"category_id": 1, "name": "Panel", "path_names": "A/Panel"},
        {"category_id": 2, "name": "Panel", "path_names": "B/Panel"},
    ]
    assert match_category_id(rows, "panel") is None


def test_segment_url_key():
    assert segment_url_key("kitchen-cabinets") == "kitchen-cabinets"
    assert segment_url_key("Kitchen Cabinets") == "kitchen-cabinets"


def test_resolve_category_ids_matches_slug_without_create():
    ttl = datetime.now(timezone.utc)
    cat_repo = MagicMock()
    cat_repo.get_all.return_value = [
        {
            "category_id": 41,
            "name": "Wall Cabinets",
            "path_names": "Default Category/Kitchen Cabinets/Wall Cabinets",
        }
    ]
    cat_repo.resolve_path.return_value = None
    cat_repo.resolve_name.return_value = None

    svc = MagentoSyncService(MagicMock(), {"id": 4}, category_cache_repo=cat_repo)
    ids = svc._resolve_category_ids(4, "kitchen-cabinets/wall-cabinets", ttl_days=7)

    assert ids == [41]
    svc._api.create_category.assert_not_called()


def test_ensure_category_recovers_url_key_conflict_via_url_key_search():
    cat_repo = MagicMock()
    cat_repo.get_all.return_value = []
    cat_repo.resolve_path.return_value = None
    cat_repo.upsert_category = MagicMock()

    api = MagicMock()
    api.create_category.return_value = (
        400,
        {"error": "URL key for specified store already exists."},
    )
    api.search_categories.side_effect = [
        (200, [{"id": 15, "parent_id": 2, "name": "Kitchen Cabinets", "path": "1/2/15", "is_active": True}]),
    ]

    svc = MagentoSyncService(api, {"id": 4}, category_cache_repo=cat_repo)
    ttl = datetime.now(timezone.utc)
    cid = svc._ensure_category_path_exists(4, "kitchen-cabinets", ttl)

    assert cid == 15
    cat_repo.upsert_category.assert_called_once()
    adopted = cat_repo.upsert_category.call_args[0][1]
    assert adopted["category_id"] == 15
    assert adopted["name"] == "Kitchen Cabinets"
    assert adopted["path_names"] == "Kitchen Cabinets"
    api.search_categories.assert_called()
    assert api.search_categories.call_args_list[0].kwargs.get("url_key") == "kitchen-cabinets"


def test_resolve_category_ids_warns_once_per_missing_path(caplog):
    cat_repo = MagicMock()
    cat_repo.get_all.return_value = []
    cat_repo.resolve_path.return_value = None
    cat_repo.resolve_name.return_value = None

    svc = MagentoSyncService(MagicMock(), {"id": 4}, category_cache_repo=cat_repo)
    with caplog.at_level("WARNING"):
        assert svc._resolve_category_ids(4, "missing/path") == []
        assert svc._resolve_category_ids(4, "missing/path") == []

    warnings = [r for r in caplog.records if "not found and could not create" in r.getMessage()]
    assert len(warnings) == 1
