from db.attribute_mapping import (
    _magento_action_rows,
    _shopify_action_rows,
    _should_publish_to_magento,
    _should_publish_to_shopify,
    _suggest_canonical_code,
    _suggest_purpose,
    _suggest_target_scope,
    _suggest_transform_rule,
    _suggest_value_strategy,
)
from types import SimpleNamespace


def _row(column_key: str) -> dict:
    return {"source_column_key": column_key, "destination_hint": None, "purpose": None}


def test_shopify_option_fields_are_dynamic_channel_projection():
    row = _row("Shopify Option 1 Name")
    scope = _suggest_target_scope(row)
    canonical = _suggest_canonical_code(row)

    assert scope == "dynamic"
    assert _suggest_purpose(row, scope) == "channel_dynamic"
    assert _suggest_transform_rule(row, canonical, scope) == {
        "type": "channel_variation_projection",
        "channel": "shopify",
        "max_options": 3,
        "source": "canonical_variation_model",
    }
    assert _suggest_value_strategy(row, canonical, scope) == (
        "generated_for_shopify_from_canonical_variation_model_max_3_options"
    )


def test_magento_configurable_fields_are_dynamic_channel_projection():
    row = _row("magento_configurable_variations")
    scope = _suggest_target_scope(row)
    canonical = _suggest_canonical_code(row)

    assert scope == "dynamic"
    assert _suggest_purpose(row, scope) == "channel_dynamic"
    assert _suggest_transform_rule(row, canonical, scope) == {
        "type": "channel_variation_projection",
        "channel": "magento",
        "source": "canonical_variation_model",
    }
    assert _suggest_value_strategy(row, canonical, scope) == (
        "generated_for_magento_from_canonical_variation_model"
    )


def test_master_style_fields_remain_shared_canonical_attributes():
    row = _row("Cabinet Door Style")
    scope = _suggest_target_scope(row)

    assert scope == "canonical"
    assert _suggest_purpose(row, scope) == "presentation"
    assert _suggest_canonical_code(row) == "cabinet_door_style"


def test_channel_publish_candidates_are_master_or_explicit_channel_fields():
    master_row = {
        "source_system": "master",
        "suggested_target_scope": "canonical",
    }
    plytix_row = {
        "source_system": "plytix_catalog",
        "suggested_target_scope": "canonical",
    }
    shopify_row = {
        "source_system": "plytix_catalog",
        "suggested_target_scope": "shopify",
    }
    magento_row = {
        "source_system": "magento",
        "suggested_target_scope": "magento",
    }

    assert _should_publish_to_magento(master_row)
    assert _should_publish_to_shopify(master_row)
    assert not _should_publish_to_magento(plytix_row)
    assert not _should_publish_to_shopify(plytix_row)
    assert not _should_publish_to_shopify(shopify_row)
    assert not _should_publish_to_magento(shopify_row)
    assert _should_publish_to_magento(magento_row)
    assert not _should_publish_to_shopify(magento_row)


def test_plytix_shopify_fields_do_not_drive_shopify_actions():
    rows = [
        {
            "source_system": "plytix_catalog",
            "source_label": "plytix",
            "source_column_key": "shopify_description",
            "suggested_canonical_code": "description",
            "suggested_target_scope": "shopify",
            "suggested_purpose": "channel_specific",
            "sku_count": "",
            "sample_values": "",
        }
    ]

    assert _shopify_action_rows(rows, {}) == []


def test_shopify_registry_fields_drive_keep_actions_when_present():
    rows = [
        {
            "source_system": "shopify_registry",
            "source_label": "store.myshopify.com",
            "source_column_key": "custom_material",
            "suggested_canonical_code": "custom_material",
            "suggested_target_scope": "shopify",
            "suggested_purpose": "channel_specific",
            "sku_count": "",
            "sample_values": "Material",
        }
    ]
    existing = {
        "custom_material": {
            "shop_code": "store.myshopify.com",
            "name": "Material",
            "is_standard": False,
        }
    }

    actions = _shopify_action_rows(rows, existing)

    assert len(actions) == 1
    assert actions[0]["action"] == "keep_existing_shopify_field"


def test_shopify_custom_namespace_matches_master_canonical_code():
    rows = [
        {
            "source_system": "master",
            "source_label": "master_catalog",
            "source_column_key": "cabinet_back_material",
            "suggested_canonical_code": "cabinet_back_material",
            "suggested_target_scope": "canonical",
            "suggested_purpose": "presentation",
            "sku_count": "",
            "sample_values": "Plywood",
        }
    ]
    existing = {
        "cabinet_back_material": {
            "shop_code": "store.myshopify.com",
            "attribute_code": "custom_cabinet_back_material",
            "name": "Cabinet Back Material",
            "namespace": "custom",
            "key": "cabinet_back_material",
            "is_standard": False,
        }
    }

    actions = _shopify_action_rows(rows, existing)

    assert len(actions) == 1
    assert actions[0]["action"] == "keep_existing_shopify_field"
    assert actions[0]["attribute_code"] == "cabinet_back_material"


def test_magento_alias_prevents_duplicate_add_and_delete_review():
    desired = {
        "cabinet_door_style": {
            "source_system": "master",
            "source_label": "master_catalog",
            "source_column_key": "cabinet_door_style",
            "suggested_canonical_code": "cabinet_door_style",
            "suggested_target_scope": "canonical",
            "suggested_purpose": "presentation",
            "sku_count": "",
            "sample_values": "Shaker",
        }
    }
    existing = {
        "door_style": {
            "connection_id": 1,
            "frontend_label": "Door style",
            "is_user_defined": True,
        }
    }
    alias = SimpleNamespace(
        canonical_code="cabinet_door_style",
        channel_attribute_code="door_style",
    )

    actions = _magento_action_rows(
        [],
        desired,
        existing,
        {"cabinet_door_style": [alias]},
        {"door_style": alias},
    )

    assert {action["action"] for action in actions} == {"use_existing_channel_alias"}
    assert actions[0]["attribute_code"] == "door_style"
