"""
「ロト6生活」のウェブサイトから当選数字を取得するモジュール

    「ロト6 当せん数字予測アプリ」
    Copyright (c) 2025 toshifumi tsutsui
    Released under the MIT license
    https://wpandora8.net/the_mit_license.html
"""

import re

import requests
from bs4 import BeautifulSoup
from bs4.element import Tag


def fetch_data_from_web() -> list[dict[str, int | str]]:
    """ロト6の当選数字のリストを取得する。

    Returns:
        list[dict[str, int | str]] | None: ロト6の当選数字のリスト。
    """

    URL: str = "http://sougaku.com/loto6/data/list1/index_50.html"

    records: list[dict[str, int | str]] = []

    if (html := _get_response_text(URL)) is not None:
        soup: BeautifulSoup = BeautifulSoup(html, "html.parser")
        if (tbody := _get_tbody(soup)) is not None:
            for tr in tbody.select("tr"):
                record: dict[str, int | str] = {}
                for i, td in enumerate(tr.select("td")):
                    match i:
                        case 0:
                            record["times"] = int(re.sub(r"\D", "", td.get_text()))
                        case 1:
                            record["first_num"] = int(td.get_text(strip=True))
                        case 2:
                            record["second_num"] = int(td.get_text(strip=True))
                        case 3:
                            record["third_num"] = int(td.get_text(strip=True))
                        case 4:
                            record["fourth_num"] = int(td.get_text(strip=True))
                        case 5:
                            record["fifth_num"] = int(td.get_text(strip=True))
                        case 6:
                            record["sixth_num"] = int(td.get_text(strip=True))
                        case 7:
                            record["bonus_num"] = int(td.get_text(strip=True))
                        case 8:
                            record["ball_set"] = td.get_text(strip=True)
                            records.append(record)
                        case _:
                            continue

    return records


def _get_tbody(soup: BeautifulSoup) -> Tag | None:
    """指定された BeautifulSoup オブジェクトから tbody 要素を取得する。

    Args:
        soup (BeautifulSoup): 解析対象の BeautifulSoup オブジェクト。

    Returns:
        Tag | None: tbody要素。存在しない場合はNone。
    """

    try:
        h3: Tag | None = soup.select_one(
            "h3:-soup-contains('当選数字一覧（最新50回）')"
        )
        return h3.parent.next_sibling.next_sibling.select_one("tbody")  # type: ignore

    except Exception:
        return None


def _get_response_text(url: str) -> str | None:
    """指定された URL からのレスポンスのテキストを取得する。

    Args:
        url (str): レスポンスを取得する URL。

    Returns:
        str | None: レスポンスのテキスト。取得できなかった場合はNone。
    """

    try:
        response: requests.Response = requests.get(url, timeout=10.0)
        response.raise_for_status()  # Raise an error for bad responses
        return response.content.decode("utf-8", "ignore")

    except Exception:
        return None
