
from __future__ import annotations
from typing import Dict, Union
from bs4 import BeautifulSoup
from shared.utils import normalize_text
from ..registry import extractor
from ..helpers.price import parse_price, parse_case_size

@extractor
def ex_info_table(soup: BeautifulSoup, url: str) -> Dict:
    """
    Extracts:
    <div class="product-page-info-table"> ... rows of label/content ... </div>
    Produces:
      info_table (raw map), brand, rrp[_raw|_currency], price_per_unit[_raw|_currency],
      case_size_* fields
    """
    container = soup.select_one(".product-page-info-table") or None
    if not container:
        return {}
    rows_parent = container.select_one(".product-page-info-table-rows") or container
    rows = rows_parent.select(".product-page-info-table-row") or []
    if not rows:
        return {}

    raw_map: Dict[str, str] = {}
    for r in rows:
        lab_el = r.select_one(".product-page-info-table__label")
        val_el = r.select_one(".product-page-info-table__content")
        if not lab_el or not val_el:
            continue
        label = normalize_text(lab_el.get_text())
        value = normalize_text(val_el.get_text())
        if label:
            raw_map[label] = value

    out: Dict[str, Union[str, float, int, Dict]] = {"info_table": raw_map}

    # Brand
    brand = raw_map.get("Brand") or raw_map.get("Brand Name") or None
    if brand:
        out["brand"] = brand

    # RRP
    rrp_val, rrp_cur, rrp_raw = parse_price(raw_map.get("RRP", ""))
    if rrp_raw and (rrp_val is not None or rrp_cur is not None):
        out["rrp_raw"] = rrp_raw
    if rrp_val is not None:
        out["rrp"] = rrp_val
    if rrp_cur:
        out["rrp_currency"] = rrp_cur

    # Price Per Unit
    ppu_val, ppu_cur, ppu_raw = parse_price(
        raw_map.get("Price Per Unit", "") or raw_map.get("Unit Price", "")
    )
    if ppu_raw and (ppu_val is not None or ppu_cur is not None):
        out["price_per_unit_raw"] = ppu_raw
    if ppu_val is not None:
        out["price_per_unit"] = ppu_val
    if ppu_cur:
        out["price_per_unit_currency"] = ppu_cur

    # Case Size
    cs_text = raw_map.get("Case Size", "") or raw_map.get("Pack Size", "")
    cs_count, cs_item_qty, cs_item_unit, cs_raw = parse_case_size(cs_text)
    if cs_raw:
        out["case_size_raw"] = cs_raw
    if cs_count is not None:
        out["case_size_count"] = cs_count
    if cs_item_qty is not None:
        out["case_size_item_qty"] = cs_item_qty
    if cs_item_unit:
        out["case_size_item_unit"] = cs_item_unit

    return out
