"""Track D — Mode-specific fields (overlay 19 + inline 15 + box 16).

The `get_widget_config` JSON endpoint is what the widget JS reads on
boot — every mode-specific knob the affiliate sets in the backend
form must arrive in the right JSON key. This file walks the full
3-mode matrix with self.subTest() so a wiring break on any single
field surfaces as a clearly-labelled assertion failure.

Each row is `(field_on_model, json_key_in_response, value_to_set,
expected_in_json)`. ``expected_in_json`` is usually the value verbatim;
where the endpoint coerces (e.g. ``None`` for unset, ``int`` for
counts) the expected differs from the input.

Why one big subTest loop instead of N test methods: 50 cookie-cutter
tests churn the suite output. The subTest pattern reports a
clean per-field row when one fails, and otherwise stays quiet.
"""

from odoo.tests import tagged

from odoo.addons.kj_affiliate_widget.tests.common import WidgetTestCommon


@tagged("post_install", "-at_install", "kj_affiliate_widget", "D")
class TestConfigTrackDModeSpecific(WidgetTestCommon):

    def _get_json(self, mode=None):
        url = f"/api/widget/config/{self.config.widget_key}"
        if mode:
            url += f"?mode={mode}"
        r = self.url_open(url)
        self.assertEqual(r.status_code, 200)
        return r.json()

    # =================================================================
    # OVERLAY (19 fields)
    # =================================================================

    def test_d_overlay_fields(self):
        cases = [
            # (field, json_key, value, expected)
            ("position",            "position",        "top-left",         "top-left"),
            ("button_style",        "btn_style",       "square",           "square"),
            ("overlay_radius",      "overlay_radius",  "8",                "8"),
            ("button_text",         "text",            "Karriere check",   "Karriere check"),
            ("show_button",         "button",          False,              False),
            ("show_logo",           "logo",            False,              False),
            ("toolbar_height",      "toolbar_height",  "56",               "56"),
            ("backdrop_opacity",    "backdrop",        "80",               "80"),
            ("overlay_border",      "border",          True,               True),
            ("border_color",        "border_color",    "#ff00ff",          "#ff00ff"),
            ("bg_image_url",        "bg_image",        "https://i.test/bg.png", "https://i.test/bg.png"),
            ("bg_image_opacity",    "bg_opacity",      "50",               "50"),
            ("nav_layout",          "nav",             "left-sidebar",     "left-sidebar"),
            ("nav_bg_color",        "nav_bg",          "#0a1a2a",          "#0a1a2a"),
            ("nav_font_color",      "nav_fc",          "#fefefe",          "#fefefe"),
            ("show_footer",         "footer",          True,               True),
            ("footer_text",         "footer_text",     "© Affiliate",      "© Affiliate"),
            ("footer_bg_color",     "footer_bg",       "#202020",          "#202020"),
            ("footer_font_color",   "footer_fc",       "#cccccc",          "#cccccc"),
        ]
        # widget_mode='overlay' so the response matches the realistic shape
        self.config.widget_mode = "overlay"
        for field, json_key, value, expected in cases:
            with self.subTest(field=field):
                self.config.write({field: value})
                data = self._get_json(mode="overlay")
                self.assertEqual(
                    data.get(json_key), expected,
                    f"overlay field {field!r}={value!r} expected JSON "
                    f"{json_key}={expected!r}, got {data.get(json_key)!r}",
                )

    # =================================================================
    # INLINE (15 fields)
    # =================================================================

    def test_d_inline_fields(self):
        cases = [
            ("inline_width",                    "width",                       "75%",     "75%"),
            ("inline_height",                   "height",                      "640px",   "640px"),
            ("inline_auto_resize",              "auto_resize",                 True,      True),
            ("inline_border_radius",            "border_radius",               "8",       "8"),
            ("inline_show_topbar",              "topbar",                      True,      True),
            ("inline_show_header",              "show_header",                 True,      True),
            ("inline_show_logo",                "show_logo",                   True,      True),
            ("inline_custom_logo_url",          "custom_logo_url",             "https://i.test/lg.png", "https://i.test/lg.png"),
            ("inline_show_menu",                "show_menu",                   True,      True),
            ("inline_menu_layout",              "menu_layout",                 "vertical", "vertical"),
            ("inline_show_menu_stellenangebote","show_menu_stellenangebote",   False,     False),
            ("inline_show_menu_firmenprofile",  "show_menu_firmenprofile",     False,     False),
            ("inline_show_menu_karriere_tipps", "show_menu_karriere_tipps",    False,     False),
            ("inline_show_menu_actions",        "show_menu_actions",           False,     False),
            ("theme_footer_mode",               "footer_mode",                 "full",    "full"),
        ]
        self.config.widget_mode = "inline"
        for field, json_key, value, expected in cases:
            with self.subTest(field=field):
                self.config.write({field: value})
                data = self._get_json(mode="inline")
                self.assertEqual(
                    data.get(json_key), expected,
                    f"inline field {field!r}={value!r} expected JSON "
                    f"{json_key}={expected!r}, got {data.get(json_key)!r}",
                )

    # =================================================================
    # BOX (16 fields)
    # =================================================================

    def test_d_box_fields(self):
        cases = [
            ("box_job_count",       "box_count",         8,            8),
            ("box_layout",          "box_layout",        "horizontal", "horizontal"),
            ("box_link_target",     "box_target",        "_parent",    "_parent"),
            ("box_title",           "box_title",         "Top Jobs",   "Top Jobs"),
            ("box_header_bg",       "box_header_bg",     "#003366",    "#003366"),
            ("box_header_text",     "box_header_text",   "#ffeecc",    "#ffeecc"),
            ("box_header_font_size","box_header_fs",     20,           20),
            ("box_body_bg",         "box_body_bg",       "#f9f9f9",    "#f9f9f9"),
            ("box_body_font_size",  "box_body_fs",       13,           13),
            ("box_link_color",      "box_link_color",    "#9b59b6",    "#9b59b6"),
            ("box_show_border",     "box_border",        True,         True),
            ("box_border_color",    "box_border_color",  "#e0e0e0",    "#e0e0e0"),
            ("box_footer_bg",       "box_footer_bg",     "#222222",    "#222222"),
            ("box_footer_text",     "box_footer_text",   "#aaaaaa",    "#aaaaaa"),
            ("box_width",           "box_width",         "400px",      "400px"),
            ("box_height",          "box_height",        "500px",      "500px"),
        ]
        self.config.widget_mode = "box"
        for field, json_key, value, expected in cases:
            with self.subTest(field=field):
                self.config.write({field: value})
                data = self._get_json(mode="box")
                self.assertEqual(
                    data.get(json_key), expected,
                    f"box field {field!r}={value!r} expected JSON "
                    f"{json_key}={expected!r}, got {data.get(json_key)!r}",
                )

    # =================================================================
    # Regression — track_event mode disambiguation
    # =================================================================

    def test_d_track_event_routes_by_mode_when_key_has_multiple_configs(self):
        """When a widget_key has both inline + overlay configs, passing
        ``mode`` on /api/widget/event must route the event to the
        matching config row — not to the lowest-id config.

        Pre-fix, every event silently attributed to whichever config
        had the lower id; the other mode's analytics were stuck at 0.
        """
        import json as _json
        # Create a second config (overlay) for the same key.
        other = self.config.copy({
            "widget_mode": "overlay",
            "widget_key": self.config.widget_key,
        })
        # Lower-id one is the original (inline). Fire an overlay event.
        r = self.url_open(
            "/api/widget/event",
            data=_json.dumps({
                "key": self.config.widget_key,
                "type": "click",
                "mode": "overlay",
                "job_id": self.job.id,
            }),
            headers={"Content-Type": "application/json"},
        )
        self.assertEqual(r.status_code, 200)
        # Force-flush the batched event queue.
        from odoo.addons.kj_affiliate_widget.controllers import widget_api as _wa
        _wa._flush_event_queue()
        # The event row must point at the overlay config, not the inline one.
        events = self.env["affiliate.widget.event"].search([
            ("config_id", "in", (self.config.id, other.id)),
            ("event_type", "=", "click"),
        ])
        self.assertEqual(len(events), 1)
        self.assertEqual(
            events.config_id, other,
            "Click event must attribute to the overlay config (the one "
            "the visitor actually saw), not the inline config.",
        )
