"""
PM Application DTOs.

DTO‌های لایه Application برای تبادل داده بین API و Use Case‌ها.
"""
from dataclasses import dataclass, field
from datetime import date, datetime, time
from decimal import Decimal
from typing import Optional, List
from uuid import UUID


# ═══════════════════════════════════════════════════
# Project DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateProjectDTO:
    code: str
    title: str
    tenant_id: UUID
    project_type: str = "project"
    description: str = ""
    parent_id: Optional[UUID] = None
    priority: str = "medium"
    planned_start: Optional[date] = None
    planned_end: Optional[date] = None
    total_budget: Decimal = Decimal("0")
    estimated_cost: Decimal = Decimal("0")
    company_id: Optional[UUID] = None
    org_unit_id: Optional[UUID] = None
    currency_id: Optional[UUID] = None
    manager_id: Optional[UUID] = None
    calendar_id: Optional[UUID] = None
    color: str = "#3B82F6"
    tags: List[str] = field(default_factory=list)
    metadata: dict = field(default_factory=dict)
    created_by: Optional[UUID] = None


@dataclass
class UpdateProjectDTO:
    id: UUID
    title: Optional[str] = None
    description: Optional[str] = None
    project_type: Optional[str] = None
    parent_id: Optional[UUID] = None
    priority: Optional[str] = None
    planned_start: Optional[date] = None
    planned_end: Optional[date] = None
    total_budget: Optional[Decimal] = None
    estimated_cost: Optional[Decimal] = None
    company_id: Optional[UUID] = None
    org_unit_id: Optional[UUID] = None
    currency_id: Optional[UUID] = None
    manager_id: Optional[UUID] = None
    calendar_id: Optional[UUID] = None
    color: Optional[str] = None
    tags: Optional[List[str]] = None
    metadata: Optional[dict] = None
    updated_by: Optional[UUID] = None


@dataclass
class ProjectResponseDTO:
    id: UUID
    code: str
    title: str
    description: str
    project_type: str
    parent_id: Optional[UUID]
    status: str
    priority: str
    planned_start: Optional[date]
    planned_end: Optional[date]
    actual_start: Optional[date]
    actual_end: Optional[date]
    progress: int
    total_budget: Decimal
    actual_cost: Decimal
    estimated_cost: Decimal
    company_id: Optional[UUID]
    org_unit_id: Optional[UUID]
    currency_id: Optional[UUID]
    manager_id: Optional[UUID]
    calendar_id: Optional[UUID]
    color: str
    tags: List[str]
    metadata: dict
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    created_by: Optional[UUID] = None
    updated_by: Optional[UUID] = None
    # Computed
    task_count: int = 0
    completed_task_count: int = 0
    member_count: int = 0
    risk_count: int = 0


# ═══════════════════════════════════════════════════
# Task DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateTaskDTO:
    project_id: UUID
    title: str
    tenant_id: UUID
    code: str = ""
    description: str = ""
    parent_id: Optional[UUID] = None
    task_type: str = "task"
    planned_start: Optional[date] = None
    planned_end: Optional[date] = None
    duration: int = 1
    planned_cost: Decimal = Decimal("0")
    assignee_id: Optional[UUID] = None
    color: str = ""
    tags: List[str] = field(default_factory=list)
    notes: str = ""
    sort_order: Optional[int] = None


@dataclass
class UpdateTaskDTO:
    id: UUID
    title: Optional[str] = None
    description: Optional[str] = None
    parent_id: Optional[UUID] = None
    task_type: Optional[str] = None
    planned_start: Optional[date] = None
    planned_end: Optional[date] = None
    duration: Optional[int] = None
    progress: Optional[int] = None
    planned_cost: Optional[Decimal] = None
    actual_cost: Optional[Decimal] = None
    assignee_id: Optional[UUID] = None
    color: Optional[str] = None
    tags: Optional[List[str]] = None
    notes: Optional[str] = None
    sort_order: Optional[int] = None


@dataclass
class TaskResponseDTO:
    id: UUID
    project_id: UUID
    code: str
    title: str
    description: str
    parent_id: Optional[UUID]
    sort_order: int
    task_type: str
    status: str
    planned_start: Optional[date]
    planned_end: Optional[date]
    actual_start: Optional[date]
    actual_end: Optional[date]
    duration: int
    progress: int
    planned_cost: Decimal
    actual_cost: Decimal
    is_critical: bool
    is_milestone: bool
    early_start: Optional[date]
    early_finish: Optional[date]
    late_start: Optional[date]
    late_finish: Optional[date]
    total_float: Optional[int]
    free_float: Optional[int]
    assignee_id: Optional[UUID]
    color: str
    tags: List[str]
    notes: str
    metadata: dict
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    # Computed
    children_count: int = 0
    resource_count: int = 0


@dataclass
class MoveTaskDTO:
    """انتقال تسک (تغییر والد یا ترتیب)."""
    id: UUID
    parent_id: Optional[UUID] = None
    sort_order: Optional[int] = None


# ═══════════════════════════════════════════════════
# Dependency DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateDependencyDTO:
    project_id: UUID
    predecessor_id: UUID
    successor_id: UUID
    tenant_id: UUID
    dependency_type: str = "FS"
    lag_days: int = 0


@dataclass
class DependencyResponseDTO:
    id: UUID
    project_id: UUID
    predecessor_id: UUID
    successor_id: UUID
    dependency_type: str
    lag_days: int
    created_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Resource DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateResourceDTO:
    name: str
    tenant_id: UUID
    code: str = ""
    resource_type: str = "human"
    employee_id: Optional[UUID] = None
    user_id: Optional[UUID] = None
    company_id: Optional[UUID] = None
    standard_rate: Decimal = Decimal("0")
    overtime_rate: Decimal = Decimal("0")
    cost_per_use: Decimal = Decimal("0")
    currency_id: Optional[UUID] = None
    max_units: Decimal = Decimal("100")
    calendar_id: Optional[UUID] = None
    email: str = ""
    phone: str = ""
    notes: str = ""


@dataclass
class UpdateResourceDTO:
    id: UUID
    name: Optional[str] = None
    code: Optional[str] = None
    resource_type: Optional[str] = None
    standard_rate: Optional[Decimal] = None
    overtime_rate: Optional[Decimal] = None
    cost_per_use: Optional[Decimal] = None
    currency_id: Optional[UUID] = None
    max_units: Optional[Decimal] = None
    calendar_id: Optional[UUID] = None
    email: Optional[str] = None
    phone: Optional[str] = None
    is_active: Optional[bool] = None
    notes: Optional[str] = None


@dataclass
class ResourceResponseDTO:
    id: UUID
    name: str
    code: str
    resource_type: str
    employee_id: Optional[UUID]
    user_id: Optional[UUID]
    company_id: Optional[UUID]
    standard_rate: Decimal
    overtime_rate: Decimal
    cost_per_use: Decimal
    currency_id: Optional[UUID]
    max_units: Decimal
    calendar_id: Optional[UUID]
    email: str
    phone: str
    is_active: bool
    notes: str
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    # Computed
    assignment_count: int = 0


# ═══════════════════════════════════════════════════
# Resource Assignment DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateAssignmentDTO:
    project_id: UUID
    task_id: UUID
    resource_id: UUID
    tenant_id: UUID
    units: Decimal = Decimal("100")
    planned_hours: Decimal = Decimal("0")
    planned_cost: Decimal = Decimal("0")
    start_date: Optional[date] = None
    end_date: Optional[date] = None
    notes: str = ""


@dataclass
class AssignmentResponseDTO:
    id: UUID
    project_id: UUID
    task_id: UUID
    resource_id: UUID
    units: Decimal
    planned_hours: Decimal
    actual_hours: Decimal
    planned_cost: Decimal
    actual_cost: Decimal
    start_date: Optional[date]
    end_date: Optional[date]
    is_active: bool
    notes: str
    created_at: Optional[datetime] = None
    resource_name: str = ""


# ═══════════════════════════════════════════════════
# Cost DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateBudgetDTO:
    project_id: UUID
    name: str
    tenant_id: UUID
    task_id: Optional[UUID] = None
    description: str = ""
    original_budget: Decimal = Decimal("0")
    currency_id: Optional[UUID] = None
    period_start: Optional[date] = None
    period_end: Optional[date] = None
    notes: str = ""


@dataclass
class BudgetResponseDTO:
    id: UUID
    project_id: UUID
    task_id: Optional[UUID]
    name: str
    description: str
    original_budget: Decimal
    revised_budget: Decimal
    committed_cost: Decimal
    actual_cost: Decimal
    currency_id: Optional[UUID]
    period_start: Optional[date]
    period_end: Optional[date]
    is_active: bool
    notes: str
    created_at: Optional[datetime] = None
    variance: Decimal = Decimal("0")


@dataclass
class CreateCostEntryDTO:
    project_id: UUID
    description: str
    amount: Decimal
    tenant_id: UUID
    task_id: Optional[UUID] = None
    resource_id: Optional[UUID] = None
    budget_id: Optional[UUID] = None
    cost_type: str = "variable"
    currency_id: Optional[UUID] = None
    entry_date: Optional[date] = None
    reference_number: str = ""
    notes: str = ""
    created_by: Optional[UUID] = None


@dataclass
class CostEntryResponseDTO:
    id: UUID
    project_id: UUID
    task_id: Optional[UUID]
    resource_id: Optional[UUID]
    budget_id: Optional[UUID]
    description: str
    amount: Decimal
    cost_type: str
    currency_id: Optional[UUID]
    entry_date: Optional[date]
    reference_number: str
    notes: str
    created_at: Optional[datetime] = None
    created_by: Optional[UUID] = None


