import secrets

from markupsafe import escape

from odoo import api, fields, models


class AffiliateWidgetConfig(models.Model):
    _name = "affiliate.widget.config"
    _description = "Affiliate Widget Configuration"
    _rec_name = "partner_id"

    partner_id = fields.Many2one(
        "res.partner",
        string="Affiliate",
        required=True,
        ondelete="cascade",
        domain=[("role_user_type", "=", "affiliate")],
    )
    widget_key = fields.Char(
        string="Widget Key",
        required=True,
        readonly=True,
        copy=False,
        index=True,
        default=lambda self: secrets.token_urlsafe(16),
    )
    is_active = fields.Boolean(string="Active", default=True)

    # --- Widget Mode ---
    widget_mode = fields.Selection(
        [
            ("overlay", "Overlay (Popup)"),
            ("inline", "Inline (Embedded)"),
            ("grid", "Grid (Job Cards)"),
            ("box", "Box Widget (Compact)"),
        ],
        string="Widget Mode",
        default="overlay",
    )

    # =====================================================================
    # OVERLAY-ONLY SETTINGS (presentation wrapper for popup mode)
    # =====================================================================
    position = fields.Selection(
        [
            ("bottom-right", "Bottom Right"),
            ("bottom-left", "Bottom Left"),
            ("top-right", "Top Right"),
            ("top-left", "Top Left"),
        ],
        string="Button Position",
        default="bottom-right",
    )
    primary_color = fields.Char(string="Primary Color", default="#c0392b")
    text_color = fields.Char(string="Text Color", default="#ffffff")
    button_style = fields.Selection(
        [
            ("pill", "Pill"),
            ("rounded", "Rounded"),
            ("square", "Square"),
        ],
        string="Button Style",
        default="pill",
    )
    overlay_radius = fields.Selection(
        [
            ("16", "Rounded (16px)"),
            ("8", "Subtle (8px)"),
            ("0", "Sharp (0px)"),
        ],
        string="Overlay Corners",
        default="16",
    )
    button_text = fields.Char(string="Button Text", default="Karriere-Jura")
    language = fields.Selection(
        [("de", "Deutsch"), ("en", "English")],
        string="Language",
        default="de",
    )
    show_button = fields.Boolean(string="Show Floating Button", default=True)

    # Toolbar options
    show_logo = fields.Boolean(string="Show Logo in Toolbar", default=True)
    toolbar_height = fields.Selection(
        [
            ("44", "Compact (44px)"),
            ("56", "Normal (56px)"),
            ("0", "Hidden"),
        ],
        string="Toolbar Height",
        default="44",
    )

    # Overlay body options
    backdrop_opacity = fields.Selection(
        [
            ("60", "Normal (60%)"),
            ("40", "Light (40%)"),
            ("80", "Dark (80%)"),
            ("0", "None (transparent)"),
        ],
        string="Backdrop Opacity",
        default="60",
    )
    overlay_border = fields.Boolean(string="Show Overlay Border", default=False)
    border_color = fields.Char(string="Border Color", default="#d0d0d0")
    bg_image_url = fields.Char(string="Background Image URL")
    bg_image_opacity = fields.Selection(
        [
            ("10", "10%"),
            ("20", "20%"),
            ("30", "30%"),
            ("50", "50%"),
        ],
        string="Background Image Opacity",
        default="20",
    )

    # Navigation sidebar
    nav_layout = fields.Selection(
        [
            ("hidden", "Hidden"),
            ("left-sidebar", "Left Sidebar"),
        ],
        string="Navigation Layout",
        default="hidden",
    )
    nav_bg_color = fields.Char(string="Navigation Background", default="#1b2a4a")
    nav_font_color = fields.Char(string="Navigation Text Color", default="#ffffff")

    # Overlay footer bar (widget chrome, not KJ site footer)
    show_footer = fields.Boolean(string="Show Footer", default=False)
    footer_text = fields.Char(
        string="Footer Text", default="Powered by Karriere-Jura",
    )
    footer_bg_color = fields.Char(string="Footer Background", default="#f5f5f5")
    footer_font_color = fields.Char(string="Footer Text Color", default="#999999")

    # Landing page for iframe
    landing_page = fields.Selection(
        [
            ("/", "Homepage"),
            ("/job-offers", "Job Offers"),
            ("/company-profiles", "Company Profiles"),
        ],
        string="Landing Page",
        default="/job-offers",
    )

    # =====================================================================
    # SHARED THEME SETTINGS (apply to KJ site inside iframe — both modes)
    # =====================================================================

    # Base theme color → auto-generates palette
    theme_color = fields.Char(string="Theme Color", default="#c0392b")
    theme_font_family = fields.Selection(
        [
            ("system", "System Default"),
            ("open-sans", "Open Sans"),
            ("roboto", "Roboto"),
            ("lato", "Lato"),
            ("montserrat", "Montserrat"),
            ("raleway", "Raleway"),
            ("ubuntu", "Ubuntu"),
            ("merriweather", "Merriweather"),
            ("playfair", "Playfair Display"),
            ("pt-sans", "PT Sans"),
            ("noto-sans", "Noto Sans"),
            ("source-sans", "Source Sans Pro"),
        ],
        string="Theme Font",
        default="system",
    )
    theme_font_size = fields.Integer(string="Base Font Size (px)", default=14)

    # Color overrides (empty = auto-derived from theme_color)
    theme_bg_color = fields.Char(string="Background Color")
    theme_heading_color = fields.Char(string="Heading Color")
    theme_text_color = fields.Char(string="Body Text Color")
    theme_link_color = fields.Char(string="Link Color")
    theme_btn_color = fields.Char(string="Button Color")
    theme_border_color = fields.Char(string="Theme Border Color")

    # Navbar (inside KJ site)
    theme_navbar_scheme = fields.Selection(
        [
            ("default", "KJ Default"),
            ("light", "Light"),
            ("dark", "Dark"),
            ("custom", "Custom"),
        ],
        string="Navbar Style",
        default="default",
    )
    theme_navbar_bg = fields.Char(string="Navbar Background")
    theme_navbar_text = fields.Char(string="Navbar Text Color")

    # KJ site footer (inside iframe)
    theme_site_footer_visible = fields.Boolean(
        string="Show Site Footer", default=False,
    )
    theme_site_footer_scheme = fields.Selection(
        [
            ("default", "KJ Default"),
            ("light", "Light"),
            ("dark", "Dark"),
            ("custom", "Custom"),
        ],
        string="Footer Style",
        default="default",
    )
    theme_site_footer_bg = fields.Char(string="Site Footer Background")
    theme_site_footer_text = fields.Char(string="Site Footer Text Color")

    # Cards & Forms
    theme_card_bg = fields.Char(string="Card Background")
    theme_card_header_bg = fields.Char(string="Card Header Background")
    theme_input_bg = fields.Char(string="Input Background")
    theme_form_bg = fields.Char(string="Form Background")

    # Content visibility
    theme_show_search = fields.Boolean(string="Show Search Bar", default=True)
    theme_show_logo = fields.Boolean(string="Show KJ Logo", default=True)
    theme_show_newsletter_popup = fields.Boolean(
        string="Show Newsletter Popup", default=False,
    )
    theme_custom_title = fields.Char(string="Custom Page Title", translate=True)
    theme_no_results_text = fields.Text(
        string="No Results Text", translate=True,
    )

    # =====================================================================
    # INLINE-ONLY SETTINGS (embedded in-page presentation)
    # =====================================================================
    inline_width = fields.Char(string="Widget Width", default="100%")
    inline_height = fields.Char(string="Widget Height", default="800px")
    inline_auto_resize = fields.Boolean(
        string="Auto-Resize Height", default=True,
    )

    # --- Header visibility ---
    inline_show_header = fields.Boolean(
        string="Show Header", default=True,
        help="Show the entire KJ header (logo + topbar + navbar).",
    )
    inline_show_topbar = fields.Boolean(
        string="Show Top Bar", default=True,
        help="Show the top bar (social icons, language, login).",
    )
    inline_show_logo = fields.Boolean(
        string="Show KJ Logo in Header", default=True,
        help="Show the KJ logo in the header area.",
    )
    inline_custom_logo = fields.Binary(
        string="Custom Logo",
        help="Upload a custom logo to replace the KJ logo in the header.",
    )
    inline_custom_logo_url = fields.Char(
        string="Custom Logo URL",
        help="URL to a custom logo image (alternative to upload).",
    )
    inline_show_menu = fields.Boolean(
        string="Show Menu", default=True,
        help="Show the main navigation menu.",
    )
    inline_menu_layout = fields.Selection(
        [
            ("horizontal", "Horizontal (default top bar)"),
            ("vertical", "Vertical (left sidebar)"),
        ],
        string="Menu Layout",
        default="horizontal",
        help="How to display the navigation menu.",
    )
    inline_show_menu_stellenangebote = fields.Boolean(
        string="Show 'Stellenangebote'", default=True,
    )
    inline_show_menu_firmenprofile = fields.Boolean(
        string="Show 'Firmenprofile'", default=True,
    )
    inline_show_menu_karriere_tipps = fields.Boolean(
        string="Show 'Karriere-Tipps'", default=True,
    )
    inline_show_menu_actions = fields.Boolean(
        string="Show Action Buttons", default=True,
        help="Show Wishlist and Post Job buttons in header.",
    )

    inline_border_radius = fields.Selection(
        [
            ("0", "None"),
            ("8", "Subtle (8px)"),
            ("16", "Rounded (16px)"),
        ],
        string="Border Radius",
        default="0",
    )

    # =====================================================================
    # BOX WIDGET SETTINGS (compact job ticker)
    # =====================================================================
    box_title = fields.Char(
        string="Box Title",
        default="Neue Stellenangebote",
        translate=True,
    )
    box_job_count = fields.Integer(string="Number of Jobs", default=5)
    box_layout = fields.Selection(
        [("vertical", "Vertical"), ("horizontal", "Horizontal")],
        string="Box Layout",
        default="vertical",
    )
    box_link_target = fields.Selection(
        [("_blank", "New Tab"), ("_parent", "Same Window")],
        string="Link Target",
        default="_blank",
    )
    box_header_bg = fields.Char(string="Box Header Background", default="#c0392b")
    box_header_text = fields.Char(string="Box Header Text", default="#ffffff")
    box_header_font_size = fields.Integer(
        string="Box Header Font Size", default=14,
    )
    box_body_bg = fields.Char(string="Box Body Background", default="#ffffff")
    box_body_font_size = fields.Integer(
        string="Box Body Font Size", default=12,
    )
    box_link_color = fields.Char(string="Box Link Color", default="#0645AD")
    box_show_border = fields.Boolean(string="Show Box Border", default=True)
    box_border_color = fields.Char(string="Box Border Color", default="#dddddd")
    box_footer_bg = fields.Char(string="Box Footer Background", default="#f5f5f5")
    box_footer_text = fields.Char(string="Box Footer Text", default="#999999")
    box_width = fields.Char(string="Box Width", default="300px")
    box_height = fields.Char(string="Box Height", default="auto")

    # =====================================================================
    # JOB FILTERING (shared — applies to all modes)
    # =====================================================================
    filter_mode = fields.Selection(
        [
            ("all", "All Published Jobs"),
            ("curated", "Curated Job List"),
            ("filtered", "Filtered by Category"),
        ],
        string="Job Filter Mode",
        default="all",
    )
    filter_job_ids = fields.Many2many(
        "hr.job",
        "affiliate_widget_filter_job_rel",
        "config_id",
        "job_id",
        string="Curated Jobs",
    )
    filter_field_ids = fields.Many2many(
        "hr.job.fields",
        "affiliate_widget_filter_field_rel",
        "config_id",
        "field_id",
        string="Fields of Law",
    )
    filter_function_ids = fields.Many2many(
        "hr.job.function",
        "affiliate_widget_filter_func_rel",
        "config_id",
        "function_id",
        string="Job Functions",
    )
    filter_employer_ids = fields.Many2many(
        "res.partner",
        "affiliate_widget_filter_employer_rel",
        "config_id",
        "partner_id",
        string="Employers",
        domain=[("is_company", "=", True)],
    )

    # =====================================================================
    # COMPUTED STATS
    # =====================================================================
    total_impressions = fields.Integer(
        string="Total Impressions",
        compute="_compute_stats",
    )
    total_clicks = fields.Integer(
        string="Total Clicks",
        compute="_compute_stats",
    )

    _sql_constraints = [
        (
            "widget_key_unique",
            "UNIQUE(widget_key)",
            "Widget key must be unique.",
        ),
        (
            "partner_unique",
            "UNIQUE(partner_id)",
            "Each affiliate can only have one widget configuration.",
        ),
    ]

    def _compute_stats(self):
        if not self.ids:
            for rec in self:
                rec.total_impressions = 0
                rec.total_clicks = 0
            return
        groups = self.env["affiliate.widget.event"].read_group(
            domain=[("config_id", "in", self.ids)],
            fields=["config_id", "event_type"],
            groupby=["config_id", "event_type"],
            lazy=False,
        )
        impressions = {}
        clicks = {}
        for g in groups:
            cid = g["config_id"][0]
            if g["event_type"] == "impression":
                impressions[cid] = g["__count"]
            elif g["event_type"] == "click":
                clicks[cid] = g["__count"]
        for rec in self:
            rec.total_impressions = impressions.get(rec.id, 0)
            rec.total_clicks = clicks.get(rec.id, 0)

    def get_embed_code(self):
        """Return the HTML embed snippet for the affiliate.

        Only the widget key is embedded in the script tag. All configuration
        is fetched from the server at runtime via /api/widget/config/<key>,
        so changes in the portal take effect immediately without re-embedding.
        """
        self.ensure_one()
        base_url = (
            self.env["ir.config_parameter"].sudo().get_param("web.base.url")
        )
        mode = self.widget_mode or "overlay"

        script_tag = (
            f'<script src="{escape(base_url)}/api/widget/kj-widget.js?v=4"'
            f' data-kj-key="{escape(self.widget_key)}"'
            f" defer></script>"
        )

        if mode in ("inline", "box"):
            return f'<div id="kj-widget"></div>\n{script_tag}'
        return script_tag
