"""Tests for channel product removal planning."""

from types import SimpleNamespace
from unittest.mock import MagicMock

import pytest

from db.channel_product_removal import RemovalCandidate, plan_product_removals


class _ScalarResult:
    def __init__(self, rows):
        self._rows = rows

    def all(self):
        return self._rows


class _FakeSession:
    def __init__(self, rows_by_stmt):
        self._rows_by_stmt = rows_by_stmt

    def execute(self, stmt):
        key = str(stmt)
        for fragment, rows in self._rows_by_stmt.items():
            if fragment in key:
                return _ScalarResult(rows)
        return _ScalarResult([])

    def scalar(self, stmt):
        key = str(stmt)
        for fragment, value in self._rows_by_stmt.get("_scalar", {}).items():
            if fragment in key:
                return value
        return None


def test_plan_not_in_master_flags_orphan_magento_sku(monkeypatch):
    session = _FakeSession(
        {
            "magento_catalog_state": [("RTA-OLD-SKU", 999)],
            "master_product": [("ASM-100",)],
            "_scalar": {},
        }
    )

    monkeypatch.setattr(
        "db.channel_product_removal.master_sku_for_channel_sku",
        lambda *args, **kwargs: None,
    )
    monkeypatch.setattr(
        "db.channel_product_removal._relation_hints",
        lambda *args, **kwargs: (set(), {}),
    )

    plan = plan_product_removals(
        session,
        "magento",
        connection_id=1,
        selection="not_in_master",
    )
    assert plan["candidate_count"] == 1
    assert plan["candidates"][0]["channel_sku"] == "RTA-OLD-SKU"
    assert plan["candidates"][0]["remote_id"] == "999"
    assert plan["candidates"][0]["reason"] == "not_in_master"


def test_plan_master_filter_resolves_remote_id(monkeypatch):
    session = _FakeSession(
        {
            "channel_publish_state": [("RTA-100", "gid://shopify/Product/1")],
            "_scalar": {},
        }
    )

    monkeypatch.setattr(
        "db.channel_product_removal.resolve_filtered_master_skus",
        lambda *args, **kwargs: ["RTA-100"],
    )
    monkeypatch.setattr(
        "db.channel_product_removal.channel_sku_for_master",
        lambda *args, **kwargs: "RTA-100",
    )
    monkeypatch.setattr(
        "db.channel_product_removal._relation_hints",
        lambda *args, **kwargs: (set(), {}),
    )

    plan = plan_product_removals(
        session,
        "shopify",
        selection="master_filter",
        master_filters=[{"code": "assembly_type", "value": "RTA"}],
    )
    assert plan["candidate_count"] == 1
    assert plan["candidates"][0]["remote_id"] == "gid://shopify/Product/1"
    assert plan["candidates"][0]["master_sku"] == "RTA-100"


def test_plan_sku_filter_flags_matching_remote_skus(monkeypatch):
    session = _FakeSession(
        {
            "magento_catalog_state": [
                ("RTA-OLD-SKU", 999),
                ("ASM-KEEP-SKU", 1000),
                ("X-RTA-CONTAINS", 1001),
            ],
            "master_product": [("RTA-OLD-SKU",), ("ASM-KEEP-SKU",), ("X-RTA-CONTAINS",)],
            "_scalar": {},
        }
    )

    monkeypatch.setattr(
        "db.channel_product_removal.master_sku_for_channel_sku",
        lambda *args, **kwargs: None,
    )
    monkeypatch.setattr(
        "db.channel_product_removal._relation_hints",
        lambda *args, **kwargs: (set(), {}),
    )

    plan = plan_product_removals(
        session,
        "magento",
        connection_id=1,
        selection="sku_filter",
        sku_filter="RTA-",
        sku_match_mode="starts_with",
    )

    assert plan["candidate_count"] == 1
    assert plan["candidates"][0]["channel_sku"] == "RTA-OLD-SKU"
    assert plan["candidates"][0]["reason"] == "sku_filter:starts_with:RTA-"


def test_removal_candidate_as_dict():
    item = RemovalCandidate(
        master_sku="M1",
        channel_sku="CH-M1",
        remote_id="42",
        reason="master_filter",
    )
    assert item.as_dict()["remote_id"] == "42"
