'''
Created on 01-Apr-2021
@author: bthakur
'''
import os 
#import decimal
from functools import reduce
from xv.km.ui import SvgHelper 

import numpy as np
import random
import inspect
import traceback
from sympy import (simplify, sympify, log, symbols, Eq, Matrix, latex, 
                   solve, Rational, diag)

        
from xv.util import toIntOrFloat


from ..helper import BaseHelper
from xv.km.managers import BaseManager
from xv.km.kelements import KProblemTemplate
        
class SeriesPatternManager(BaseManager):
    '''
    SeriesPatternManager
    Example:
        ke = SeriesPatternManager()
        ke.getRandomProblem()
        ke.getRandomProblem(problem_type = 0)
        ke.getRandomProblem(problem_type = 0, arr = [324, 361, 400, 441])
        ke.getRandomProblem(problem_type = 1)
        ...
        
        ke.printProblem()
        ke.printAnswer()
        ke.printSolution()
        
        ke.printProblemTypes()
        
    '''    
    
    def __new__(cls, *args, **kwargs):
        instance = super(SeriesPatternManager, cls).__new__(cls, *args, **kwargs)
        for base_class in SeriesPatternManager.__bases__:
            base_class.__init__(instance, *args, **kwargs)
        return instance
    
    def __init__(self, *args, **kwargs):
        self.base_helper = BaseHelper(**kwargs)
        pass
    


    def _init_problem_types(self, *args, **kwargs):
        self._append_problem_types([
            '_problem_find_next_term',
            '_problem_find_next_term_advanced',
            ])
        pass



    def _problem_find_next_term(self, *args, **kwargs):
        implies = symbols(u'\U000021D2')

        sp_helper = self.base_helper.get_arithmetic_helper().get_series_pattern_helper()
        
        
        arr = kwargs.get('arr', None)
        
        if arr is None:
            arr = sp_helper.get_random_array()
        
        sp_helper.set_series_data(arr)
        
                
        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')
        
        statement = f"""
        Find next term in series {arr}
        """
        problemTemplate.add_problem(statement, "text/html")

        next_term = sp_helper.get_next_term()
        
        soln_s = f"""
        {sp_helper.get_statement()}
        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        if next_term is None:
            sp1, sp2 = sp_helper.get_alternate_arrays()
            next_term1 = sp1.get_next_term()
            next_term2 = sp2.get_next_term()
            next_term = next_term1

            soln_s = f"""
            Splitting the series with alternate terms into two series:
            {sp1.arr} \t and \t {sp2.arr} 
            """
            problemTemplate.add_solution(soln_s.strip(), 'text/html')

            soln_s = f"""
            {sp1.get_statement()}
            ${implies}$ Next Term1 $= {next_term1}$

            {sp2.get_statement()}
            ${implies}$ Next Term2 $= {next_term2}$
            
            Thus, 
            Next Terms $= {next_term1}, {next_term2}$
            """
            problemTemplate.add_solution(soln_s.strip(), 'text/html')
            pass

        soln_s = f"""
        ${implies}$ Next Term $= {next_term}$
        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        

        answer_s = f"""Next Term = {next_term}"""
        problemTemplate.add_answer(f"{answer_s}", 'text/html')
        
        return problemTemplate


    def _problem_find_next_term_advanced(self, *args, **kwargs):
        sp_helper = self.base_helper.get_arithmetic_helper().get_series_pattern_helper()
        
        result = sp_helper.get_problem_find_next_term_advanced(**kwargs)
                
        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')
        
        prob_s = f"""
        {result['prob_s']}
        """
        problemTemplate.add_problem(prob_s.strip(), "text/html")

        soln_s = f"""
        {result['soln_s']}
        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        

        answer_s = f"""
        {result['answer_s']}
        """
        problemTemplate.add_answer(answer_s.strip(), 'text/html')
        
        return problemTemplate