# ═══════════════════════════════════════════════════
# Risk DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateRiskDTO:
    project_id: UUID
    title: str
    tenant_id: UUID
    code: str = ""
    description: str = ""
    category: str = ""
    probability: str = "medium"
    impact: str = "moderate"
    response_strategy: str = "mitigate"
    response_plan: str = ""
    mitigation_actions: str = ""
    owner_id: Optional[UUID] = None
    cost_impact: Decimal = Decimal("0")
    schedule_impact_days: int = 0
    affected_tasks: List[UUID] = field(default_factory=list)
    identified_date: Optional[date] = None
    due_date: Optional[date] = None


@dataclass
class UpdateRiskDTO:
    id: UUID
    title: Optional[str] = None
    description: Optional[str] = None
    category: Optional[str] = None
    probability: Optional[str] = None
    impact: Optional[str] = None
    status: Optional[str] = None
    response_strategy: Optional[str] = None
    response_plan: Optional[str] = None
    mitigation_actions: Optional[str] = None
    owner_id: Optional[UUID] = None
    cost_impact: Optional[Decimal] = None
    schedule_impact_days: Optional[int] = None
    due_date: Optional[date] = None


@dataclass
class RiskResponseDTO:
    id: UUID
    project_id: UUID
    code: str
    title: str
    description: str
    category: str
    probability: str
    impact: str
    status: str
    response_strategy: str
    response_plan: str
    mitigation_actions: str
    owner_id: Optional[UUID]
    cost_impact: Decimal
    schedule_impact_days: int
    affected_tasks: list
    identified_date: Optional[date]
    due_date: Optional[date]
    closed_date: Optional[date]
    notes: str
    risk_score: int = 0
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Issue DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateIssueDTO:
    project_id: UUID
    title: str
    tenant_id: UUID
    code: str = ""
    description: str = ""
    category: str = "other"
    severity: str = "moderate"
    priority: str = "medium"
    reporter_id: Optional[UUID] = None
    assignee_id: Optional[UUID] = None
    affected_tasks: List[UUID] = field(default_factory=list)
    related_risk_id: Optional[UUID] = None
    impact_description: str = ""
    cost_impact: Decimal = Decimal("0")
    schedule_impact_days: int = 0
    identified_date: Optional[date] = None
    due_date: Optional[date] = None


@dataclass
class UpdateIssueDTO:
    id: UUID
    title: Optional[str] = None
    description: Optional[str] = None
    category: Optional[str] = None
    severity: Optional[str] = None
    priority: Optional[str] = None
    assignee_id: Optional[UUID] = None
    affected_tasks: Optional[list] = None
    related_risk_id: Optional[UUID] = None
    impact_description: Optional[str] = None
    cost_impact: Optional[Decimal] = None
    schedule_impact_days: Optional[int] = None
    due_date: Optional[date] = None
    notes: Optional[str] = None


@dataclass
class IssueResponseDTO:
    id: UUID
    project_id: UUID
    code: str
    title: str
    description: str
    category: str
    severity: str
    priority: str
    status: str
    reporter_id: Optional[UUID]
    assignee_id: Optional[UUID]
    affected_tasks: list
    related_risk_id: Optional[UUID]
    resolution: str
    impact_description: str
    cost_impact: Decimal
    schedule_impact_days: int
    identified_date: Optional[date]
    due_date: Optional[date]
    resolved_date: Optional[date]
    closed_date: Optional[date]
    notes: str
    is_overdue: bool = False
    is_critical: bool = False
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Baseline DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateBaselineDTO:
    project_id: UUID
    name: str
    tenant_id: UUID
    description: str = ""
    baseline_type: str = "initial"
    created_by: Optional[UUID] = None


@dataclass
class BaselineResponseDTO:
    id: UUID
    project_id: UUID
    name: str
    description: str
    baseline_type: str
    is_active: bool
    snapshot_date: Optional[date]
    total_tasks: int
    total_cost: Decimal
    planned_start: Optional[date]
    planned_end: Optional[date]
    created_at: Optional[datetime] = None
    created_by: Optional[UUID] = None


# ═══════════════════════════════════════════════════
# Calendar DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateCalendarDTO:
    name: str
    tenant_id: UUID
    description: str = ""
    is_default: bool = False
    work_start: time = time(8, 0)
    work_end: time = time(17, 0)
    hours_per_day: int = 8
    working_days: List[int] = field(default_factory=lambda: [0, 1, 2, 3, 4])


@dataclass
class CalendarResponseDTO:
    id: UUID
    name: str
    description: str
    is_default: bool
    work_start: time
    work_end: time
    hours_per_day: int
    working_days: List[int]
    created_at: Optional[datetime] = None


