import pandas as pd

from db.channel_exports import map_fields_to_channel
from db.master_static_field_mapping import (
    DEFAULT_STATIC_MASTER_FIELDS,
    DEFAULT_CHANNEL_FIELD_ALIASES,
    DYNAMIC_TRANSFORM_FIELDS,
    _channel_value,
    _default_alias_allowed,
    _default_group,
)


def test_default_static_master_fields_include_core_columns():
    codes = {row["master_attribute_code"] for row in DEFAULT_STATIC_MASTER_FIELDS}
    assert "title" in codes
    assert "meta_title" in codes
    assert "price" in codes


def test_default_group_classification():
    assert _default_group("meta_title") == "seo"
    assert _default_group("title") == "core"
    assert _default_group("base_image") == "media_transform"
    assert _default_group("category_l1") == "taxonomy"
    assert _default_group("msi_source") == "operations_transform"


def test_default_aliases_keep_taxonomy_out_of_static_defaults():
    assert DEFAULT_CHANNEL_FIELD_ALIASES["magento"]["title"] == "name"
    assert DEFAULT_CHANNEL_FIELD_ALIASES["magento"]["brand"] == "family"
    assert DEFAULT_CHANNEL_FIELD_ALIASES["shopify"]["brand"] == "vendor"
    assert DEFAULT_CHANNEL_FIELD_ALIASES["shopify"]["meta_title"] == "seo_title"
    assert DEFAULT_CHANNEL_FIELD_ALIASES["shopify"]["meta_description"] == "seo_description"
    assert DEFAULT_CHANNEL_FIELD_ALIASES["shopify"]["short_description"] == "custom_short_description"
    assert "category_l1" not in DEFAULT_CHANNEL_FIELD_ALIASES["shopify"]
    assert "collection" in DYNAMIC_TRANSFORM_FIELDS


def test_default_alias_allowed_for_known_channel_top_level_fields():
    assert _default_alias_allowed("shopify", "brand", "vendor", {})
    assert _default_alias_allowed("magento", "title", "name", {})
    assert not _default_alias_allowed("magento", "brand", "family", {"magento": {}})
    assert _default_alias_allowed("magento", "brand", "family", {"magento": {"family": "family"}})


def test_channel_value_accepts_short_column_names():
    row = {
        "master_attribute_code": "title",
        "magento": "name",
        "shopify": "title",
        "plytix": "label",
    }
    assert _channel_value(row, "magento") == "name"
    assert _channel_value(row, "shopify") == "title"


def test_wide_csv_row_maps_fields_one_to_one():
    """Simulate post-import alias map used by channel export."""
    alias_map = {
        "title": ["title"],
        "brand": ["vendor"],
    }
    mapped = map_fields_to_channel(
        {"title": "Shaker Cabinet", "brand": "Acme", "cabinet_door_style": "Shaker"},
        alias_map,
    )
    assert mapped["title"] == "Shaker Cabinet"
    assert mapped["vendor"] == "Acme"
    assert mapped["cabinet_door_style"] == "Shaker"


def test_import_dataframe_skips_channel_attribute_reference_rows():
    from db.master_static_field_mapping import import_static_field_mapping_dataframe

    class FakeSession:
        def __init__(self):
            self.executed = 0

        def execute(self, stmt):
            self.executed += 1

        def scalars(self, stmt):
            class R:
                def all(self_inner):
                    return []

            return R()

        def scalar(self, stmt):
            return 0

    df = pd.DataFrame(
        [
            {
                "row_type": "mapping",
                "master_attribute_code": "title",
                "magento": "name",
            },
            {
                "row_type": "channel_attribute",
                "channel_code": "magento",
                "channel_attribute_code": "price",
            },
        ]
    )
    session = FakeSession()
    stats = import_static_field_mapping_dataframe(session, df, sync_aliases=False)
    assert stats["upserted"] == 1
    assert stats["skipped"] == 1


def test_export_static_field_mapping_csv_includes_channel_attribute_rows():
    from db.master_static_field_mapping import export_static_field_mapping_csv_rows
    import db.master_static_field_mapping as module

    class FakeSession:
        pass

    original_build = module.build_static_field_mapping_table

    def fake_build(session, **kwargs):
        return {
            "rows": [
                {
                    "master_attribute_code": "title",
                    "master_label": "Title",
                    "field_group": "core",
                    "data_type": "text",
                    "magento": "name",
                    "shopify": "",
                    "plytix": "",
                    "mapped_channel_count": 1,
                    "is_active": True,
                    "notes": "",
                }
            ],
            "channel_options": {
                "magento": [{"code": "price", "label": "Price", "data_type": "decimal", "source": "magento_attribute_registry"}],
                "shopify": [{"code": "title", "label": "Title", "data_type": "single_line_text_field", "source": "shopify_attribute_registry"}],
                "plytix": [],
            },
        }

    module.build_static_field_mapping_table = fake_build
    try:
        rows = export_static_field_mapping_csv_rows(FakeSession(), magento_connection_id=1, shopify_connection_id=1000001)
    finally:
        module.build_static_field_mapping_table = original_build

    mapping_rows = [row for row in rows if row["row_type"] == "mapping"]
    channel_rows = [row for row in rows if row["row_type"] == "channel_attribute"]
    assert len(mapping_rows) == 1
    assert len(channel_rows) == 2
    assert {row["channel_code"] for row in channel_rows} == {"magento", "shopify"}
    magento_row = next(row for row in channel_rows if row["channel_code"] == "magento")
    shopify_row = next(row for row in channel_rows if row["channel_code"] == "shopify")
    assert magento_row["connection_id"] == 1
    assert shopify_row["connection_id"] == 1000001


def test_import_dataframe_parses_wide_columns():
    from db.master_static_field_mapping import import_static_field_mapping_dataframe

    class FakeSession:
        def __init__(self):
            self.executed = 0

        def execute(self, stmt):
            self.executed += 1

        def scalars(self, stmt):
            class R:
                def all(self_inner):
                    return []

            return R()

        def scalar(self, stmt):
            return 0

    df = pd.DataFrame(
        [
            {
                "master_attribute_code": "title",
                "magento": "name",
                "shopify": "title",
            }
        ]
    )
    session = FakeSession()
    stats = import_static_field_mapping_dataframe(session, df, sync_aliases=False)
    assert stats["upserted"] == 1
    assert stats["skipped"] == 0
