"""
PM Module — Advanced Domain Entities

موجودیت‌های پیشرفته — پورتفولیو، برنامه، کدهای فعالیت، UDF، و ...
"""

from dataclasses import dataclass, field
from datetime import date, datetime
from decimal import Decimal
from typing import Optional, List
from uuid import UUID, uuid4

from shared.base_classes.entity import TenantEntity


# ═══════════════════════════════════════════════════
# Activity Code (کد فعالیت — P6 style)
# ═══════════════════════════════════════════════════

@dataclass
class ActivityCodeType(TenantEntity):
    """نوع کد فعالیت — (مثلاً: Phase, Discipline, Location)."""

    name: str = ""
    code: str = ""
    description: str = ""
    scope: str = "global"  # global | project
    project_id: Optional[UUID] = None  # null = global, set = project-specific
    is_active: bool = True
    sort_order: int = 0


@dataclass
class ActivityCodeValue(TenantEntity):
    """مقدار کد فعالیت (مثلاً: Phase=Design, Discipline=Civil)."""

    code_type_id: UUID = field(default_factory=uuid4)
    parent_id: Optional[UUID] = None  # hierarchical
    code: str = ""
    name: str = ""
    description: str = ""
    color: str = ""
    sort_order: int = 0


@dataclass
class TaskActivityCode(TenantEntity):
    """اختصاص مقدار کد فعالیت به تسک."""

    task_id: UUID = field(default_factory=uuid4)
    code_value_id: UUID = field(default_factory=uuid4)


# ═══════════════════════════════════════════════════
# User Defined Field (UDF — EAV)
# ═══════════════════════════════════════════════════

@dataclass
class UDFDefinition(TenantEntity):
    """تعریف فیلد سفارشی (EAV pattern)."""

    name: str = ""
    code: str = ""
    description: str = ""
    field_type: str = "text"  # text, number, date, boolean, select, multi_select
    entity_type: str = "task"  # task, project, resource
    default_value: str = ""
    options: Optional[list] = field(default_factory=list)  # for select/multi_select
    is_required: bool = False
    is_active: bool = True
    sort_order: int = 0


@dataclass
class UDFValue(TenantEntity):
    """مقدار فیلد سفارشی."""

    definition_id: UUID = field(default_factory=uuid4)
    entity_id: UUID = field(default_factory=uuid4)  # task_id, project_id, or resource_id
    entity_type: str = "task"
    value_text: str = ""
    value_number: Optional[Decimal] = None
    value_date: Optional[date] = None
    value_boolean: Optional[bool] = None


# ═══════════════════════════════════════════════════
# Resource Skill & Availability
# ═══════════════════════════════════════════════════

@dataclass
class ResourceSkill(TenantEntity):
    """مهارت منبع."""

    resource_id: UUID = field(default_factory=uuid4)
    skill_name: str = ""
    proficiency_level: int = 1  # 1-5
    notes: str = ""


@dataclass
class ResourceAvailability(TenantEntity):
    """دوره دسترسی منبع."""

    resource_id: UUID = field(default_factory=uuid4)
    start_date: date = field(default_factory=date.today)
    end_date: Optional[date] = None
    available_units: Decimal = Decimal("100")  # درصد
    notes: str = ""


@dataclass
class ResourceCostRate(TenantEntity):
    """جدول نرخ هزینه منبع (بر اساس تاریخ)."""

    resource_id: UUID = field(default_factory=uuid4)
    effective_date: date = field(default_factory=date.today)
    standard_rate: Decimal = Decimal("0")
    overtime_rate: Decimal = Decimal("0")
    cost_per_use: Decimal = Decimal("0")
    notes: str = ""


# ═══════════════════════════════════════════════════
# Cost Breakdown Structure (CBS)
# ═══════════════════════════════════════════════════

@dataclass
class CostAccount(TenantEntity):
    """حساب هزینه — CBS hierarchy."""

    project_id: UUID = field(default_factory=uuid4)
    parent_id: Optional[UUID] = None
    code: str = ""
    name: str = ""
    description: str = ""
    budget_amount: Decimal = Decimal("0")
    actual_amount: Decimal = Decimal("0")
    sort_order: int = 0


@dataclass
class FundingSource(TenantEntity):
    """منبع مالی پروژه."""

    project_id: UUID = field(default_factory=uuid4)
    name: str = ""
    description: str = ""
    total_amount: Decimal = Decimal("0")
    allocated_amount: Decimal = Decimal("0")
    remaining_amount: Decimal = Decimal("0")
    start_date: Optional[date] = None
    end_date: Optional[date] = None
    is_active: bool = True


@dataclass
class CashFlowEntry(TenantEntity):
    """جریان نقدی دوره‌ای."""

    project_id: UUID = field(default_factory=uuid4)
    period_start: date = field(default_factory=date.today)
    period_end: Optional[date] = None
    planned_income: Decimal = Decimal("0")
    planned_expense: Decimal = Decimal("0")
    actual_income: Decimal = Decimal("0")
    actual_expense: Decimal = Decimal("0")
    notes: str = ""


# ═══════════════════════════════════════════════════
# Schedule Health & Reporting
# ═══════════════════════════════════════════════════

@dataclass
class ScheduleHealthSnapshot(TenantEntity):
    """اسنپ‌شات سلامت زمان‌بندی."""

    project_id: UUID = field(default_factory=uuid4)
    snapshot_date: date = field(default_factory=date.today)

    # BEI — Baseline Execution Index
    bei: Optional[Decimal] = None
    # CPLI — Critical Path Length Index
    cpli: Optional[Decimal] = None
    # SPI (EVM)
    spi: Optional[Decimal] = None
    # Tasks on critical path
    critical_tasks_count: int = 0
    total_tasks_count: int = 0
    # Out-of-sequence count
    out_of_sequence_count: int = 0
    # Missing logic (tasks with no predecessors/successors)
    missing_logic_count: int = 0
    # Negative float count
    negative_float_count: int = 0
    # High float tasks (>80 days)
    high_float_count: int = 0

    # Overall health score (0-100)
    health_score: int = 0
    details: Optional[dict] = field(default_factory=dict)


# ═══════════════════════════════════════════════════
# Project Template
# ═══════════════════════════════════════════════════

@dataclass
class ProjectTemplate(TenantEntity):
    """قالب پروژه."""

    name: str = ""
    description: str = ""
    category: str = ""
    template_data: Optional[dict] = field(default_factory=dict)
    is_active: bool = True
    usage_count: int = 0
