"""
Part comparator screen for the NEXUS AUTOPARTS console application.

Displays a side-by-side comparison of an OEM part against its aftermarket
alternatives.  The first column is always the OEM part; subsequent columns
are aftermarket options.  Below the comparison table, cross-reference
numbers are shown grouped by type.
"""

from console.core.screens import Screen
from console.core.keybindings import Key
from console.config import APP_NAME, VERSION
from console.utils.formatting import format_currency, quality_bar


# Footer labels
_FOOTER = [
    ("\u2190\u2192", "Scroll"),
    ("#", "Ver detalle"),
    ("F3", "Otra parte"),
    ("ESC", "Atras"),
]


class ComparadorScreen(Screen):
    """Side-by-side OEM vs aftermarket comparison."""

    def __init__(self):
        super().__init__(name="comparador", title="Comparador")
        self._part = None
        self._alternatives = []
        self._cross_refs = []
        self._manufacturers = {}  # id -> dict
        self._col_offset = 0      # horizontal scroll offset
        self._selected_alt = 0    # currently highlighted alternative

    # ------------------------------------------------------------------
    # Data loading
    # ------------------------------------------------------------------

    def _load(self, context, db):
        """Load OEM part, alternatives, cross-refs, and manufacturer info."""
        part_id = context.get("part_id")
        if part_id is None:
            self._part = None
            self._alternatives = []
            self._cross_refs = []
            return

        self._part = db.get_part(part_id)
        self._alternatives = db.get_alternatives(part_id) if self._part else []
        self._cross_refs = db.get_cross_references(part_id) if self._part else []

        # Build manufacturer lookup for country info
        try:
            mfrs = db.get_manufacturers()
            self._manufacturers = {m["id"]: m for m in mfrs}
        except Exception:
            self._manufacturers = {}

        # Set initial column offset to show the selected alternative
        selected = context.get("selected_alt_index", 0)
        if 0 <= selected < len(self._alternatives):
            self._selected_alt = selected
        else:
            self._selected_alt = 0
        self._col_offset = 0

    # ------------------------------------------------------------------
    # Helpers
    # ------------------------------------------------------------------

    @staticmethod
    def _format_warranty(months):
        """Format warranty months as 'X meses' or '──' if missing."""
        if months is None:
            return "\u2500\u2500"
        return f"{months} meses"

    @staticmethod
    def _calc_savings(oem_price, alt_price):
        """Calculate percentage savings of alt vs OEM.

        Returns a formatted string like '-28%' or '──' when prices are
        unavailable.
        """
        if oem_price is None or alt_price is None or oem_price == 0:
            return "\u2500\u2500"
        pct = ((oem_price - alt_price) / oem_price) * 100
        if pct > 0:
            return f"-{pct:.0f}%"
        elif pct < 0:
            return f"+{abs(pct):.0f}%"
        return "0%"

    @staticmethod
    def _format_stock(in_stock):
        """Format boolean in_stock as Si/No."""
        if in_stock is None:
            return "\u2500\u2500"
        return "Si" if in_stock else "No"

    def _build_columns(self):
        """Build the column list for draw_comparison.

        First column is the OEM part, followed by each aftermarket
        alternative.  Returns a list of dicts with 'header' and 'rows'.
        """
        if self._part is None:
            return []

        p = self._part
        oem_price = None  # OEM parts don't have price_usd in our schema

        # ── OEM column ──
        oem_col = {
            "header": "OEM",
            "rows": [
                ("Numero", p.get("oem_part_number", "")),
                ("Calidad", quality_bar("oem")),
                ("Tier", "OEM"),
                ("Precio USD", "\u2500\u2500"),
                ("Ahorro", "\u2500\u2500"),
                ("Garantia", "\u2500\u2500"),
                ("En stock", "\u2500\u2500"),
                ("Fabricante", p.get("category_name", "")),
            ],
        }

        columns = [oem_col]

        # ── Aftermarket columns ──
        for alt in self._alternatives:
            tier = alt.get("quality_tier", "") or ""
            price = alt.get("price_usd")
            mfr_id = alt.get("manufacturer_id")
            mfr_name = alt.get("manufacturer_name", "")
            mfr_country = ""
            if mfr_id and mfr_id in self._manufacturers:
                mfr_country = self._manufacturers[mfr_id].get("country", "") or ""

            alt_col = {
                "header": mfr_name,
                "rows": [
                    ("Numero", alt.get("part_number", "")),
                    ("Calidad", quality_bar(tier.lower()) if tier else "\u2500\u2500"),
                    ("Tier", tier.capitalize()),
                    ("Precio USD", format_currency(price)),
                    ("Ahorro", self._calc_savings(oem_price, price)),
                    ("Garantia", self._format_warranty(alt.get("warranty_months"))),
                    ("En stock", self._format_stock(alt.get("in_stock"))),
                    ("Fabricante", mfr_country if mfr_country else mfr_name),
                ],
            }
            columns.append(alt_col)

        return columns

    # ------------------------------------------------------------------
    # Render
    # ------------------------------------------------------------------

    def render(self, context, db, renderer):
        self._load(context, db)

        # Header
        renderer.draw_header(
            f" {APP_NAME} v{VERSION}",
            " COMPARADOR OEM vs AFTERMARKET ",
        )

        if self._part is None:
            renderer.draw_text(5, 4, "Parte no encontrada", "error")
            renderer.draw_footer([("ESC", "Atras")])
            return

        # Build comparison columns
        all_columns = self._build_columns()

        # Apply horizontal scroll: always show OEM (col 0) + offset slice
        if len(all_columns) <= 1:
            visible_columns = all_columns
        else:
            # Determine how many alt columns we can show.
            # The renderer will auto-size, but let's allow scrolling
            # through alternatives.
            h, w = renderer.get_size()
            # Rough estimate: label_w ~12, each col ~15-20 chars
            # We keep it simple: show OEM + up to 3 alternatives at a time
            max_visible_alts = max((w - 20) // 18, 1)
            alt_cols = all_columns[1:]  # all aftermarket columns
            end = min(self._col_offset + max_visible_alts, len(alt_cols))
            visible_columns = [all_columns[0]] + alt_cols[self._col_offset:end]

        part_name = self._part.get("name_es") or self._part.get("name", "")
        oem_number = self._part.get("oem_part_number", "")
        title = f"COMPARACION: {oem_number} - {part_name}"

        renderer.draw_comparison(visible_columns, title=title)

        # ── Cross-references below the comparison ──
        h, w = renderer.get_size()
        # Estimate row where comparison ends:
        # title(3) + header(1) + sep(1) + 8 data rows + 1 gap = 14
        xref_row = 3 + 3 + 1 + 8 + 2

        if self._cross_refs and xref_row < h - 4:
            section_title = (
                "\u2500\u2500 CROSS-REFERENCES "
                + "\u2500" * max(w - 24, 4)
            )
            renderer.draw_text(xref_row, 2, section_title, "title")
            xref_row += 1

            # Group by reference type
            by_type = {}
            for xr in self._cross_refs:
                rtype = xr.get("reference_type", "other") or "other"
                by_type.setdefault(rtype, []).append(
                    xr.get("cross_reference_number", "")
                )
            for rtype, numbers in by_type.items():
                if xref_row >= h - 3:
                    break
                line = f"{rtype.capitalize()}: {', '.join(numbers)}"
                renderer.draw_text(xref_row, 4, line, "normal")
                xref_row += 1

        # Scroll indicator
        if len(all_columns) > 1:
            alt_count = len(all_columns) - 1
            indicator = (
                f"  Mostrando alternativas "
                f"{self._col_offset + 1}-"
                f"{min(self._col_offset + len(visible_columns) - 1, alt_count)}"
                f" de {alt_count}"
            )
            indicator_row = min(xref_row + 1, h - 4)
            if indicator_row > 0:
                renderer.draw_text(indicator_row, 2, indicator, "info")

        renderer.draw_footer(_FOOTER)

    # ------------------------------------------------------------------
    # Key handling
    # ------------------------------------------------------------------

    def on_key(self, key, context, db, renderer, nav):
        # ESC: back to part detail
        if key == Key.ESCAPE:
            return "back"

        # Left arrow: scroll columns left
        if key == Key.LEFT:
            if self._col_offset > 0:
                self._col_offset -= 1
            return None

        # Right arrow: scroll columns right
        if key == Key.RIGHT:
            max_offset = max(len(self._alternatives) - 1, 0)
            if self._col_offset < max_offset:
                self._col_offset += 1
            return None

        # Number keys (1-9): view alternative detail
        if 49 <= key <= 57:  # '1'..'9'
            idx = key - 49  # 0-based
            if self._alternatives and 0 <= idx < len(self._alternatives):
                part_id = context.get("part_id")
                return (
                    "comparador",
                    {"part_id": part_id, "selected_alt_index": idx},
                    "Comparador",
                )
            return None

        # F3: search for another part (go to buscar_parte)
        if key == Key.F3:
            return ("buscar_parte", {}, "Buscar Parte")

        return None
