"""
PM Module — OBS Entity (Organizational Breakdown Structure)

ساختار شکست سازمانی — نمایش سلسله‌مراتب سازمانی برای تخصیص مسئولیت پروژه.
"""

from dataclasses import dataclass, field
from typing import Optional
from uuid import UUID, uuid4

from shared.base_classes.entity import TenantEntity

from ..value_objects.common import OBSNodeType


@dataclass
class OBSNode(TenantEntity):
    """
    گره ساختار شکست سازمانی.

    هر گره نمایانگر یک واحد سازمانی، تیم یا فرد مسئول در پروژه است.
    ساختار درختی با parent/child.
    """

    project_id: UUID = field(default_factory=uuid4)
    parent_id: Optional[UUID] = None

    # --- Identification ---
    code: str = ""
    name: str = ""
    description: str = ""

    # --- Classification ---
    node_type: str = OBSNodeType.DEPARTMENT.value
    level: int = 0                      # عمق در درخت (ریشه = 0)

    # --- Assignment ---
    manager_id: Optional[UUID] = None   # → User (مدیر/مسئول گره)
    org_unit_id: Optional[UUID] = None  # → HRM OrgUnit (واحد سازمانی مرجع)

    # --- Details ---
    responsibilities: str = ""           # شرح مسئولیت‌ها
    is_active: bool = True
    sort_order: int = 0

    # --- Metadata ---
    metadata: Optional[dict] = field(default_factory=dict)

    # ─── Business Methods ───────────────────────────────

    def deactivate(self):
        """غیرفعال کردن گره."""
        self.is_active = False

    def activate(self):
        """فعال کردن گره."""
        self.is_active = True

    def set_manager(self, manager_id: UUID):
        """تنظیم مدیر/مسئول گره."""
        self.manager_id = manager_id

    def move_to_parent(self, new_parent_id: Optional[UUID], new_level: int):
        """جابجایی گره به والد جدید."""
        self.parent_id = new_parent_id
        self.level = new_level

    @property
    def is_root(self) -> bool:
        """آیا گره ریشه است."""
        return self.parent_id is None

    @property
    def display_name(self) -> str:
        """نام نمایشی."""
        return f"{self.code} — {self.name}" if self.code else self.name
