import os

import pandas as pd
import datetime
import numpy as np

from tqdm import tqdm

from market_trade.core.indicators_v2 import *
from market_trade.core.signals_v2 import *
from market_trade.core.dealManager import *
from market_trade.core.trandeVoter import *
from market_trade.core.riskManager import *
import pickle


class decsionManager:
    '''
sigAgrReq = {
    'sig_BB':{
        'className':sig_BB,
        'params':{'source':'close','target':'close'},
        'indicators':{
            'ind_BB':{
                'className':ind_BB,
                'params':{'MeanType':'SMA','window':30,'valueType':'close','kDev':2.5}
            }            
        }
    },
    'sig_BB_2':{
        'className':sig_BB,
        'params':{'source':'close','target':'close'},
        'indicators':{
            'ind_BB':{
                'className':ind_BB,
                'params':{'MeanType':'SMA','window':30,'valueType':'close','kDev':2}
            }            
        }
    }
}

sigAgrData = {
    'sig_BB':{
        'signalData': df_candle[990:1000],
        'indicatorData' :{'ind_BB': df_candle[:1000]}
    },
    'sig_BB_2':{
        'signalData': df_candle[990:1000],
        'indicatorData' :{'ind_BB': df_candle[:1000]}
    }    
}


sigAgrRetroTemplate = {
    'sig_BB':{
        'signalData': None,
        'indicatorData' :{'ind_BB': None}
    },
    'sig_BB_2':{
        'signalData': None,
        'indicatorData' :{'ind_BB': None}
    }     
}    
    
    
    
    
    
    
    '''
    
    
    
    
    def __init__(self,name, sigDict: dict):
        self.RM = riskManager()
        self.DM = DealManager()
        self.TV = trandeVoter(name)
        self.SA = signalsAgrigator(sigDict)
        self.sigDict = sigDict
        
        
    def getOnlineAns(self, signalsAns: dict, price: float) -> dict:
        probabilityDecsion = self.TV.getDecisionBySignals(self.getSignalsAns(signalsAns))
        RMD = self.RM.getDecision(probabilityDecision=probabilityDecsion, price=price, deals = self.DM.deals)
        return RMD
        
    def getSignalsAns(self, signalsDataDict: dict) -> dict:
        return self.SA.getAns(signalsDataDict)
    
    def getRightAns(self,value_1, value_2):
        
        ans=''
        
        if value_1 > value_2:
            ans = 'down'
        elif value_1 < value_2:
            ans = 'up'
        else:
            ans = 'none'
        
        return ans
        
    def getRetroTrendAns(self, retroTemplateDict: dict, data: pd.DataFrame(), window: int) -> list:
        
        reqSig={} 
        ans = {
            'signalsAns':[],
            'rightAns':[]
            
        }
        target = ''
        
        
        for k in tqdm(range(data.shape[0]-window-1)):
            for i in retroTemplateDict.keys():
                reqSig[i] = {'signalData': data[k:k+window], 'indicatorData':{}}
                target = self.SA.signals[i].params['target']
                for j in retroTemplateDict[i]['indicatorData'].keys():
                    reqSig[i]['indicatorData'][j] = data[k:k+window]
                    
            sigAns = self.getSignalsAns(reqSig)
            rightAns = self.getRightAns(data[target][k], data[target][k+1])

            ans['signalsAns'].append(sigAns)
            ans['rightAns'].append(rightAns)

        return ans
 

    def generateMatrixProbabilityFromDict(self, dictSignals: dict) -> dict:
        self.TV.createMatrixAmounts(dictSignals['signalsAns'][0].keys())
        for i in range(len(dictSignals['signalsAns'])):
            self.TV.setDecisionBySignals(signalDecisions = dictSignals['signalsAns'][i],
                                        trande = dictSignals['rightAns'][i])
        self.TV.generateMatrixProbability()
        
    def createDump(self,postfix='') -> str:
        dataDict = {
            'RM':self.RM,
            'DM':self.DM,
            'TV':self.TV,
            'SA':self.SA,
            'sigDict':self.sigDict
        }
        fileName='data_'+postfix+'.pickle'
        with open(fileName, 'wb') as f:
            pickle.dump(dataDict, f)
            
        return os.path.abspath(fileName)
    
    def loadDump(self,path: str) -> None:
        
        with open(path, 'rb') as f:
            dataDict = pickle.load(f)
        
        self.RM = dataDict['RM']
        self.DM = dataDict['DM']
        self.TV = dataDict['TV']
        self.SA = dataDict['SA']
        self.sigDict = dataDict['sigDict']