'''
Created on 12-Jul-2021

@author: bthakur
'''
import random
import inspect
import traceback   #        {inspect.stack()[0][3]}

import re
from sympy import (Eq, symbols, sqrt, latex,
                   Rational, solve, log, nsimplify, E, exp,  
                   sin, cos, I, series, pi)

from ....util import LatexEquation, MathUtil


from xv.util import UtilClass, list_to_str

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

    def get_random_model(self, *args, **kwargs):
        methods = [
                    self.arithmetic_puzzle_1,
                   ]
        
        method = random.choice(methods)
        random_model = method()
    
        var_names = random_model['var_names']
        var_vals = random_model['var_vals']
        
        
        solutions = random_model['solutions']
        
        var_names_str = [f"${latex(k)}: {latex(v)}$" for k,v in var_names.items()]
        var_names_str = "\n".join(var_names_str)
        
        solutions_str = [f"${latex(k)}: {latex(v)}$" for k,v in solutions.items()]
        solutions_str = "\n".join(solutions_str)
        
        prob_s = f"""
        {random_model['statement_header']}
        {random_model['statement']}
        {random_model['statement_footer']}
        """
                
        soln_s = f"""
        <b>Let:</b>
        {var_names_str}
        
        <b>Equations:</b>
        {random_model['eqs_str']}
        
        <b>Solving the equations:</b>
        {solutions_str}
        """
        
        answer_s = f"""
        {solutions_str}
        """
        
        result = {
            'prob_s': prob_s.strip(),
            'soln_s': soln_s.strip(),
            'answer_s': answer_s.strip(),
            }
        
        return result
    
        pass


    def model_min_common_volume(self):
        V1, V2, V3, n1, n2, n3, CV = symbols('V_1, V_2, V_3, n_1, n_2, n_3, V_c')
        
        var_names = {V1: 'volume of first container',
                     V2: 'volume of second container',
                     V3: 'volume of third container',
                     n1: 'times first container is used',
                     n2: 'times second container is used',
                     n3: 'times third container is used',
                     CV: 'minimum common volume',
                     }
        
        V1_val = random.randint(3, 20)
        V2_val = random.randint(2, 20)
        V3_val = random.randint(2, 20)
        CV_val = MathUtil.lcm(V1_val, V2_val, V3_val)
        
        n1_val = CV_val // V1_val
        n2_val = CV_val // V2_val
        n3_val = CV_val // V3_val

        vals_dict = {
                     V1: V1_val,
                     V2: V2_val,
                     V3: V3_val,
                     CV: CV_val,
                     n1: n1_val,
                     n2: n2_val,
                     n3: n3_val,
                    }
        
        var_vals = self._get_filtered_dict(vals_dict, [V1, V2, V3])
        solutions = self._get_filtered_dict(vals_dict, [CV, n1, n2, n3])
        
        statement_header = ''
        statement = f"""
        Three measuring containers are have capacity of {V1_val}, {V2_val} and {V3_val} liters. 
        """
        statement_footer = "What is the minimum volume that we can measure?"

        eq1 = Eq(V1_val * n1, CV )
        latex_eq1 = LatexEquation(f"{V1_val} * {latex(n1)}",
                                  latex(CV),
                                  eq1)
        
        eq2 = Eq(V2_val * n2, CV )
        latex_eq2 = LatexEquation(f"{V2_val} * {latex(n2)}",
                                  latex(CV),
                                  eq2)

        eq3 = Eq(V3_val * n3, CV )
        latex_eq3 = LatexEquation(f"{V3_val} * {latex(n3)}",
                                  latex(CV),
                                  eq3)

        latex_eqs = [latex_eq1, latex_eq2, latex_eq3]
        eqs_str = self._get_eqs_str(latex_eqs)
        

        random_model = {
            'statement_header': statement_header,
            'statement': statement,
            'statement_footer': statement_footer,
            'var_names': var_names,
            'latex_eqs': latex_eqs,
            'eqs_str': eqs_str,
            'var_names': var_names,
            'var_vals': var_vals,
            'solutions': solutions,
            }
        
        return random_model
        pass

    
    def arithmetic_puzzle_1(self):
        d1, d2, d3, n1, n2, n3, cd = symbols('d_1, d_2, d_3, n_1, n_2, n_3, d_c')
        
        var_names = {d1: 'distance covered by first friend each time',
                     d2: 'distance covered by second friend each time',
                     d3: 'distance covered by third friend each time',
                     n1: 'times first friend runs',
                     n2: 'times second friend runs',
                     n3: 'times third friend runs',
                     cd: 'minimum common distance',
                     }
        
        d1_val = random.randint(2, 20)
        d2_val = random.randint(2, 20)
        d3_val = random.randint(2, 20)
        cd_val = MathUtil.lcm(d1_val, d2_val, d3_val)
        
        n1_val = cd_val // d1_val
        n2_val = cd_val // d2_val
        n3_val = cd_val // d3_val

        vals_dict = {
                     d1: d1_val,
                     d2: d2_val,
                     d3: d3_val,
                     cd: cd_val,
                     n1: n1_val,
                     n2: n2_val,
                     n3: n3_val,
                    }
        
        var_vals = self._get_filtered_dict(vals_dict, [d1, d2, d3])
        solutions = self._get_filtered_dict(vals_dict, [cd, n1, n2, n3])
        
        statement_header = ''
        statement = f"""
        "On the coast there are three lighthouses.
        The first light shines for {d1_val} seconds, then is off for {d1_val} seconds.
        The second light shines for {d2_val} seconds, then is off for {d2_val} seconds.
        The third light shines for {d3_val} seconds, then is off for {d3_val} seconds.
        When will all three lights come on together?
        """
        statement_footer = ""

        eq1 = Eq(d1_val * n1, cd )
        latex_eq1 = LatexEquation(f"{d1_val} * {latex(n1)}",
                                  latex(cd),
                                  eq1)
        
        eq2 = Eq(d2_val * n2, cd )
        latex_eq2 = LatexEquation(f"{d2_val} * {latex(n2)}",
                                  latex(cd),
                                  eq2)

        eq3 = Eq(d3_val * n3, cd )
        latex_eq3 = LatexEquation(f"{d3_val} * {latex(n3)}",
                                  latex(cd),
                                  eq3)

        latex_eqs = [latex_eq1, latex_eq2, latex_eq3]
        eqs_str = self._get_eqs_str(latex_eqs)
        

        random_model = {
            'statement_header': statement_header,
            'statement': statement,
            'statement_footer': statement_footer,
            'var_names': var_names,
            'latex_eqs': latex_eqs,
            'eqs_str': eqs_str,
            'var_names': var_names,
            'var_vals': var_vals,
            'solutions': solutions,
            }
        
        return random_model
        pass

    
    def _get_eqs_str(self, latex_eqs):
        eqs_str = [f'$\\displaystyle {latex_eq}$' for latex_eq in latex_eqs]
        eqs_str = "\n\n".join(eqs_str)
        return eqs_str
        pass
    
    def _get_filtered_dict(self, dct, keys):
        return {k:dct[k] for k in keys}
        pass
    
    
    pass
#class ModellingAssortedHelper:
