from __future__ import annotations

from dataclasses import dataclass

from packages.domain import Project
from packages.ports import ProjectRepository


@dataclass(slots=True)
class CreateProjectCommand:
    name: str
    description: str = ""


class ListProjectsUseCase:
    def __init__(self, project_repository: ProjectRepository):
        self.project_repository = project_repository

    def execute(self, user_id: str) -> list[Project]:
        if not user_id.strip():
            raise ValueError("user_id 不能为空")
        return self.project_repository.find_accessible_projects(user_id.strip())


class GetProjectUseCase:
    def __init__(self, project_repository: ProjectRepository):
        self.project_repository = project_repository

    def execute(self, project_id: str) -> Project | None:
        if not project_id.strip():
            raise ValueError("project_id 不能为空")
        return self.project_repository.find_by_id(project_id.strip())


class CreateProjectUseCase:
    def __init__(self, project_repository: ProjectRepository):
        self.project_repository = project_repository

    def execute(self, command: CreateProjectCommand, owner_user_id: str) -> Project:
        project = Project.create(
            owner_user_id=owner_user_id,
            name=command.name,
            description=command.description,
        )
        return self.project_repository.save(project)


class ShareProjectUseCase:
    def __init__(self, project_repository: ProjectRepository):
        self.project_repository = project_repository

    def execute(self, project_id: str, owner_user_id: str, shared_user_id: str) -> Project:
        project = self.project_repository.find_by_id(project_id)
        if not project:
            raise ValueError("项目不存在")
        if not project.is_owner(owner_user_id):
            raise ValueError("只有项目所有者可以共享项目")
        if shared_user_id not in project.shared_users:
            project.shared_users.append(shared_user_id)
            self.project_repository.save(project)
        return project


class DeleteProjectUseCase:
    def __init__(self, project_repository: ProjectRepository):
        self.project_repository = project_repository

    def execute(self, project_id: str, user_id: str) -> bool:
        project = self.project_repository.find_by_id(project_id)
        if not project:
            return False
        if not project.is_owner(user_id):
            raise PermissionError("只有项目所有者可以删除项目")
        return self.project_repository.delete(project_id)


class UnshareProjectUseCase:
    def __init__(self, project_repository: ProjectRepository):
        self.project_repository = project_repository

    def execute(self, project_id: str, owner_user_id: str, shared_user_id: str) -> Project:
        project = self.project_repository.find_by_id(project_id)
        if not project:
            raise ValueError("项目不存在")
        if not project.is_owner(owner_user_id):
            raise ValueError("只有项目所有者可以取消共享")
        if shared_user_id in project.shared_users:
            project.shared_users.remove(shared_user_id)
            self.project_repository.save(project)
        return project