@dataclass
class CreateHolidayDTO:
    calendar_id: UUID
    name: str
    holiday_date: date
    tenant_id: UUID
    is_recurring: bool = False
    notes: str = ""


@dataclass
class HolidayResponseDTO:
    id: UUID
    calendar_id: UUID
    name: str
    holiday_date: date
    is_recurring: bool
    notes: str
    created_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Change Request DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateChangeRequestDTO:
    project_id: UUID
    title: str
    tenant_id: UUID
    code: str = ""
    description: str = ""
    justification: str = ""
    priority: str = "medium"
    scope_impact: str = ""
    cost_impact: Decimal = Decimal("0")
    schedule_impact_days: int = 0
    requester_id: Optional[UUID] = None


@dataclass
class ChangeRequestResponseDTO:
    id: UUID
    project_id: UUID
    code: str
    title: str
    description: str
    justification: str
    status: str
    priority: str
    scope_impact: str
    cost_impact: Decimal
    schedule_impact_days: int
    requester_id: Optional[UUID]
    reviewer_id: Optional[UUID]
    workflow_instance_id: Optional[UUID]
    submitted_date: Optional[date]
    decision_date: Optional[date]
    implementation_date: Optional[date]
    decision_notes: str
    created_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Timesheet DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateTimesheetDTO:
    project_id: UUID
    work_date: date
    regular_hours: Decimal
    tenant_id: UUID
    task_id: Optional[UUID] = None
    resource_id: Optional[UUID] = None
    user_id: Optional[UUID] = None
    overtime_hours: Decimal = Decimal("0")
    description: str = ""
    notes: str = ""


@dataclass
class TimesheetResponseDTO:
    id: UUID
    project_id: UUID
    task_id: Optional[UUID]
    resource_id: Optional[UUID]
    user_id: Optional[UUID]
    work_date: date
    regular_hours: Decimal
    overtime_hours: Decimal
    total_hours: Decimal
    description: str
    status: str
    approved_by_id: Optional[UUID]
    approved_date: Optional[date]
    notes: str
    created_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Project Member DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateMemberDTO:
    project_id: UUID
    user_id: UUID
    tenant_id: UUID
    role: str = "member"
    joined_date: Optional[date] = None
    notes: str = ""


@dataclass
class MemberResponseDTO:
    id: UUID
    project_id: UUID
    user_id: UUID
    role: str
    is_active: bool
    joined_date: Optional[date]
    left_date: Optional[date]
    notes: str
    created_at: Optional[datetime] = None
    user_display_name: str = ""


# ═══════════════════════════════════════════════════
# Comment DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateCommentDTO:
    project_id: UUID
    content: str
    user_id: UUID
    tenant_id: UUID
    task_id: Optional[UUID] = None
    parent_id: Optional[UUID] = None
    mentions: List[UUID] = field(default_factory=list)


@dataclass
class CommentResponseDTO:
    id: UUID
    project_id: UUID
    task_id: Optional[UUID]
    user_id: UUID
    content: str
    parent_id: Optional[UUID]
    mentions: list
    is_edited: bool
    is_deleted: bool
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    user_display_name: str = ""
    reply_count: int = 0


# ═══════════════════════════════════════════════════
# Dashboard / Summary DTOs
# ═══════════════════════════════════════════════════

@dataclass
class ProjectDashboardDTO:
    """خلاصه داشبورد پروژه."""
    project: ProjectResponseDTO
    task_summary: dict = field(default_factory=dict)
    cost_summary: dict = field(default_factory=dict)
    risk_summary: dict = field(default_factory=dict)
    evm_data: Optional[dict] = None
    recent_activities: List[dict] = field(default_factory=list)
    milestones: List[TaskResponseDTO] = field(default_factory=list)


@dataclass
class EVMReportDTO:
    """گزارش مدیریت ارزش کسب‌شده."""
    project_id: UUID
    data_date: date
    pv: Decimal = Decimal("0")
    ev: Decimal = Decimal("0")
    ac: Decimal = Decimal("0")
    cv: Decimal = Decimal("0")
    sv: Decimal = Decimal("0")
    cpi: Decimal = Decimal("0")
    spi: Decimal = Decimal("0")
    eac: Decimal = Decimal("0")
    etc: Decimal = Decimal("0")
    vac: Decimal = Decimal("0")
    tcpi: Decimal = Decimal("0")
    s_curve_data: List[dict] = field(default_factory=list)


# ═══════════════════════════════════════════════════
# Activity Code DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateActivityCodeTypeDTO:
    name: str
    code: str
    tenant_id: UUID
    description: str = ""
    scope: str = "global"
    project_id: Optional[UUID] = None
    sort_order: int = 0


