from typing import List, Optional

import instalabel.client
from instalabel.client.models.aws_integration_response import AWSIntegrationResponse
from instalabel.client.models.project_create import ProjectCreate
from instalabel.client.models.task_enum import TaskEnum
from instalabel.client.models.workspace_create import WorkspaceCreate
from instalabel.client.models.workspace_credits import WorkspaceCredits
from instalabel.client.models.workspace_in_db import WorkspaceInDB
from instalabel.config import INSTALABEL_CLIENT_CONFIGURATION as configuration
from instalabel.core.project import Project


class Workspace:
    def __init__(self, workspace: WorkspaceInDB):
        """Initialize a workspace instance"""
        self.id = workspace.workspace_id
        self.name = workspace.workspace_name
        self.description = workspace.description
        self.created_at = workspace.created_at
        self.updated_at = workspace.updated_at
        self.credits = workspace.credits

    @classmethod
    def create(cls, workspace_name: str, description: str = None) -> "Workspace":
        """Create a new workspace"""
        with instalabel.client.ApiClient(configuration) as api_client:
            api_instance = instalabel.client.WorkspacesApi(api_client)
            workspace_create = WorkspaceCreate(
                workspace_name=workspace_name, description=description
            )

            try:
                api_response = api_instance.create_workspace_api_v1_workspaces_post(
                    workspace_create
                )
                return cls(api_response)
            except Exception as e:
                print(f"Exception when creating workspace: {e}")
                return None

    def create_project(
        self, project_name: str, task: TaskEnum, project_description: str = ""
    ) -> Optional[Project]:
        """Create a new project in the workspace"""
        with instalabel.client.ApiClient(configuration) as api_client:
            api_instance = instalabel.client.ProjectsApi(api_client)
            project_create = ProjectCreate(
                workspace_id=self.id,
                project_name=project_name,
                project_description=project_description,
                task=task,
            )

            try:
                api_response = api_instance.create_project_api_v1_projects_post(
                    workspace_id=self.id, project_create=project_create
                )
                return Project(api_response)
            except Exception as e:
                print(f"Exception when creating project: {e}")
                return None

    def get_projects(self) -> List[Project]:
        """Get all projects in the workspace"""
        with instalabel.client.ApiClient(configuration) as api_client:
            api_instance = instalabel.client.ProjectsApi(api_client)

            try:
                api_response = api_instance.read_projects_api_v1_projects_get(
                    workspace_id=self.id
                )
                return [Project(project) for project in api_response]
            except Exception as e:
                print(f"Exception when getting projects: {e}")
                return []

    def get_credits(self) -> Optional[WorkspaceCredits]:
        """Get workspace credits information"""
        with instalabel.client.ApiClient(configuration) as api_client:
            api_instance = instalabel.client.WorkspacesApi(api_client)

            try:
                api_response = (
                    api_instance.read_workspace_api_v1_workspaces_workspace_id_get(
                        workspace_id=self.id
                    )
                )
                return api_response.credits
            except Exception as e:
                print(f"Exception when getting workspace credits: {e}")
                return None

    def get_integrations(self) -> List[AWSIntegrationResponse]:
        """Get all AWS integrations for the workspace

        Returns:
            List[AWSIntegrationResponse]: List of AWS integrations for this workspace
        """
        with instalabel.client.ApiClient(configuration) as api_client:
            api_instance = instalabel.client.AwsIntegrationsApi(api_client)

            try:
                api_response = api_instance.get_workspace_integrations_api_v1_aws_integrations_workspace_workspace_id_get(
                    workspace_id=self.id
                )
                return api_response
            except Exception as e:
                print(f"Exception when getting AWS integrations: {e}")
                return []

    def get_project(self, project_id: str) -> Optional[Project]:
        """Get a specific project by ID from the workspace

        Args:
            project_id (str): The ID of the project to retrieve

        Returns:
            Optional[Project]: The project if found, None otherwise
        """
        with instalabel.client.ApiClient(configuration) as api_client:
            api_instance = instalabel.client.ProjectsApi(api_client)

            try:
                api_response = api_instance.read_project_api_v1_projects_project_id_get(
                    project_id=project_id
                )
                return Project(api_response)
            except Exception as e:
                print(f"Exception when getting project: {e}")
                return None

    def __str__(self):
        return f"Workspace(ID: {self.id}, Name: {self.name})"
