from typing import Union

import pandas
import parsel

from extreme_parser.amazon.product.model import Product
from extreme_parser.util.parse import parse_number


def parse(html: str, p: Product):
    sel = parsel.Selector(text=html)
    parse_weight(p, selector=sel)
    parse_brand(p, selector=sel)


def parse_weight(p: Product, html: str = None, selector: parsel.Selector = None):
    def s1() -> str:
        table = selector.xpath(
            "//table[@id='productDetails_detailBullets_sections1']|"
            "//table[@id='productDetails_techSpec_section_1']"
        ).get()
        if table is None:
            return ""
        table = pandas.read_html(table)
        if len(table) <= 0:
            return ""
        table = table[0].set_index(0)
        if "Item Weight" not in table[1]:
            return ""
        s = table[1]["Item Weight"]
        return s

    def s2() -> str:
        ul = selector.xpath("//div[@id='detailBullets_feature_div']/ul")
        s = ul.xpath("//span[contains(text(), 'Item Weight')]/following-sibling::span[1]/text()").get()
        s = s or ul.xpath(
            "substring-after(//span[contains(text(), 'Product Dimensions')]/following-sibling::span[1]/text(), '; ')"
        ).get("")
        return s

    weight_str = s1() or s2()
    if weight_str == "":
        p.weight = None
        return
    weight: Union[None, int, float] = parse_number(weight_str)
    if weight is None:
        p.weight = None
        return

    if weight_str.endswith("ounces") or weight_str.endswith("Ounces"):
        p.weight = weight * 0.0625
    elif weight_str.endswith("pounds") or weight_str.endswith("Pounds"):
        p.weight = float(weight)
    else:
        p.weight = None
        return


def parse_brand(p: Product, html: str = None, selector: parsel.Selector = None):
    def s1() -> str:
        table = selector.xpath("//div[@id='productOverview_feature_div']//table").get()
        if table is None:
            return ""
        table = pandas.read_html(table)
        if len(table) <= 0:
            return ""
        table = table[0].set_index(0)
        if "Brand" not in table[1]:
            return ""
        s = table[1]["Brand"]
        return s

    def s2() -> str:
        s = selector.xpath("//a[@id='bylineInfo']/text()").re_first("Brand: (.*)")
        s = s or selector.xpath("//a[@id='bylineInfo']/text()").re_first("Visit the (.*) Store")
        return s

    brand = s1() or s2()
    if brand == "":
        p.brand = None
        return

    p.brand = brand