@dataclass
class UpdateActivityCodeTypeDTO:
    id: UUID
    name: Optional[str] = None
    description: Optional[str] = None
    is_active: Optional[bool] = None
    sort_order: Optional[int] = None


@dataclass
class ActivityCodeTypeResponseDTO:
    id: UUID
    name: str
    code: str
    description: str
    scope: str
    project_id: Optional[UUID]
    is_active: bool
    sort_order: int
    created_at: Optional[datetime] = None
    value_count: int = 0


@dataclass
class CreateActivityCodeValueDTO:
    code_type_id: UUID
    code: str
    name: str
    tenant_id: UUID
    parent_id: Optional[UUID] = None
    description: str = ""
    color: str = ""
    sort_order: int = 0


@dataclass
class ActivityCodeValueResponseDTO:
    id: UUID
    code_type_id: UUID
    parent_id: Optional[UUID]
    code: str
    name: str
    description: str
    color: str
    sort_order: int
    created_at: Optional[datetime] = None


@dataclass
class TaskActivityCodeResponseDTO:
    id: UUID
    task_id: UUID
    code_value_id: UUID
    code_type_name: str = ""
    code_value_name: str = ""
    created_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# UDF DTOs (User Defined Fields)
# ═══════════════════════════════════════════════════

@dataclass
class CreateUDFDefinitionDTO:
    name: str
    code: str
    field_type: str
    entity_type: str
    tenant_id: UUID
    description: str = ""
    default_value: str = ""
    options: list = field(default_factory=list)
    is_required: bool = False
    sort_order: int = 0


@dataclass
class UpdateUDFDefinitionDTO:
    id: UUID
    name: Optional[str] = None
    description: Optional[str] = None
    default_value: Optional[str] = None
    options: Optional[list] = None
    is_required: Optional[bool] = None
    is_active: Optional[bool] = None
    sort_order: Optional[int] = None


@dataclass
class UDFDefinitionResponseDTO:
    id: UUID
    name: str
    code: str
    description: str
    field_type: str
    entity_type: str
    default_value: str
    options: list
    is_required: bool
    is_active: bool
    sort_order: int
    created_at: Optional[datetime] = None


@dataclass
class SetUDFValueDTO:
    definition_id: UUID
    entity_id: UUID
    entity_type: str
    tenant_id: UUID
    value_text: str = ""
    value_number: Optional[Decimal] = None
    value_date: Optional[date] = None
    value_boolean: Optional[bool] = None


@dataclass
class UDFValueResponseDTO:
    id: UUID
    definition_id: UUID
    entity_id: UUID
    entity_type: str
    value_text: str
    value_number: Optional[Decimal]
    value_date: Optional[date]
    value_boolean: Optional[bool]
    definition_name: str = ""
    definition_code: str = ""
    created_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Advanced Resource DTOs (Skill, Availability, Cost Rate)
# ═══════════════════════════════════════════════════

@dataclass
class CreateResourceSkillDTO:
    resource_id: UUID
    skill_name: str
    tenant_id: UUID
    proficiency_level: int = 1
    notes: str = ""


@dataclass
class ResourceSkillResponseDTO:
    id: UUID
    resource_id: UUID
    skill_name: str
    proficiency_level: int
    notes: str
    created_at: Optional[datetime] = None


@dataclass
class CreateResourceAvailabilityDTO:
    resource_id: UUID
    start_date: date
    tenant_id: UUID
    end_date: Optional[date] = None
    available_units: Decimal = Decimal("100")
    notes: str = ""


@dataclass
class ResourceAvailabilityResponseDTO:
    id: UUID
    resource_id: UUID
    start_date: date
    end_date: Optional[date]
    available_units: Decimal
    notes: str
    created_at: Optional[datetime] = None


@dataclass
class CreateResourceCostRateDTO:
    resource_id: UUID
    effective_date: date
    tenant_id: UUID
    standard_rate: Decimal = Decimal("0")
    overtime_rate: Decimal = Decimal("0")
    cost_per_use: Decimal = Decimal("0")
    notes: str = ""


@dataclass
class ResourceCostRateResponseDTO:
    id: UUID
    resource_id: UUID
    effective_date: date
    standard_rate: Decimal
    overtime_rate: Decimal
    cost_per_use: Decimal
    notes: str
    created_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Cost Account DTOs (CBS)
# ═══════════════════════════════════════════════════

@dataclass
class CreateCostAccountDTO:
    project_id: UUID
    code: str
    name: str
    tenant_id: UUID
    parent_id: Optional[UUID] = None
    description: str = ""
    budget_amount: Decimal = Decimal("0")
    sort_order: int = 0


@dataclass
class UpdateCostAccountDTO:
    id: UUID
    name: Optional[str] = None
    description: Optional[str] = None
    budget_amount: Optional[Decimal] = None
    actual_amount: Optional[Decimal] = None
    sort_order: Optional[int] = None


