'''
Created on 24-Jul-2025

@author: bthakur
'''

import random

from ._base_subtract_q_gen import BaseSubtractQGen

# SubtractIntQGen
# _subtract_int_q_gen

class SubtractIntQGen(BaseSubtractQGen):
    """
    Subtraction question generator for integers.
    Inherits all logic from BaseSubtractQGen, only overrides random pair generation and formatting.
    """
    def __init__(self, min_value=10, max_value=999, **kwargs):
        super().__init__(min_value, max_value, **kwargs)


    def _init_swp_templates(self):
        from ._subtract_int_word_prob_templates import SubtractIntWordProbTemplates
        swp_templates = SubtractIntWordProbTemplates(self)
        return swp_templates
        pass


    def estimation(self):

        a, b = self._rand_pair()

        # 1. Decide best place value for estimation
        max_abs = max(abs(int(a)), abs(int(b)))
        if max_abs < 100:
            place = 10
        elif max_abs < 1000:
            place = 100
        elif max_abs < 10000:
            place = 1000
        else:
            place = 10 ** (len(str(int(max_abs))) - 1)

        def round_to(x, base):
            return int(base * round(float(x) / base))

        est_a = round_to(a, place)
        est_b = round_to(b, place)
        estimate = est_a - est_b

        # Prepare formatted block
        a_str = str(est_a)
        b_str = str(est_b)
        result_str = str(estimate)
        width = max(len(a_str), len(b_str), len(result_str), 5)
        solid_line = "─" * width
        subtraction_block = (
            f"<pre style='font-size:1.2em; margin-bottom:0;'>"
            f"{a_str.rjust(width)}\n"
            f"{'− ' + b_str.rjust(width-2)}\n"
            f"{solid_line}\n"
            f"{result_str.rjust(width)}\n"
            f"</pre>"
        )

        # Human-friendly explanation of the rounding
        if place == 10:
            round_str = "nearest ten"
        elif place == 100:
            round_str = "nearest hundred"
        elif place == 1000:
            round_str = "nearest thousand"
        else:
            round_str = f"nearest {place}"

        solution = (
            f"Step 1: Round each number to the <b>{round_str}</b>.<br>"
            f"${self.sp_latex(a)}$ rounds to <b>${self.sp_latex(est_a)}$</b>.<br>"
            f"${self.sp_latex(b)}$ rounds to <b>${self.sp_latex(est_b)}$</b>.<br>"
            f"Step 2: Subtract the rounded numbers:<br>{subtraction_block}"
            f"Step 3: The estimated answer is <b>${self.sp_latex(estimate)}$</b>.<br>"
        )
        question = (
            f"Estimate the result of <b>${self.sp_latex(a)}$</b> − <b>${self.sp_latex(b)}$</b> "
            f"(round to {round_str})."
        )
        return {
            "type": "estimation",
            "question": question,
            "answer": f"${self.sp_latex(estimate)}$",
            "solution": solution
        }

    def _rand_pair(self):
        # Generate two integers (a >= b)
        a = random.randint(self.min_value, self.max_value)
        b = random.randint(self.min_value, a)
        return a, b

    def _align_and_subtract_block(self, a, b, **kwargs):
        op = kwargs.get("op", "-")
        # Map op to proper symbol for display
        op_symbol = {
            '-': '−',
            '+': '+',
            '*': '×',
            '/': '÷'
        }.get(op, op)  # Default to op itself if not in the dict

        # Compute result according to op
        if op == '-':
            result = a - b
        elif op == '+':
            result = a + b
        elif op == '*':
            result = a * b
        elif op == '/':
            # Division by zero handled by Python (raises)
            result = a / b
        else:
            # Fallback to subtraction for unknown op
            result = a - b

        a_str = str(a)
        b_str = str(b)
        result_str = str(result)
        width = max(len(a_str), len(b_str), len(result_str)) + 4
        solid_line = "─" * width
        block = (
            f"<pre style='font-size:1.2em; margin-bottom:0;'>"
            f"{a_str.rjust(width)}\n"
            f"{op_symbol + ' ' + b_str.rjust(width-2)}\n"
            f"{solid_line}\n"
            f"{result_str.rjust(width)}\n"
            f"</pre>"
        )
        return a_str, b_str, result_str, block

    def _result(self, a, b):
        # No rounding needed for integer subtraction
        return a - b
