import logging

import requests
from bs4 import BeautifulSoup

logger = logging.getLogger(__name__)

CELLARTRACKER_URL = "https://www.cellartracker.com/wine.asp?iWine={cellartracker_id}"


def get_title_from_soup(soup) -> str:
    title = ""
    try:
        title = soup.find("h1").get_text(strip=True)
    except AttributeError:
        pass
    return title


def get_description_from_soup(soup) -> str:
    desc = ""
    try:
        desc = soup.find("div", class_="wine-notes").get_text(strip=True)
    except AttributeError:
        pass
    return desc


def get_wine_type_from_soup(soup) -> str:
    wine_type = ""
    try:
        wine_type_text = soup.find("td", string=lambda t: t and "Type" in t)
        if wine_type_text:
            wine_type = (
                wine_type_text.find_next_sibling("td").get_text(strip=True).lower()
            )
    except AttributeError:
        pass
    return wine_type


def get_rating_from_soup(soup) -> float:
    rating = None
    try:
        rating_text = soup.find("td", string=lambda t: t and "Score" in t)
        if rating_text:
            rating = float(rating_text.find_next_sibling("td").get_text(strip=True))
    except (AttributeError, ValueError):
        pass
    return rating


def get_grapes_from_soup(soup) -> list[str]:
    grapes = []
    try:
        grape_text = soup.find("td", string=lambda t: t and "Varietal" in t)
        if grape_text:
            grape_str = grape_text.find_next_sibling("td").get_text(strip=True)
            grapes = [g.strip() for g in grape_str.split("/") if g.strip()]
    except AttributeError:
        pass
    return grapes


def get_region_from_soup(soup) -> str:
    region = ""
    try:
        region_text = soup.find("td", string=lambda t: t and "Region" in t)
        if region_text:
            region = region_text.find_next_sibling("td").get_text(strip=True)
    except AttributeError:
        pass
    return region


def get_producer_from_soup(soup) -> str:
    producer = ""
    try:
        producer_text = soup.find("td", string=lambda t: t and "Producer" in t)
        if producer_text:
            producer = producer_text.find_next_sibling("td").get_text(strip=True)
    except AttributeError:
        pass
    return producer


def get_vintage_from_soup(soup) -> str:
    vintage = ""
    try:
        vintage_text = soup.find("td", string=lambda t: t and "Vintage" in t)
        if vintage_text:
            vintage = vintage_text.find_next_sibling("td").get_text(strip=True)
    except AttributeError:
        pass
    return vintage


def get_image_url_from_soup(soup) -> str:
    image_url = ""
    try:
        image_url = soup.find("img", class_="wine-image")["src"]
    except (AttributeError, KeyError, TypeError):
        pass
    return image_url


def get_wine_from_cellartracker_id(cellartracker_id: str) -> dict:
    wine_url = CELLARTRACKER_URL.format(cellartracker_id=cellartracker_id)
    headers = {"User-Agent": "Vrobbler 0.11.12"}
    response = requests.get(wine_url, headers=headers)
    wine_dict = {"cellartracker_id": cellartracker_id}

    if response.status_code != 200:
        logger.warning(
            "Bad response from cellartracker.com", extra={"response": response}
        )
        return wine_dict

    soup = BeautifulSoup(response.text, "html.parser")
    wine_dict["title"] = get_title_from_soup(soup)
    wine_dict["description"] = get_description_from_soup(soup)
    wine_dict["wine_type"] = get_wine_type_from_soup(soup)
    wine_dict["cellartracker_rating"] = get_rating_from_soup(soup)
    wine_dict["grapes"] = get_grapes_from_soup(soup)
    wine_dict["region"] = get_region_from_soup(soup)
    wine_dict["producer__name"] = get_producer_from_soup(soup)
    wine_dict["vintage"] = get_vintage_from_soup(soup)
    wine_dict["image_url"] = get_image_url_from_soup(soup)

    return wine_dict
