from unittest.mock import MagicMock, patch

from db.channel_sku_mapping_repair import plan_channel_sku_mapping_repairs
from db.models import ChannelSkuMapping


def _mapping_row(*, mapping_id: int, master_sku: str, channel_sku: str, remote_id: str | None = None):
    row = ChannelSkuMapping(
        master_sku=master_sku,
        channel_code="shopify",
        connection_id=1_000_001,
        channel_sku=channel_sku,
        remote_id=remote_id,
        mapping_status="active",
        match_source="link_from_remote",
    )
    row.id = mapping_id
    return row


@patch("db.channel_sku_mapping_repair.resolve_channel_sku_from_prefixes")
@patch("db.channel_sku_mapping_repair._active_mappings")
@patch("db.channel_sku_mapping_repair._master_skus")
def test_plan_repairs_rta_mirror_channel_sku(mock_masters, mock_mappings, mock_resolve):
    mock_masters.return_value = {"RTA-HPW123", "HPW-B15"}
    mock_mappings.return_value = {
        "RTA-HPW123": _mapping_row(mapping_id=10, master_sku="RTA-HPW123", channel_sku="RTA-HPW123"),
        "HPW-B15": _mapping_row(mapping_id=11, master_sku="HPW-B15", channel_sku="HPW-B15"),
    }

    def resolve(session, master_sku, channel, connection_id=None):
        targets = {
            "RTA-HPW123": "RTA-HD-CW123",
            "HPW-B15": "HD-CW-B15",
        }
        return targets[master_sku]

    mock_resolve.side_effect = resolve
    session = MagicMock()
    session.scalars.return_value.first.return_value = None

    plan = plan_channel_sku_mapping_repairs(
        session,
        "shopify",
        connection_id=1_000_001,
        rta_only=True,
    )

    assert plan["repair_count"] == 1
    assert plan["repairs"][0]["master_sku"] == "RTA-HPW123"
    assert plan["repairs"][0]["target_channel_sku"] == "RTA-HD-CW123"


@patch("db.channel_sku_mapping_repair.resolve_channel_sku_from_prefixes")
@patch("db.channel_sku_mapping_repair._active_mappings")
@patch("db.channel_sku_mapping_repair._master_skus")
def test_plan_skips_when_target_channel_sku_already_occupied(mock_masters, mock_mappings, mock_resolve):
    mock_masters.return_value = {"RTA-HPW123"}
    mock_mappings.return_value = {
        "RTA-HPW123": _mapping_row(mapping_id=10, master_sku="RTA-HPW123", channel_sku="RTA-HPW123"),
    }
    mock_resolve.return_value = "RTA-HD-CW123"

    occupant = _mapping_row(mapping_id=99, master_sku="OTHER", channel_sku="RTA-HD-CW123")
    session = MagicMock()
    session.scalars.return_value.first.return_value = occupant

    plan = plan_channel_sku_mapping_repairs(session, "shopify", connection_id=1_000_001)

    assert plan["repair_count"] == 0
    assert plan["conflict_count"] == 1
    assert plan["conflicts"][0]["conflict_master_sku"] == "OTHER"
