"""Domain Ports for the Projects Bounded Context.

These Protocol interfaces define the contracts that the Application Services
depend on. Infrastructure Adapters (e.g. PostgresProjectRepository) implement
these protocols, keeping the Domain layer independent of any framework, ORM, or DB.

Architecture:
    Presentation → Application Services → [Domain Ports] ← Infrastructure Adapters
"""
from __future__ import annotations

from typing import Any, Optional, Protocol, runtime_checkable
from uuid import UUID

from app.modules.projects.domain.entities import Project


@runtime_checkable
class ProjectRepositoryPort(Protocol):
    """Port cho CQRS Command-side operations (write path).

    Implemented by: ProjectRepository (existing, connection-scoped).
    Used by: CreateProjectCommandHandler
    """

    def save(self, project: Project) -> None: ...
    def get_by_id(self, project_id: UUID) -> Optional[Project]: ...


@runtime_checkable
class ProjectCrudPort(Protocol):
    """Port cho ProjectManagement full-featured CRUD operations.

    Covers: project listing, detail, create/update/delete, WBS tree,
    financial summaries, milestones, and war room data.

    Migrated from: PostgresClient.fetch_project_management_records()
                   ProjectCrudRepository (app/core/postgres/project_crud/)
    """

    def is_enabled(self) -> bool: ...

    # --- Project CRUD ---
    def fetch_project_management_records(self) -> list[dict[str, Any]]: ...
    def get_project_detail(self, project_id_or_code: str) -> Optional[dict[str, Any]]: ...
    def create_project(self, data: dict[str, Any]) -> dict[str, Any]: ...
    def update_project(self, project_id: str, data: dict[str, Any]) -> dict[str, Any]: ...
    def list_projects_summary(self) -> list[dict[str, Any]]: ...

    # --- WBS Operations ---
    def list_wbs(self, project_id: str) -> list[dict[str, Any]]: ...
    def create_wbs_item(self, project_id: str, data: dict[str, Any]) -> dict[str, Any]: ...
    def update_wbs_item(self, wbs_id: str, data: dict[str, Any]) -> dict[str, Any]: ...
    def delete_wbs_item(self, wbs_id: str) -> dict[str, Any]: ...

    # --- Project Financial Summary ---
    def get_project_financial_summary(self, project_id: str) -> dict[str, Any]: ...


@runtime_checkable
class ProjectEventStorePort(Protocol):
    """Port cho idempotent event processing (cost sync from invoices).

    Migrated from: ErpDatabaseClient direct SQL in cost_sync_listener.py
    """

    def is_event_processed(self, project_id: str, event_type: str, reference_id: str) -> bool: ...
    def add_cost_to_wbs(self, wbs_id: str, project_id: str, amount: float) -> int: ...
    def record_processed_event(self, project_id: str, event_type: str, reference_id: str) -> None: ...


@runtime_checkable
class ProjectQueryPort(Protocol):
    """Port cho read-optimized queries (CQRS Query-side).

    Migrated from: BasePostgresClient direct SQL in queries.py
    """

    def get_project_details_read_model(self, project_id: UUID) -> Optional[dict[str, Any]]: ...


@runtime_checkable
class ProjectDataIntegrityPort(Protocol):
    """Port cho data integrity audit operations.

    Migrated from: ErpDatabaseClient in data_integrity_service.py
    """

    def fetch_all_projects_for_audit(self) -> list[dict[str, Any]]: ...
    def fetch_wbs_for_project(self, project_id: str) -> list[dict[str, Any]]: ...
    def fetch_ipcs_for_project(self, project_id: str) -> list[dict[str, Any]]: ...


@runtime_checkable
class ProjectExcelSyncPort(Protocol):
    """Port cho Excel ↔ Database sync operations.

    Migrated from: ErpDatabaseClient in excel_sync_service.py
    """

    def fetch_all_projects_for_export(self) -> list[dict[str, Any]]: ...
    def upsert_project_from_excel(self, data: dict[str, Any]) -> dict[str, Any]: ...
