"""
PPM Domain — Events

رویدادهای دامنه ماژول مدیریت پرتفولیو و برنامه.
"""

from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional
from uuid import UUID, uuid4


@dataclass(frozen=True)
class PPMDomainEvent:
    """رویداد پایه دامنه PPM."""
    event_id: UUID = field(default_factory=uuid4)
    tenant_id: Optional[UUID] = None
    occurred_at: datetime = field(default_factory=datetime.now)


# ─── Portfolio Events ────────────────────────────────────────

@dataclass(frozen=True)
class PortfolioCreated(PPMDomainEvent):
    event_type: str = "ppm.portfolio.created"
    portfolio_id: Optional[UUID] = None
    code: str = ""
    name: str = ""


@dataclass(frozen=True)
class PortfolioUpdated(PPMDomainEvent):
    event_type: str = "ppm.portfolio.updated"
    portfolio_id: Optional[UUID] = None


@dataclass(frozen=True)
class PortfolioClosed(PPMDomainEvent):
    event_type: str = "ppm.portfolio.closed"
    portfolio_id: Optional[UUID] = None


# ─── Program Events ─────────────────────────────────────────

@dataclass(frozen=True)
class ProgramCreated(PPMDomainEvent):
    event_type: str = "ppm.program.created"
    program_id: Optional[UUID] = None
    code: str = ""
    name: str = ""
    portfolio_id: Optional[UUID] = None


@dataclass(frozen=True)
class ProgramUpdated(PPMDomainEvent):
    event_type: str = "ppm.program.updated"
    program_id: Optional[UUID] = None


@dataclass(frozen=True)
class ProgramCompleted(PPMDomainEvent):
    event_type: str = "ppm.program.completed"
    program_id: Optional[UUID] = None


@dataclass(frozen=True)
class ProgramProjectAdded(PPMDomainEvent):
    event_type: str = "ppm.program_project.added"
    program_id: Optional[UUID] = None
    project_id: Optional[UUID] = None
    role: str = ""


@dataclass(frozen=True)
class ProgramProjectRemoved(PPMDomainEvent):
    event_type: str = "ppm.program_project.removed"
    program_id: Optional[UUID] = None
    project_id: Optional[UUID] = None


# ─── Business Case Events ────────────────────────────────────

@dataclass(frozen=True)
class BusinessCaseCreated(PPMDomainEvent):
    event_type: str = "ppm.business_case.created"
    business_case_id: Optional[UUID] = None
    title: str = ""


@dataclass(frozen=True)
class BusinessCaseSubmitted(PPMDomainEvent):
    event_type: str = "ppm.business_case.submitted"
    business_case_id: Optional[UUID] = None


@dataclass(frozen=True)
class BusinessCaseApproved(PPMDomainEvent):
    event_type: str = "ppm.business_case.approved"
    business_case_id: Optional[UUID] = None


@dataclass(frozen=True)
class BusinessCaseRejected(PPMDomainEvent):
    event_type: str = "ppm.business_case.rejected"
    business_case_id: Optional[UUID] = None


# ─── Scoring Events ──────────────────────────────────────────

@dataclass(frozen=True)
class ScoringModelCreated(PPMDomainEvent):
    event_type: str = "ppm.scoring_model.created"
    scoring_model_id: Optional[UUID] = None
    name: str = ""


@dataclass(frozen=True)
class ScoringModelActivated(PPMDomainEvent):
    event_type: str = "ppm.scoring_model.activated"
    scoring_model_id: Optional[UUID] = None


@dataclass(frozen=True)
class ProjectScored(PPMDomainEvent):
    event_type: str = "ppm.project.scored"
    project_id: Optional[UUID] = None
    scoring_model_id: Optional[UUID] = None
    weighted_score: Optional[str] = None


@dataclass(frozen=True)
class ProjectsRanked(PPMDomainEvent):
    event_type: str = "ppm.projects.ranked"
    scoring_model_id: Optional[UUID] = None
    portfolio_id: Optional[UUID] = None


# ─── Benefit Realization Events ───────────────────────────────

@dataclass(frozen=True)
class BenefitPlanCreated(PPMDomainEvent):
    event_type: str = "ppm.benefit_plan.created"
    benefit_plan_id: Optional[UUID] = None
    name: str = ""


@dataclass(frozen=True)
class BenefitCreated(PPMDomainEvent):
    event_type: str = "ppm.benefit.created"
    benefit_id: Optional[UUID] = None
    benefit_plan_id: Optional[UUID] = None
    title: str = ""


@dataclass(frozen=True)
class BenefitRealized(PPMDomainEvent):
    event_type: str = "ppm.benefit.realized"
    benefit_id: Optional[UUID] = None


@dataclass(frozen=True)
class BenefitMeasured(PPMDomainEvent):
    event_type: str = "ppm.benefit.measured"
    benefit_id: Optional[UUID] = None
    measurement_id: Optional[UUID] = None
    value: Optional[str] = None


# ─── Capacity Planning Events ─────────────────────────────────

@dataclass(frozen=True)
class CapacityPlanCreated(PPMDomainEvent):
    event_type: str = "ppm.capacity_plan.created"
    capacity_plan_id: Optional[UUID] = None
    name: str = ""


@dataclass(frozen=True)
class CapacityBottleneckDetected(PPMDomainEvent):
    event_type: str = "ppm.capacity.bottleneck_detected"
    capacity_plan_id: Optional[UUID] = None
    resource_type: str = ""
    period: str = ""


# ─── Cross-Project Dependency Events ──────────────────────────

@dataclass(frozen=True)
class DependencyCreated(PPMDomainEvent):
    event_type: str = "ppm.dependency.created"
    dependency_id: Optional[UUID] = None
    predecessor_project_id: Optional[UUID] = None
    successor_project_id: Optional[UUID] = None
    dependency_type: str = ""


@dataclass(frozen=True)
class DependencyResolved(PPMDomainEvent):
    event_type: str = "ppm.dependency.resolved"
    dependency_id: Optional[UUID] = None


@dataclass(frozen=True)
class CircularDependencyDetected(PPMDomainEvent):
    event_type: str = "ppm.dependency.circular_detected"
    cycle: str = ""  # serialized cycle info
