from typing import Self
import csv
import ast

from classes.concept import Concept
from classes.feature_vector import FeatureVector

class DecisionTree:

	def __init__(self, children: dict = {}, parent: Self = None, concept: Concept = Concept.UNKNOWN, depth: int = 0, cycles: int = 3) -> None:
		self.children: dict = children # (number, DecisionTree)
		self.parent: Self = parent
		self.concept: Concept = concept
		self.depth: int = depth
		self.cycles: int = cycles
	

	# TODO
	# IMPLEMENTATION IS NOT WORKING

	def classify(self, feature_vector: FeatureVector) -> Concept:
		if len(self.children) == 0:
			return self.concept
		
		feature_value = feature_vector.features_list[self.depth] # get feature value of vector based on current depth
		
		try:
			new_decision_tree: Self = self.children[feature_value] # get sub decition tree for feature
		except KeyError:
			return Concept.UNKNOWN
		
		return new_decision_tree.classify(feature_vector) # classify new desicion tree

	
	def learn(self, training_set: list[FeatureVector]) -> None:
		i = 0
		while not self._finished(i, len(training_set)):
			vector: FeatureVector = training_set[i % len(training_set)]
			concept = self.classify(vector)
			#print(f"{i}\t: actual: {vector.concept} \t classified as: {concept}")
			if concept == vector.concept:
				i += 1
			else:
				self._insert(vector)
				#i += 1


	def _insert(self, vector: FeatureVector) -> None:
		if self.concept == Concept.UNKNOWN:
			self.concept = vector.concept

		else:
			feature_value = vector.features_list[self.depth]

			try:
				sub_decision_tree: Self = self.children[feature_value] # get sub decition tree for feature
				sub_decision_tree._insert(vector)
			except KeyError:
				self.children.update({vector.features_list[self.depth]: DecisionTree(concept=vector.concept, parent=self, depth=self.depth+1, children={}, cycles=self.cycles)})
		
		
	def _finished(self, i: int, num_training_data: int):
		# TODO implement proper finished condition
		if i < num_training_data*self.cycles:
			return False
		return True