"""
PM Module — Public Events Contract

رویدادهای عمومی ماژول مدیریت پروژه.
سایر ماژول‌ها فقط از این فایل import می‌کنند.
"""

from dataclasses import dataclass
from datetime import date, datetime
from decimal import Decimal
from typing import Optional
from uuid import UUID


@dataclass(frozen=True)
class PMEvent:
    """رویداد پایه ماژول PM."""
    event_id: UUID
    tenant_id: UUID
    occurred_at: datetime
    version: int = 1


@dataclass(frozen=True)
class ProjectCreated(PMEvent):
    event_type: str = "pm.project.created"
    project_id: Optional[UUID] = None
    code: str = ""
    title: str = ""
    project_type: str = ""
    company_id: Optional[UUID] = None


@dataclass(frozen=True)
class ProjectStatusChanged(PMEvent):
    event_type: str = "pm.project.status_changed"
    project_id: Optional[UUID] = None
    old_status: str = ""
    new_status: str = ""


@dataclass(frozen=True)
class ProjectCompleted(PMEvent):
    event_type: str = "pm.project.completed"
    project_id: Optional[UUID] = None
    actual_end: Optional[date] = None


@dataclass(frozen=True)
class TaskCreated(PMEvent):
    event_type: str = "pm.task.created"
    project_id: Optional[UUID] = None
    task_id: Optional[UUID] = None
    title: str = ""


@dataclass(frozen=True)
class TaskCompleted(PMEvent):
    event_type: str = "pm.task.completed"
    project_id: Optional[UUID] = None
    task_id: Optional[UUID] = None


@dataclass(frozen=True)
class MilestoneReached(PMEvent):
    event_type: str = "pm.milestone.reached"
    project_id: Optional[UUID] = None
    task_id: Optional[UUID] = None
    title: str = ""


@dataclass(frozen=True)
class ResourceAssigned(PMEvent):
    event_type: str = "pm.resource.assigned"
    project_id: Optional[UUID] = None
    task_id: Optional[UUID] = None
    resource_id: Optional[UUID] = None


@dataclass(frozen=True)
class CostRecorded(PMEvent):
    event_type: str = "pm.cost.recorded"
    project_id: Optional[UUID] = None
    amount: Decimal = Decimal("0")


@dataclass(frozen=True)
class RiskIdentified(PMEvent):
    event_type: str = "pm.risk.identified"
    project_id: Optional[UUID] = None
    risk_id: Optional[UUID] = None
    title: str = ""


@dataclass(frozen=True)
class ChangeRequestSubmitted(PMEvent):
    event_type: str = "pm.change_request.submitted"
    project_id: Optional[UUID] = None
    change_request_id: Optional[UUID] = None
    title: str = ""


@dataclass(frozen=True)
class ChangeRequestApproved(PMEvent):
    event_type: str = "pm.change_request.approved"
    project_id: Optional[UUID] = None
    change_request_id: Optional[UUID] = None


@dataclass(frozen=True)
class BaselineCreated(PMEvent):
    event_type: str = "pm.baseline.created"
    project_id: Optional[UUID] = None
    baseline_id: Optional[UUID] = None


@dataclass(frozen=True)
class IssueCreated(PMEvent):
    event_type: str = "pm.issue.created"
    project_id: Optional[UUID] = None
    issue_id: Optional[UUID] = None
    title: str = ""
    severity: str = ""
    priority: str = ""


@dataclass(frozen=True)
class IssueResolved(PMEvent):
    event_type: str = "pm.issue.resolved"
    project_id: Optional[UUID] = None
    issue_id: Optional[UUID] = None


@dataclass(frozen=True)
class IssueClosed(PMEvent):
    event_type: str = "pm.issue.closed"
    project_id: Optional[UUID] = None
    issue_id: Optional[UUID] = None


# ─── OBS Events ──────────────────────────────────────────────────────

@dataclass(frozen=True)
class OBSNodeCreated(PMEvent):
    event_type: str = "pm.obs_node.created"
    project_id: Optional[UUID] = None
    node_id: Optional[UUID] = None
    code: str = ""
    name: str = ""


@dataclass(frozen=True)
class OBSNodeDeleted(PMEvent):
    event_type: str = "pm.obs_node.deleted"
    project_id: Optional[UUID] = None
    node_id: Optional[UUID] = None


# ─── RBS Events ──────────────────────────────────────────────────────

@dataclass(frozen=True)
class RBSNodeCreated(PMEvent):
    event_type: str = "pm.rbs_node.created"
    project_id: Optional[UUID] = None
    node_id: Optional[UUID] = None
    code: str = ""
    name: str = ""


@dataclass(frozen=True)
class RBSNodeDeleted(PMEvent):
    event_type: str = "pm.rbs_node.deleted"
    project_id: Optional[UUID] = None
    node_id: Optional[UUID] = None


# ─── Quality Events ─────────────────────────────────────────────────

@dataclass(frozen=True)
class InspectionCompleted(PMEvent):
    event_type: str = "pm.inspection.completed"
    project_id: Optional[UUID] = None
    inspection_id: Optional[UUID] = None
    code: str = ""
    result: str = ""


@dataclass(frozen=True)
class NCRCreated(PMEvent):
    event_type: str = "pm.ncr.created"
    project_id: Optional[UUID] = None
    ncr_id: Optional[UUID] = None
    code: str = ""
    severity: str = ""


@dataclass(frozen=True)
class NCRResolved(PMEvent):
    event_type: str = "pm.ncr.resolved"
    project_id: Optional[UUID] = None
    ncr_id: Optional[UUID] = None
    code: str = ""


# ─── Document Events ─────────────────────────────────────────

@dataclass(frozen=True)
class DocumentLinked(PMEvent):
    event_type: str = "pm.document.linked"
    project_id: Optional[UUID] = None
    document_id: Optional[UUID] = None
    entity_type: str = ""
    entity_id: str = ""


@dataclass(frozen=True)
class DocumentUnlinked(PMEvent):
    event_type: str = "pm.document.unlinked"
    project_id: Optional[UUID] = None
    document_id: Optional[UUID] = None
    entity_type: str = ""
    entity_id: str = ""
