import random


class Puzzle:
    pass


class BlankPuzzle(Puzzle):
    """填空题谜题生成器
    
    Args:
        text: 原始字符串(需要 "/" 分割句子, 末尾应有 "/")
        min_denominator: 最小概率倒数(如占所有可生成填空数的 1/7 中的 7, 若期望值小于 1, 则取 1)
    """

    def __init__(self, text: str, min_denominator: int):
        self.text = text
        self.min_denominator = min_denominator
        self.wording = "填空题 - 尚未刷新谜题"
        self.answer = ["填空题 - 尚未刷新谜题"]

    def refresh(self):  # 刷新谜题
        placeholder = "___SLASH___"
        tmp_text = self.text.replace("/", placeholder)
        words = tmp_text.split(placeholder)
        if not words:
            return
        words = [word for word in words if word]
        num_blanks = min(max(1, len(words) // self.min_denominator), len(words))
        indices_to_blank = random.sample(range(len(words)), num_blanks)
        indices_to_blank.sort()
        blanked_words = list(words)
        answer = list()
        for index in indices_to_blank:
            blanked_words[index] = "__" * len(words[index])
            answer.append(words[index])
        self.answer = answer
        self.wording = "".join(blanked_words)

    def __str__(self):
        return f"{self.wording}\n{str(self.answer)}"


class SelectionPuzzle(Puzzle):
    """选择题谜题生成器
    
    Args:
        mapping: 正确选项映射 {问题: 答案}
        jammer: 干扰项列表
        max_riddles_num: 最大生成谜题数 (默认2个)
        prefix: 问题前缀
    """

    def __init__(
        self,
        mapping: dict,
        jammer: list,
        max_riddles_num: int = 2,
        prefix: str = ""
    ):
        self.prefix = prefix
        self.mapping = mapping
        self.jammer = list(set(jammer + list(mapping.values())))
        while len(self.jammer) < 4:
            self.jammer.append(" ")
        self.max_riddles_num = max(1, min(max_riddles_num, 5))
        self.wording = "选择题 - 尚未刷新谜题"
        self.answer = ["选择题 - 尚未刷新谜题"]
        self.options = []

    def refresh(self):
        """刷新谜题，根据题目数量生成适当数量的谜题"""
        if not self.mapping:
            self.wording = "无可用题目"
            self.answer = ["无答案"]
            self.options = []
            return
        
        num_questions = min(self.max_riddles_num, len(self.mapping))
        questions = random.sample(list(self.mapping.items()), num_questions)
        puzzles = []
        answers = []
        all_options = []
        
        for question, correct_answer in questions:
            options = [correct_answer]
            available_jammers = [
                j for j in self.jammer if j != correct_answer
            ]
            if len(available_jammers) >= 3:
                selected_jammers = random.sample(available_jammers, 3)
            else:
                selected_jammers = random.choices(available_jammers, k=3)
            options.extend(selected_jammers)
            random.shuffle(options)
            puzzles.append(question)
            answers.append(correct_answer)
            all_options.append(options)
        
        question_texts = []
        for i, puzzle in enumerate(puzzles):
            question_texts.append(f"{self.prefix}:\n  {i+1}. {puzzle}")
        
        self.wording = question_texts
        self.answer = answers
        self.options = all_options

    def __str__(self):
        return f"{self.wording}\n正确答案: {', '.join(self.answer)}"

if __name__ == "__main__":
    puz = SelectionPuzzle(
        {"1+1": "2", "1+2": "3", "1+3": "4"},
        ["2", "5", "0"],
        3,
        '求值: '
    )
    puz.refresh()
    print(puz.wording)
    print(puz.answer)
    print(puz.options)