import json
import unittest
from pathlib import Path

from webpage_extractor.core.tag_mapping import MapItemToHtmlTagsParser

base_dir = Path(__file__).resolve().parent


def parse_tuple_key(key_str):
    if key_str.startswith("(") and key_str.endswith(")"):
        try:
            # Convert "(1, 2)" → (1, 2) using ast.literal_eval (safer than eval)
            return eval(key_str)
        except Exception:
            return key_str
    return key_str


class TestTagMapping(unittest.TestCase):
    """测试模版正文结构树抽取."""

    def test_construct_main_tree(self):
        data = []
        raw_html_path = base_dir.joinpath("assets/tag_mapping/test_tag_mapping_web.jsonl")
        with open(raw_html_path, "r", encoding="utf-8") as f:
            for line in f:
                data.append(json.loads(line.strip()))  # 解析每行 JSON
        mock_dict = data[0]
        pre_data = mock_dict["pre_data"]
        # 实际使用原网页html字段作为typical_raw_html
        pre_data["typical_raw_html"] = pre_data["typical_raw_tag_html"]
        parser = MapItemToHtmlTagsParser({})
        pre_data = parser.parse(pre_data)
        content_list = pre_data.get("html_target_list", [])
        element_dict = pre_data.get("html_element_dict", [])
        self.assertEqual(content_list, mock_dict["expected_content_list"])
        verify_key = mock_dict["verify_key1"]
        verify_key = (verify_key[0], verify_key[1], verify_key[2], verify_key[4], verify_key[5])
        new_res = element_dict[8][verify_key][0]
        self.assertEqual("red", new_res)

        verify_key = mock_dict["verify_key2"]
        verify_key = (verify_key[0], verify_key[1], verify_key[2], verify_key[4], verify_key[5])
        new_res = element_dict[7][verify_key][0]
        self.assertEqual("red", new_res)

    def test_construct_main_tree_fail_by_similarity(self):
        """测试由于抽取正文和原网页相似度过高导致构建失败，模拟模型给出的结果中没有正文标签，根据推广算法会保留全网页."""
        data = []
        raw_html_path = base_dir.joinpath("assets/tag_mapping/test_tag_mapping_web.jsonl")
        with open(raw_html_path, "r", encoding="utf-8") as f:
            for line in f:
                data.append(json.loads(line.strip()))  # 解析每行 JSON
        mock_dict = data[0]
        pre_data = mock_dict["pre_data"]
        pre_data["typical_raw_html"] = pre_data["typical_raw_tag_html"]
        # 用bad模型结果替换
        pre_data["llm_response"] = pre_data["llm_response_bad"]
        parser = MapItemToHtmlTagsParser({})
        pre_data = parser.parse(pre_data)
        construct_success = pre_data.get("typical_main_html_success")
        self.assertEqual(False, construct_success)

    def test_parse_single(self):
        data = []
        raw_html_path = base_dir.joinpath("assets/tag_mapping/test_tag_mapping_web.jsonl")
        with open(raw_html_path, "r", encoding="utf-8") as f:
            for line in f:
                data.append(json.loads(line.strip()))  # 解析每行 JSON
        mock_dict = data[0]
        pre_data = mock_dict["pre_data"]
        pre_data["typical_raw_html"] = pre_data["typical_raw_tag_html"]
        pre_data["success_label_enable"] = True
        parser = MapItemToHtmlTagsParser({})
        pre_data = parser.parse_single(pre_data)
        content_list = pre_data["html_target_list"]
        self.assertEqual(content_list, mock_dict["expected_content_list"])
        self.assertEqual(len(pre_data["typical_main_html"]), 2502)

    def test_illegal_tag(self):
        # 构造测试html
        typical_raw_tag_html = base_dir.joinpath("assets/tag_mapping/test_illegal_tag.html").read_text(encoding="utf-8")
        # 简化网页
        # 模型结果格式改写
        llm_path = "assets/tag_mapping/test_illegal_tag.json"
        llm_response = json.loads(base_dir.joinpath(llm_path).read_text(encoding="utf-8"))
        pre_data = {"typical_raw_tag_html": typical_raw_tag_html, "typical_raw_html": typical_raw_tag_html, "llm_response": llm_response}
        # 映射
        parser = MapItemToHtmlTagsParser({})
        pre_data = parser.parse(pre_data)
        assert "This course looks" in pre_data["typical_main_html"]
