"""Group VCP features into UI sections. Pure, no GTK."""

from __future__ import annotations

from .i18n import N_
from .models import Access, Feature

# Section labels are kept as stable English identifiers (dict keys + ORDER) and
# marked with N_ so xgettext extracts them; the UI translates each with _() at
# render time (see window._render).
BRIGHTNESS = N_("Brightness & Contrast")
COLOR = N_("Color")
IMAGE = N_("Image & Mode")
GEOMETRY = N_("Geometry")
INPUT = N_("Input")
POWER = N_("Power")
AUDIO = N_("Audio")
OSD = N_("On-Screen Display")
ACTIONS = N_("Actions")
MANUFACTURER = N_("Manufacturer-specific features")
INFO = N_("Monitor Info")
OTHER = N_("Other")

# Codes at or above this are manufacturer-specific (outside the MCCS table).
MANUFACTURER_MIN = 0xE0

# Display order of sections in the UI.
ORDER: list[str] = [
    BRIGHTNESS,
    COLOR,
    IMAGE,
    GEOMETRY,
    INPUT,
    AUDIO,
    OSD,
    POWER,
    ACTIONS,
    OTHER,
    MANUFACTURER,
    INFO,
]

# Known VCP code -> category. Codes not listed fall back by access mode.
_CODE_CATEGORY: dict[int, str] = {
    0x10: BRIGHTNESS,
    0x12: BRIGHTNESS,
    0x6B: BRIGHTNESS,  # backlight white
    0x14: COLOR,  # select color preset
    0x16: COLOR,  # video gain red
    0x18: COLOR,  # video gain green
    0x1A: COLOR,  # video gain blue
    0x6C: COLOR,  # video black level red
    0x6E: COLOR,  # video black level green
    0x70: COLOR,  # video black level blue
    0x0B: COLOR,  # color temperature increment
    0x0C: COLOR,  # color temperature request
    0x72: COLOR,  # gamma
    0x90: COLOR,  # hue
    0x59: COLOR,  # 6-axis saturation
    0x5A: COLOR,
    0x5B: COLOR,
    0x5C: COLOR,
    0x5D: COLOR,
    0x5E: COLOR,
    0x60: INPUT,  # input source
    0xAA: IMAGE,  # screen orientation
    0xDC: IMAGE,  # display mode
    0x86: IMAGE,  # display scaling
    0x87: IMAGE,  # sharpness
    0x0E: IMAGE,  # clock
    0x1E: IMAGE,  # auto setup
    0xDA: IMAGE,  # scan mode
    0xD0: IMAGE,  # output select
    0x20: GEOMETRY,  # horizontal position
    0x22: GEOMETRY,  # horizontal size
    0x24: GEOMETRY,  # horizontal pincushion
    0x30: GEOMETRY,  # vertical position
    0x32: GEOMETRY,  # vertical size
    0x34: GEOMETRY,  # vertical pincushion
    0x3E: GEOMETRY,  # clock phase
    0x9B: COLOR,  # 6-axis hue red
    0x9C: COLOR,
    0x9D: COLOR,
    0x9E: COLOR,
    0x9F: COLOR,
    0xA0: COLOR,
    0xD6: POWER,  # power mode
    0xDF: INFO,  # vcp version
    0x62: AUDIO,  # audio speaker volume
    0x63: AUDIO,  # audio speaker select
    0x64: AUDIO,  # audio mute
    0x66: AUDIO,  # audio treble
    0x8D: AUDIO,  # audio mute / screen blank
    0xCA: OSD,  # osd / button control
    0xCC: OSD,  # osd language
    0x02: ACTIONS,  # new control value
    0x04: ACTIONS,  # restore factory defaults
    0x05: ACTIONS,  # restore factory brightness/contrast
    0x06: ACTIONS,  # restore factory geometry
    0x08: ACTIONS,  # restore color defaults
    0x0A: ACTIONS,  # restore factory tv defaults
}


def category_for(feature: Feature) -> str:
    if feature.access == Access.READ_ONLY:
        return INFO
    mapped = _CODE_CATEGORY.get(feature.code)
    if mapped is not None:
        return mapped
    if feature.access == Access.WRITE_ONLY:
        return ACTIONS
    if feature.code >= MANUFACTURER_MIN:
        return MANUFACTURER
    return OTHER


def group_features(features: list[Feature]) -> list[tuple[str, list[Feature]]]:
    """Bucket features by category, returned in ORDER. Empty groups dropped."""
    buckets: dict[str, list[Feature]] = {name: [] for name in ORDER}
    for feature in features:
        buckets.setdefault(category_for(feature), []).append(feature)
    return [(name, buckets[name]) for name in ORDER if buckets.get(name)]