@dataclass
class CostAccountResponseDTO:
    id: UUID
    project_id: UUID
    parent_id: Optional[UUID]
    code: str
    name: str
    description: str
    budget_amount: Decimal
    actual_amount: Decimal
    sort_order: int
    created_at: Optional[datetime] = None
    variance: Decimal = Decimal("0")


# ═══════════════════════════════════════════════════
# Funding Source DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateFundingSourceDTO:
    project_id: UUID
    name: str
    tenant_id: UUID
    description: str = ""
    total_amount: Decimal = Decimal("0")
    start_date: Optional[date] = None
    end_date: Optional[date] = None


@dataclass
class UpdateFundingSourceDTO:
    id: UUID
    name: Optional[str] = None
    description: Optional[str] = None
    total_amount: Optional[Decimal] = None
    allocated_amount: Optional[Decimal] = None
    start_date: Optional[date] = None
    end_date: Optional[date] = None
    is_active: Optional[bool] = None


@dataclass
class FundingSourceResponseDTO:
    id: UUID
    project_id: UUID
    name: str
    description: str
    total_amount: Decimal
    allocated_amount: Decimal
    remaining_amount: Decimal
    start_date: Optional[date]
    end_date: Optional[date]
    is_active: bool
    created_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Cash Flow DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateCashFlowEntryDTO:
    project_id: UUID
    period_start: date
    tenant_id: UUID
    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 = ""


@dataclass
class UpdateCashFlowEntryDTO:
    id: UUID
    planned_income: Optional[Decimal] = None
    planned_expense: Optional[Decimal] = None
    actual_income: Optional[Decimal] = None
    actual_expense: Optional[Decimal] = None
    notes: Optional[str] = None


@dataclass
class CashFlowEntryResponseDTO:
    id: UUID
    project_id: UUID
    period_start: date
    period_end: Optional[date]
    planned_income: Decimal
    planned_expense: Decimal
    actual_income: Decimal
    actual_expense: Decimal
    notes: str
    created_at: Optional[datetime] = None
    net_planned: Decimal = Decimal("0")
    net_actual: Decimal = Decimal("0")


# ═══════════════════════════════════════════════════
# Schedule Health DTOs
# ═══════════════════════════════════════════════════

@dataclass
class ScheduleHealthSnapshotResponseDTO:
    id: UUID
    project_id: UUID
    snapshot_date: date
    health_score: int
    bei: Optional[Decimal]
    cpli: Optional[Decimal]
    spi: Optional[Decimal]
    critical_tasks_count: int
    total_tasks_count: int
    out_of_sequence_count: int
    missing_logic_count: int
    negative_float_count: int
    high_float_count: int
    details: dict
    created_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Project Template DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateProjectTemplateDTO:
    name: str
    tenant_id: UUID
    description: str = ""
    category: str = ""
    template_data: dict = field(default_factory=dict)


@dataclass
class UpdateProjectTemplateDTO:
    id: UUID
    name: Optional[str] = None
    description: Optional[str] = None
    category: Optional[str] = None
    template_data: Optional[dict] = None
    is_active: Optional[bool] = None


@dataclass
class ProjectTemplateResponseDTO:
    id: UUID
    name: str
    description: str
    category: str
    template_data: dict
    is_active: bool
    usage_count: int
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


@dataclass
class SaveProjectAsTemplateDTO:
    project_id: UUID
    name: str
    tenant_id: UUID
    description: str = ""


# ═══════════════════════════════════════════════════
# Monte Carlo Simulation DTOs
# ═══════════════════════════════════════════════════

@dataclass
class TaskEstimateDTO:
    task_id: UUID
    optimistic: float
    most_likely: float
    pessimistic: float


@dataclass
class RunMonteCarloDTO:
    project_id: UUID
    estimates: List[TaskEstimateDTO]
    tenant_id: UUID
    iterations: int = 1000


@dataclass
class MonteCarloResultDTO:
    mean: float
    std_dev: float
    p50: float
    p80: float
    p90: float
    p95: float
    histogram: List[dict]
    confidence_range: dict


# ═══════════════════════════════════════════════════
# Resource Leveling DTOs
# ═══════════════════════════════════════════════════

@dataclass
class RunResourceLevelingDTO:
    project_id: UUID
    tenant_id: UUID
    apply_results: bool = False


@dataclass
class ResourceLevelingResultDTO:
    leveled_tasks: dict
    overallocated_resources: list
    iterations: int
    success: bool
    tasks_updated: int = 0


