from app.api.v1.libraries.object import str_to_objectid
from fastapi import HTTPException
import httpx
from ..libraries.crypto import decrypt_data 

APP_COLLECTION = "app"
APP_INTEGRATION_COLLECTION = "app_users"
FLOW_COLLECTION = "flows"

class ConfigurationLoader:
    def __init__(self, db):
        self.db = db

    async def load_integration(self, app_integration_id: str):
        """
        Load app integration configuration by its ID.
        """
        try:
            integration_object_id = str_to_objectid(app_integration_id)
            app_integration = self.db[APP_INTEGRATION_COLLECTION].find_one({"_id": integration_object_id})
            # Check and decrypt the credentials if present
            
            if "auth_config" in app_integration and "credentials" in app_integration["auth_config"]:
                for key, encrypted_value in app_integration["auth_config"]["credentials"].items():
                    # Decrypt each credential
                    decrypted_value = decrypt_data(encrypted_value)
                    app_integration["auth_config"]["credentials"][key] = decrypted_value
            return app_integration
        
        except Exception as e:
            raise HTTPException(status_code=500, detail=f"Error in fetching data: {str(e)}")

        return

    async def load_flow(self, flow_id: str):
        """
        Load app integration configuration by its ID.
        """
        try:
            flow_object_id = str_to_objectid(flow_id)
            flow = self.db[FLOW_COLLECTION].find_one({"_id": flow_object_id})
            return flow
        except Exception as e:
            raise HTTPException(status_code=500, detail=f"Error in fetching data: {str(e)}")

        return
    

    async def load_app_details(self, app_id: str):
        """
        Load app details by app ID.
        """
        try:
            app_object_id = str_to_objectid(app_id)
            app_details = self.db[APP_COLLECTION].find_one({"_id": app_object_id})
            if not app_details:
                raise HTTPException(status_code=404, detail=f"App with ID {app_id} not found")
            return app_details
        except Exception as e:
            raise HTTPException(status_code=500, detail=f"Error in fetching data: {str(e)}")

    async def load_openapi_spec(self, openapi_url: str):
        """
        Load OpenAPI specification from a URL.
        """
        try:
            async with httpx.AsyncClient() as client:
                response = await client.get(openapi_url)
                response.raise_for_status()
                return response.json()
        except httpx.HTTPError as e:
            raise HTTPException(status_code=500, detail=f"HTTP error occurred while loading OpenAPI spec: {e}")

    async def load_integration_old(self, app_integration_id: str):
        """
        Load app integration configuration by its ID.
        """
        try:
            integration_object_id = str_to_objectid(app_integration_id)
            app_integration = self.db[APP_INTEGRATION_COLLECTION].find_one({"_id": integration_object_id})
            print(app_integration)
            if not app_integration:
                raise HTTPException(status_code=404, detail=f"App Integration with ID {app_integration_id} not found")
            return app_integration
        except Exception as e:
            raise HTTPException(status_code=500, detail=f"Error in fetching data: {str(e)}")


# Example usage
# Assuming 'db' is the database instance from AppEngine
# loader = ConfigurationLoader(db)
# integration = await loader.load_integration("integration_id")
