import os
import pickle
import csv 
from .dataCleaning import *
from .taxonomyAPI import *
from .higherLevelAPI import *
from .commonNameAPI import *
import itertools
import pytest 

class EcoNameTranslator:
    def __init__(self):
        self.index = {}
        self.result = {}
        self.failed = {}
    
    def translate(self,uncheckedNames):
        for item in uncheckedNames:
            self.index[item] = [cleanSingleSpeciesString(item),'']
        self.tagInputWithTaxaLevel()
        self.mapKnownTaxaLevelToSpecies()
        self.tryCommonNameOnErrorCases()
        return self.index
    
    def tagInputWithTaxaLevel(self):
        names = list(map(lambda x: self.index[x][0], self.index.keys()))
        taxonomyAPIResuls, excepted = taxonomyAPI(names)
        self.writeApiResultsToIndex(taxonomyAPIResuls)
    
    def mapKnownTaxaLevelToSpecies(self):
        names = list(map(lambda x: self.index[x][0], self.index.keys()))
        taxaTuples = list(map(lambda x: self.index[x][1], self.index.keys()))
        originalNamesWthTaxa = list(zip(names,taxaTuples))
        speciesNamesOnly = list(map(higherLevelAPI,originalNamesWthTaxa))
        self.writeApiResultsToIndex(speciesNamesOnly)
    
    def tryCommonNameOnErrorCases(self):
        names = list(map(lambda x: self.index[x][0], self.index.keys()))
        currentSpeciesResults = list(map(lambda x: self.index[x][1], self.index.keys()))
        bestEffortOfSpecies = list(zip(names,currentSpeciesResults))
        speciesNamesOnly = list(map(commonNameAPI,bestEffortOfSpecies))
        self.writeApiResultsToIndex(speciesNamesOnly)
    
    def writeApiResultsToIndex(self,taxonomyAPIResuls):
        taxaAPIDict = {}
        for cleanedName,success,result in taxonomyAPIResuls:
            taxaAPIDict[cleanedName] = result
        
        for name in self.index:
            try: self.index[name][1] = taxaAPIDict[self.index[name][0]]
            except: pass
    
    def toPickleFile(self,path):
        with open(path,'wb') as fh:
            pickle.dump(index,fh) 
    
    def toCSV(self,path,name="translatedNames.csv"):
        headers = [["Input Name","Name After Cleaning","Result"]]
        csvData = map(lambda indivEcoName: \
                        list(map(lambda result: [indivEcoName,self.index[indivEcoName][0],result], \
                        self.index[indivEcoName][1])) \
                      ,self.index.keys())
                      
        csvData = list(itertools.chain(headers,*csvData))
        
        with open(path+"/"+name, "w", newline="") as f:
            writer = csv.writer(f)
            writer.writerows(csvData)