# ═══════════════════════════════════════════════════
# OBS Node DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateOBSNodeDTO:
    project_id: UUID
    code: str
    name: str
    tenant_id: UUID
    parent_id: Optional[UUID] = None
    description: str = ""
    node_type: str = "department"
    level: int = 0
    manager_id: Optional[UUID] = None
    org_unit_id: Optional[UUID] = None
    responsibilities: str = ""
    sort_order: int = 0
    metadata: Optional[dict] = None


@dataclass
class UpdateOBSNodeDTO:
    id: UUID
    name: Optional[str] = None
    description: Optional[str] = None
    node_type: Optional[str] = None
    parent_id: Optional[UUID] = None
    level: Optional[int] = None
    manager_id: Optional[UUID] = None
    org_unit_id: Optional[UUID] = None
    responsibilities: Optional[str] = None
    is_active: Optional[bool] = None
    sort_order: Optional[int] = None
    metadata: Optional[dict] = None


@dataclass
class OBSNodeResponseDTO:
    id: UUID
    project_id: UUID
    parent_id: Optional[UUID]
    code: str
    name: str
    description: str
    node_type: str
    level: int
    manager_id: Optional[UUID]
    org_unit_id: Optional[UUID]
    responsibilities: str
    is_active: bool
    sort_order: int
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# RBS Node DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateRBSNodeDTO:
    project_id: UUID
    code: str
    name: str
    tenant_id: UUID
    parent_id: Optional[UUID] = None
    description: str = ""
    node_type: str = "category"
    level: int = 0
    resource_type: str = ""
    unit: str = ""
    default_rate: float = 0.0
    sort_order: int = 0
    metadata: Optional[dict] = None


@dataclass
class UpdateRBSNodeDTO:
    id: UUID
    name: Optional[str] = None
    description: Optional[str] = None
    node_type: Optional[str] = None
    parent_id: Optional[UUID] = None
    level: Optional[int] = None
    resource_type: Optional[str] = None
    unit: Optional[str] = None
    default_rate: Optional[float] = None
    is_active: Optional[bool] = None
    sort_order: Optional[int] = None
    metadata: Optional[dict] = None


@dataclass
class RBSNodeResponseDTO:
    id: UUID
    project_id: UUID
    parent_id: Optional[UUID]
    code: str
    name: str
    description: str
    node_type: str
    level: int
    resource_type: str
    unit: str
    default_rate: float
    is_active: bool
    sort_order: int
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Quality Plan DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateQualityPlanDTO:
    project_id: UUID
    name: str
    tenant_id: UUID
    description: str = ""
    status: str = "draft"
    criteria: str = ""
    standards: str = ""
    objectives: str = ""
    scope: str = ""
    quality_manager_id: Optional[UUID] = None
    effective_date: Optional[date] = None
    review_date: Optional[date] = None
    version: str = "1.0"
    notes: str = ""
    metadata: Optional[dict] = None


@dataclass
class UpdateQualityPlanDTO:
    id: UUID
    name: Optional[str] = None
    description: Optional[str] = None
    status: Optional[str] = None
    criteria: Optional[str] = None
    standards: Optional[str] = None
    objectives: Optional[str] = None
    scope: Optional[str] = None
    quality_manager_id: Optional[UUID] = None
    effective_date: Optional[date] = None
    review_date: Optional[date] = None
    version: Optional[str] = None
    notes: Optional[str] = None
    metadata: Optional[dict] = None


@dataclass
class QualityPlanResponseDTO:
    id: UUID
    project_id: UUID
    name: str
    description: str
    status: str
    criteria: str
    standards: str
    objectives: str
    scope: str
    quality_manager_id: Optional[UUID]
    effective_date: Optional[date]
    review_date: Optional[date]
    version: str
    notes: str
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Inspection DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateInspectionDTO:
    project_id: UUID
    code: str
    title: str
    tenant_id: UUID
    description: str = ""
    inspection_type: str = "quality_audit"
    status: str = "planned"
    result: str = "na"
    quality_plan_id: Optional[UUID] = None
    task_id: Optional[UUID] = None
    inspector_id: Optional[UUID] = None
    findings: str = ""
    recommendations: str = ""
    planned_date: Optional[date] = None
    actual_date: Optional[date] = None
    notes: str = ""
    metadata: Optional[dict] = None


@dataclass
class UpdateInspectionDTO:
    id: UUID
    title: Optional[str] = None
    description: Optional[str] = None
    inspection_type: Optional[str] = None
    status: Optional[str] = None
    result: Optional[str] = None
    quality_plan_id: Optional[UUID] = None
    task_id: Optional[UUID] = None
    inspector_id: Optional[UUID] = None
    findings: Optional[str] = None
    recommendations: Optional[str] = None
    planned_date: Optional[date] = None
    actual_date: Optional[date] = None
    notes: Optional[str] = None
    metadata: Optional[dict] = None


