'''
Created on 20-Jan-2022

@author: bthakur
'''

import inspect
import traceback
import random
import sympy
from sympy import (symbols, Symbol, Pow, latex, Rational, 
                   nsimplify, 
                   UnevaluatedExpr as ueval)

from xv.km.util import latex_fraction
from xv.util import toIntOrFloat, list_to_str
      

# _long_arithmetic_process_helper
# LongArithmeticProcessHelper

from xv.util import UtilClass

class LongArithmeticProcessHelper(UtilClass):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        pass



    def get_problem_add_integers_old(self, **kwargs):
        digit_sep = " " * 4 
        nums_size = random.randint(2, 4)
        
        nums = []
        nums_digits = []
        for i in range(nums_size):
            num = random.randint(1, 6 ** random.randint(1, 10))
            num_digits = [x for x in list(str(num))]
            nums.append(num)
            nums_digits.append(num_digits)
            pass
        
        nums_sum = sum(nums)
        nums_sum_digits = [x for x in list(str(nums_sum))]
        
        nums_str = list_to_str(nums, last_sep = ' and ')
        
        prob_s = f"""
        Find sum of {nums_str}.
        """
        
        soln_stmts = []
        
        nums_digits_str = [list_to_str(num_digits, sep = digit_sep) for num_digits in nums_digits]
        nums_digits_str = "<br/>".join(nums_digits_str)
        nums_digits_str_in_h3 = f"<h3><pre>{nums_digits_str}</pre></h3>"
        
        
        soln_stmt = f"""
        Write each number in a separate line:
        {nums_digits_str_in_h3}
        """
        soln_stmts.append(soln_stmt.strip())


        nums_digits = self.make_lists_equal_length(*nums_digits)
        nums_digits_str = [list_to_str(num_digits, sep = digit_sep) for num_digits in nums_digits]
        nums_digits_str = "<br/>".join(nums_digits_str)
        nums_digits_str_in_h3 = f"<h3><pre>{nums_digits_str}</pre></h3>"
        
        soln_stmt = f"""
        Make the count of digits in numbers same by adding zeroes to the left where needed.
        {nums_digits_str_in_h3}
        
        Start adding from the right side.
        """
        soln_stmts.append(soln_stmt.strip())


        digits_count = len(nums_digits[0])
        
        for idx in range(digits_count):
            
            step_num_digits = nums_digits.copy()
            step_num_digits.append(["-" for x in range(digits_count)])
            
            cum_sum_digits = []
            for mod_idx in range(idx + 1):
                pos_idx = - (mod_idx + 1)
                cum_sum = [int(num_digits[pos_idx]) for num_digits in nums_digits[:nums_size]]
                cum_sum_digits.insert(0, sum(cum_sum))
            
            step_num_digits.append(cum_sum_digits)
            step_num_digits = self.make_lists_equal_length(*step_num_digits, sep = " ")
        
            nums_digits_str = [list_to_str(num_digits, sep = digit_sep) 
                               for num_digits in step_num_digits]
            nums_digits_str = "<br/>".join(nums_digits_str)
            nums_digits_str_in_h3 = f"<h3><pre>{nums_digits_str}</pre></h3>"
            
            soln_stmt = f"""
            Add {pos_idx} place digits:
            {nums_digits_str_in_h3}
            
            """
            soln_stmts.append(soln_stmt.strip())
            pass
        
        
        soln_s = "\n\n".join(soln_stmts)

        answer_s = f"""
        {nums_sum}
        """
        result = {
            'prob_s': prob_s.strip(),
            'soln_s': soln_s.strip(),
            'answer_s': answer_s.strip(),
            }
        
        return result
        pass

    def get_problem_add_integers(self, **kwargs):
        digit_sep = " " * 4 
        nums_size = random.randint(2, 4)
        
        nums = []
        nums_digits = []
        for i in range(nums_size):
            num = random.randint(1, 6 ** random.randint(1, 10))
            num_digits = [x for x in list(str(num))]
            nums.append(num)
            nums_digits.append(num_digits)
            pass
        
        nums_sum = sum(nums)
        nums_sum_digits = [x for x in list(str(nums_sum))]
        
        nums_str = list_to_str(nums, last_sep = ' and ')
        
        prob_s = f"""
        Find sum of {nums_str}.
        """
        
        soln_stmts = []
        
        nums_digits_str = [list_to_str(num_digits, sep = digit_sep) for num_digits in nums_digits]
        nums_digits_str = "<br/>".join(nums_digits_str)
        nums_digits_str_in_h3 = f"<h3><pre>{nums_digits_str}</pre></h3>"
        
        
        soln_stmt = f"""
        Write each number in a separate line:
        {nums_digits_str_in_h3}
        """
        soln_stmts.append(soln_stmt.strip())


        nums_digits = self.make_lists_equal_length(*nums_digits)
        nums_digits_str = [list_to_str(num_digits, sep = digit_sep) for num_digits in nums_digits]
        nums_digits_str = "<br/>".join(nums_digits_str)
        nums_digits_str_in_h3 = f"<h3><pre>{nums_digits_str}</pre></h3>"
        
        soln_stmt = f"""
        Make the count of digits in numbers same by adding zeroes to the left where needed.
        {nums_digits_str_in_h3}
        
        Start adding from the right side.
        """
        soln_stmts.append(soln_stmt.strip())


        digits_count = len(nums_digits[0])
        
        for idx in range(digits_count):
            
            step_num_digits = nums_digits.copy()
            step_num_digits.append(["-" for x in range(digits_count)])
            
            cum_sum_digits = []
            for mod_idx in range(idx + 1):
                pos_idx = - (mod_idx + 1)
                cum_sum = [int(num_digits[pos_idx]) for num_digits in nums_digits[:nums_size]]
                cum_sum_digits.insert(0, sum(cum_sum))
            
            step_num_digits.append(cum_sum_digits)
            step_num_digits = self.make_lists_equal_length(*step_num_digits, sep = " ")
        
            nums_digits_str = [list_to_str(num_digits, sep = digit_sep) 
                               for num_digits in step_num_digits]
            nums_digits_str = "<br/>".join(nums_digits_str)
            nums_digits_str_in_h3 = f"<h3><pre>{nums_digits_str}</pre></h3>"
            
            soln_stmt = f"""
            Add {pos_idx} place digits:
            {nums_digits_str_in_h3}
            
            """
            soln_stmts.append(soln_stmt.strip())
            pass
        
        
        soln_s = "\n\n".join(soln_stmts)

        answer_s = f"""
        {nums_sum}
        """
        result = {
            'prob_s': prob_s.strip(),
            'soln_s': soln_s.strip(),
            'answer_s': answer_s.strip(),
            }
        
        return result
        pass

    def make_lists_equal_length(self, *lists, sep = '0', color = 'red'):
        
        #sep = f"""<span style="color: {color};">{sep}</span>"""
        
        max_digit_count = max([len(x) for x in lists])
        
        mod_lists = []
        for temp_list in lists:
            if len(temp_list) == max_digit_count:
                mod_lists.append(temp_list)
                continue
            
            addl_list = []
            for _ in range(max_digit_count - len(temp_list)):
                addl_list.append(sep)
            
            addl_list.extend(temp_list)
            mod_lists.append(addl_list)
            pass
        return mod_lists
        pass

    pass
#class LongArithmeticProcessHelper:
