from dataclasses import dataclass
from typing import List, Literal

from .client import ApiClient
from .organization import Organization
from .team import Team


# どのエンドポイントにも含む要素（create/update)
@dataclass
class Project:
    id: str
    name: str
    description: str
    createdAt: str
    updatedAt: str
    teamId: str
    team: Team


@dataclass
class ProjectWithThumbnail(Project):
    thumbnailImageUrl: str


def create_project(team_id: str, name: str, description: str) -> ProjectWithThumbnail:
    """
    Create a new project

    Args:
        team_id: Team ID
        name: Project name

    Returns:
        Project object or None if creation failed
    """

    response = ApiClient.post(
        "/project",
        {
            "name": name,
            "teamId": team_id,
            "description": description,
        },
    )

    return ProjectWithThumbnail(
        id=response.get("id", ""),
        name=response.get("name", ""),
        description=response.get("description", ""),
        createdAt=response.get("createdAt", ""),
        updatedAt=response.get("updatedAt", ""),
        thumbnailImageUrl=response.get("thumbnailImageUrl"),
        teamId=response.get("team", {}).get("id", ""),
        team=Team(
            id=response.get("team", {}).get("id", ""),
            name=response.get("team", {}).get("name", ""),
            createdAt=response.get("team", {}).get("createdAt", ""),
            updatedAt=response.get("team", {}).get("updatedAt", ""),
            organizationId=response.get("team", {}).get("organizationId", ""),
            organization=Organization(
                id=response.get("team", {}).get("organization", {}).get("id", ""),
                name=response.get("team", {}).get("organization", {}).get("name", ""),
                subscriptionPlan=response.get("team", {})
                .get("organization", {})
                .get("subscriptionPlan", ""),
                stripeCustomerId=response.get("team", {})
                .get("organization", {})
                .get("stripeCustomerId", ""),
                storageUnits=response.get("team", {})
                .get("organization", {})
                .get("storageUnits", 0),
                createdAt=response.get("team", {})
                .get("organization", {})
                .get("createdAt", ""),
                updatedAt=response.get("team", {})
                .get("organization", {})
                .get("updatedAt", ""),
            ),
        ),
    )


def update_project(
    project_id: str, name: str, description: str
) -> ProjectWithThumbnail:
    """
    Update an existing project

    Args:
        project_id: Project ID
        name: New project name

    Returns:
        Updated Project object or None if update failed
    """

    response = ApiClient.put(
        f"/project/{project_id}",
        {
            "name": name,
            "description": description,
        },
    )

    return ProjectWithThumbnail(
        id=response.get("id", ""),
        name=response.get("name", ""),
        description=response.get("description", ""),
        createdAt=response.get("createdAt", ""),
        updatedAt=response.get("updatedAt", ""),
        thumbnailImageUrl=response.get("thumbnailImageUrl"),
        teamId=response.get("team", {}).get("id", ""),
        team=Team(
            id=response.get("team", {}).get("id", ""),
            name=response.get("team", {}).get("name", ""),
            createdAt=response.get("team", {}).get("createdAt", ""),
            updatedAt=response.get("team", {}).get("updatedAt", ""),
            organizationId=response.get("team", {}).get("organizationId", ""),
            organization=Organization(
                id=response.get("team", {}).get("organization", {}).get("id", ""),
                name=response.get("team", {}).get("organization", {}).get("name", ""),
                subscriptionPlan=response.get("team", {})
                .get("organization", {})
                .get("subscriptionPlan", ""),
                stripeCustomerId=response.get("team", {})
                .get("organization", {})
                .get("stripeCustomerId", ""),
                storageUnits=response.get("team", {})
                .get("organization", {})
                .get("storageUnits", 0),
                createdAt=response.get("team", {})
                .get("organization", {})
                .get("createdAt", ""),
                updatedAt=response.get("team", {})
                .get("organization", {})
                .get("updatedAt", ""),
            ),
        ),
    )


def delete_project(project_id: str) -> None:
    """
    Delete a project

    Args:
        project_id: Project ID

    Returns:
        True if successful, False otherwise
    """
    ApiClient.delete(f"/project/{project_id}")


# Org内Project一覧取得用
@dataclass
class ProjectsInOrganization(ProjectWithThumbnail):
    vectorCount: int
    rasterCount: int
    mapCount: int
    storageUnitsSum: float


def get_projects_by_organization(organization_id: str) -> List[ProjectsInOrganization]:
    """
    Get a list of projects for a specific organization

    Args:
        organization_id: Organization ID

    Returns:
        List of Project objects
    """
    response = ApiClient.get(f"/organization/{organization_id}/projects")
    projects = []
    for project in response:
        projects.append(
            ProjectsInOrganization(
                id=project.get("id", ""),
                name=project.get("name", ""),
                description=project.get("description", ""),
                createdAt=project.get("createdAt", ""),
                updatedAt=project.get("updatedAt", ""),
                thumbnailImageUrl=project.get("thumbnailImageUrl", ""),
                teamId=project.get("team", {}).get("id", ""),
                team=Team(
                    id=project.get("team", {}).get("id", ""),
                    name=project.get("team", {}).get("name", ""),
                    createdAt=project.get("team", {}).get("createdAt", ""),
                    updatedAt=project.get("team", {}).get("updatedAt", ""),
                    organizationId=project.get("team", {}).get("organizationId", ""),
                    organization=Organization(
                        id=project.get("team", {})
                        .get("organization", {})
                        .get("id", ""),
                        name=project.get("team", {})
                        .get("organization", {})
                        .get("name", ""),
                        stripeCustomerId=project.get("team", {})
                        .get("organization", {})
                        .get("stripeCustomerId", ""),
                        subscriptionPlan=project.get("team", {})
                        .get("organization", {})
                        .get("subscriptionPlan", ""),
                        storageUnits=project.get("team", {})
                        .get("organization", {})
                        .get("storageUnits", 0),
                        createdAt=project.get("team", {})
                        .get("organization", {})
                        .get("createdAt", ""),
                        updatedAt=project.get("team", {})
                        .get("organization", {})
                        .get("updatedAt", ""),
                    ),
                ),
                vectorCount=project.get("vectorCount", 0),
                rasterCount=project.get("rasterCount", 0),
                mapCount=project.get("mapCount", 0),
                storageUnitsSum=project.get("storageUnitsSum", 0.0),
            )
        )
    return projects


@dataclass
class ProjectDetail(ProjectWithThumbnail):
    role: Literal["ADMIN", "OWNER", "MEMBER"]
    storageUnitsSum: float


def get_project(project_id: str) -> ProjectDetail:
    """
    Get details for a specific project

    Args:
        project_id: Project ID

    Returns:
        Project object or None if not found
    """
    response = ApiClient.get(f"/project/{project_id}")

    return ProjectDetail(
        id=response.get("id", ""),
        name=response.get("name", ""),
        description=response.get("description", ""),
        createdAt=response.get("createdAt", ""),
        updatedAt=response.get("updatedAt", ""),
        storageUnitsSum=response.get("storageUnitsSum", 0.0),
        thumbnailImageUrl=response.get("thumbnailImageUrl"),
        role=response.get("role", "MEMBER"),
        teamId=response.get("team", {}).get("id", ""),
        team=Team(
            id=response.get("team", {}).get("id", ""),
            name=response.get("team", {}).get("name", ""),
            createdAt=response.get("team", {}).get("createdAt", ""),
            updatedAt=response.get("team", {}).get("updatedAt", ""),
            organizationId=response.get("team", {}).get("organizationId", ""),
            organization=Organization(
                id=response.get("team", {}).get("organization", {}).get("id", ""),
                name=response.get("team", {}).get("organization", {}).get("name", ""),
                subscriptionPlan=response.get("team", {})
                .get("organization", {})
                .get("subscriptionPlan", ""),
                stripeCustomerId=response.get("team", {})
                .get("organization", {})
                .get("stripeCustomerId", ""),
                storageUnits=response.get("team", {})
                .get("organization", {})
                .get("storageUnits", 0),
                createdAt=response.get("team", {})
                .get("organization", {})
                .get("createdAt", ""),
                updatedAt=response.get("team", {})
                .get("organization", {})
                .get("updatedAt", ""),
            ),
        ),
    )
