from fastapi import HTTPException
import os
import re
from ..utils.hashing import HashGenerator
from user_journey_service.crew import UserJourney 
from user_journey_service.processors.defaults_estimator import MicrolearningDefaultsEstimator
defaults_estimator = MicrolearningDefaultsEstimator()
from pathlib import Path

########### without async
# class DefaultEstimator:
#     def __init__(self,input_data):
#         self.crew_instance = UserJourney()
#         self.input_data = input_data
#         self.input_hash = HashGenerator.generate_input_hash(input_data)
#         self.default_folder = f"defaults/{self.input_hash}.md"
    


#     def run(self):
#         print("Inside user defaults estimator service")
#         inputs = self.input_data.dict()
#         try:
#             exists,result = self._fetch_existing_result(self.default_folder)
#             if exists:
#                 print("Inside if of main function")
#                 output = self._restructure_output(result)
#                 return {"status": "success", "message": "Fetched existing result.","defaults":output}
#             crew = self.crew_instance.defaults_crew(output_file=self.default_folder)
#             crew.kickoff(inputs=inputs)
#             exists,result = self._fetch_existing_result(self.default_folder)
#             output = self._restructure_output(result)
#             return {"status": "success", "message": "Estimated the defaults.","defaults":output}
#         except Exception as e:
#             return {"status": "failed", "message": e}


#     def _fetch_existing_result(self,file_path):
#         print("Inside fetch result function")
#         if os.path.exists(file_path):
#             print("Inside if condition")
#             with open(file_path, 'r') as file:
#                 result = file.read()
#                 print(f"The fetched result is : {result}")
#                 print(f"The type of result is : {type(result)}")
#             # print(f"The output is : {result}")
#             return True, result
#         return False, ""

#     def _restructure_output(self,result: str) -> dict:
#         try:
#             print("Inside restructure output function")
#             print(f"The type of result is : {type(result)}")
#             print(f"Result content: {repr(result)}")
#             matches = re.findall(r"##\s*([\w\s]+?)\s*-\s*(\d+)%",result)

#             print("match found")
#             # Convert to dictionary
#             return {skill.strip(): int(percent) for skill, percent in matches}
#         except Exception as e:
#             print(e)
#             return {}

########### with async
# import aiofiles

# class DefaultEstimator:
#     def __init__(self,input_data):
#         self.crew_instance = UserJourney()
#         self.input_data = input_data
#         self.input_hash = HashGenerator.generate_input_hash(input_data)
#         self.default_folder = f"defaults/{self.input_hash}.md"
    


#     async def run(self):
#         print("Inside user defaults estimator service")
#         inputs = self.input_data.dict()
#         try:
#             exists,result = await self._fetch_existing_result(self.default_folder)
#             if exists:
#                 print("Inside if of main function")
#                 output = self._restructure_output(result)
#                 return {"status": "success", "message": "Fetched existing result.","defaults":output}
#             crew = self.crew_instance.defaults_crew(output_file=self.default_folder)
#             crew.kickoff(inputs=inputs)
#             exists,result = await self._fetch_existing_result(self.default_folder)
#             output = self._restructure_output(result)
#             return {"status": "success", "message": "Estimated the defaults.","defaults":output}
#         except Exception as e:
#             return {"status": "failed", "message": e}


#     async def _fetch_existing_result(self,file_path):
#         print("Inside fetch result function")
#         if os.path.exists(file_path):
#             print("Inside if condition")
#             # with open(file_path, 'r') as file:
#             async with aiofiles.open(file_path, 'r') as file:
#                 result = await file.read()
#                 print(f"The fetched result is : {result}")
#                 print(f"The type of result is : {type(result)}")
#             # print(f"The output is : {result}")
#             return True, result
#         return False, ""

#     def _restructure_output(self,result: str) -> dict:
#         try:
#             print("Inside restructure output function")
#             print(f"The type of result is : {type(result)}")
#             print(f"Result content: {repr(result)}")
#             matches = re.findall(r"##\s*([\w\s]+?)\s*-\s*(\d+)%",result)

#             print("match found")
#             # Convert to dictionary
#             return {skill.strip(): int(percent) for skill, percent in matches}
#         except Exception as e:
#             print(e)
#             return {}



### adding exceptions
from user_journey_service.core.exceptions import (
    FetchResultError,
    RestructureOutputError
)
class DefaultEstimator:
    def __init__(self,input_data):
        self.crew_instance = UserJourney()
        self.input_data = input_data
        self.input_hash = HashGenerator.generate_input_hash(input_data)
        self.default_folder = f"defaults/{self.input_hash}.md"
    


    def run(self):
        print("Inside user defaults estimator service")
        inputs = self.input_data.dict()
        try:
            exists,result = self._fetch_existing_result(self.default_folder)
            if exists:
                print("Inside if of main function")
                output = self._restructure_output(result)
                return {"status": "success", "message": "Fetched existing result.","defaults":output,"hashid":self.input_hash}
            crew = self.crew_instance.defaults_crew(output_file=self.default_folder)
            crew.kickoff(inputs=inputs)
            exists,result = self._fetch_existing_result(self.default_folder)
            output = self._restructure_output(result)
            return {"status": "success", "message": "Estimated the defaults.","defaults":output,"hashid":self.input_hash}
        except FetchResultError as e:
            return {"status": "failed", "message": f"Error in fetching the result: {e}"}
        except RestructureOutputError as e:
            return {"status": "failed", "message": f"Error in restructuring the result"}
        except Exception as e:
            return {"status": "failed", "message": e}


    def _fetch_existing_result(self,file_path):
        print("Inside fetch result function")
        try:
            if os.path.exists(file_path):
                print("Inside if condition")
                # os.remove(file_path)   # remove file
                # print(f"{file_path} deleted successfully")
                with open(file_path, 'r') as file:
                    result = file.read()
                    print(f"The fetched result is : {result}")
                    print(f"The type of result is : {type(result)}")
                # print(f"The output is : {result}")
                return True, result
            return False, ""
        except Exception as e:
            raise FetchResultError(file_path, str(e))

    def _restructure_output(self,result: str) -> dict:
        try:
            print("Inside restructure output function")
            print(f"The type of result is : {type(result)}")
            print(f"Result content: {repr(result)}")
            matches = re.findall(r"##\s*([\w\s]+?)\s*-\s*(\d+)%",result)

            print("match found")
            # Convert to dictionary
            return {skill.strip(): int(percent) for skill, percent in matches}
        except Exception as e:
            print(e)
            raise RestructureOutputError
            return {}