@dataclass
class InspectionResponseDTO:
    id: UUID
    project_id: UUID
    code: str
    title: str
    description: str
    inspection_type: str
    status: str
    result: str
    quality_plan_id: Optional[UUID]
    task_id: Optional[UUID]
    inspector_id: Optional[UUID]
    findings: str
    recommendations: str
    planned_date: Optional[date]
    actual_date: Optional[date]
    notes: str
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# NCR DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateNCRDTO:
    project_id: UUID
    code: str
    title: str
    tenant_id: UUID
    description: str = ""
    severity: str = "minor"
    status: str = "open"
    inspection_id: Optional[UUID] = None
    task_id: Optional[UUID] = None
    reported_by_id: Optional[UUID] = None
    assigned_to_id: Optional[UUID] = None
    root_cause: str = ""
    corrective_action: str = ""
    preventive_action: str = ""
    cost_impact: float = 0.0
    schedule_impact_days: int = 0
    identified_date: Optional[date] = None
    due_date: Optional[date] = None
    notes: str = ""
    metadata: Optional[dict] = None


@dataclass
class UpdateNCRDTO:
    id: UUID
    title: Optional[str] = None
    description: Optional[str] = None
    severity: Optional[str] = None
    status: Optional[str] = None
    inspection_id: Optional[UUID] = None
    task_id: Optional[UUID] = None
    assigned_to_id: Optional[UUID] = None
    root_cause: Optional[str] = None
    corrective_action: Optional[str] = None
    preventive_action: Optional[str] = None
    cost_impact: Optional[float] = None
    schedule_impact_days: Optional[int] = None
    due_date: Optional[date] = None
    resolved_date: Optional[date] = None
    closed_date: Optional[date] = None
    notes: Optional[str] = None
    metadata: Optional[dict] = None


@dataclass
class NCRResponseDTO:
    id: UUID
    project_id: UUID
    code: str
    title: str
    description: str
    severity: str
    status: str
    inspection_id: Optional[UUID]
    task_id: Optional[UUID]
    reported_by_id: Optional[UUID]
    assigned_to_id: Optional[UUID]
    root_cause: str
    corrective_action: str
    preventive_action: str
    cost_impact: float
    schedule_impact_days: int
    identified_date: Optional[date]
    due_date: Optional[date]
    resolved_date: Optional[date]
    closed_date: Optional[date]
    notes: str
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Quality Checklist DTOs
# ═══════════════════════════════════════════════════

@dataclass
class CreateQualityChecklistDTO:
    project_id: UUID
    name: str
    tenant_id: UUID
    description: str = ""
    quality_plan_id: Optional[UUID] = None
    task_id: Optional[UUID] = None
    notes: str = ""
    metadata: Optional[dict] = None


@dataclass
class UpdateQualityChecklistDTO:
    id: UUID
    name: Optional[str] = None
    description: Optional[str] = None
    quality_plan_id: Optional[UUID] = None
    task_id: Optional[UUID] = None
    is_completed: Optional[bool] = None
    completed_by_id: Optional[UUID] = None
    notes: Optional[str] = None
    metadata: Optional[dict] = None


@dataclass
class QualityChecklistResponseDTO:
    id: UUID
    project_id: UUID
    name: str
    description: str
    quality_plan_id: Optional[UUID]
    task_id: Optional[UUID]
    is_completed: bool
    completed_date: Optional[datetime]
    completed_by_id: Optional[UUID]
    notes: str
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


@dataclass
class CreateQualityChecklistItemDTO:
    checklist_id: UUID
    title: str
    tenant_id: UUID
    description: str = ""
    sort_order: int = 0
    metadata: Optional[dict] = None


@dataclass
class UpdateQualityChecklistItemDTO:
    id: UUID
    title: Optional[str] = None
    description: Optional[str] = None
    sort_order: Optional[int] = None
    is_checked: Optional[bool] = None
    checked_by_id: Optional[UUID] = None
    result: Optional[str] = None
    remarks: Optional[str] = None


@dataclass
class QualityChecklistItemResponseDTO:
    id: UUID
    checklist_id: UUID
    title: str
    description: str
    sort_order: int
    is_checked: bool
    checked_by_id: Optional[UUID]
    checked_date: Optional[datetime]
    result: str
    remarks: str
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


# ═══════════════════════════════════════════════════
# Project Document DTOs
# ═══════════════════════════════════════════════════

@dataclass
class ProjectDocumentCreateDTO:
    project_id: UUID
    document_id: UUID
    entity_type: str = "project"
    entity_id: Optional[UUID] = None
    title: str = ""
    document_code: str = ""
    notes: str = ""


@dataclass
class ProjectDocumentResponseDTO:
    id: UUID
    project_id: UUID
    document_id: UUID
    entity_type: str
    entity_id: Optional[UUID]
    title: str
    document_code: str
    linked_by: Optional[UUID]
    notes: str
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
