"""
PM API Serializers.

سریالایزرهای DRF ماژول مدیریت پروژه.
"""
from rest_framework import serializers
from ...infrastructure.persistence.models import (
    ProjectModel,
    TaskModel,
    DependencyModel,
    ResourceModel,
    ResourceAssignmentModel,
    BudgetModel,
    CostEntryModel,
    RiskModel,
    BaselineModel,
    CalendarModel,
    HolidayModel,
    ChangeRequestModel,
    TimesheetModel,
    ProjectMemberModel,
    CommentModel,
    ActivityLogModel,
    TaskLabelModel,
    TaskLabelAssignmentModel,
    TaskAttachmentModel,
    TaskChecklistModel,
    TaskChecklistItemModel,
    RACIAssignmentModel,
    TaskAssignmentModel,
    ActivityCodeTypeModel,
    ActivityCodeValueModel,
    TaskActivityCodeModel,
    UDFDefinitionModel,
    UDFValueModel,
    ResourceSkillModel,
    ResourceAvailabilityModel,
    ResourceCostRateModel,
    CostAccountModel,
    FundingSourceModel,
    CashFlowEntryModel,
    ScheduleHealthSnapshotModel,
    ProjectTemplateModel,
    IssueModel,
    OBSNodeModel,
    RBSNodeModel,
    QualityPlanModel,
    InspectionModel,
    NCRModel,
    QualityChecklistModel,
    QualityChecklistItemModel,
    ProjectDocumentModel,
)


# ═══════════════════════════════════════════════════
# Project Serializers
# ═══════════════════════════════════════════════════

class ProjectListSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProjectModel
        fields = [
            "id", "code", "title", "project_type", "status", "priority",
            "planned_start", "planned_end", "progress", "total_budget",
            "actual_cost", "manager", "company", "color", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class ProjectDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProjectModel
        fields = "__all__"
        read_only_fields = ["id", "tenant", "created_at", "updated_at"]


class ProjectCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProjectModel
        fields = [
            "id", "code", "title", "description", "project_type", "parent",
            "priority", "planned_start", "planned_end",
            "total_budget", "estimated_cost",
            "company", "org_unit", "currency", "manager", "calendar",
            "color", "tags", "metadata",
        ]
        read_only_fields = ["id"]


class ProjectStatusSerializer(serializers.Serializer):
    status = serializers.ChoiceField(choices=ProjectModel.Status.choices)


# ═══════════════════════════════════════════════════
# Task Serializers
# ═══════════════════════════════════════════════════

class TaskListSerializer(serializers.ModelSerializer):
    project_title = serializers.CharField(source="project.title", read_only=True, default="")
    assignee_name = serializers.SerializerMethodField()
    responsible = serializers.SerializerMethodField()
    accountable = serializers.SerializerMethodField()
    consulted = serializers.SerializerMethodField()
    informed = serializers.SerializerMethodField()

    class Meta:
        model = TaskModel
        fields = [
            "id", "project", "project_title", "code", "title", "parent", "sort_order",
            "task_type", "status", "planned_start", "planned_end",
            "duration", "progress", "is_critical", "is_milestone",
            "assignee", "assignee_name",
            "responsible", "accountable", "consulted", "informed",
            "color", "created_at",
        ]
        read_only_fields = ["id", "created_at"]

    def get_assignee_name(self, obj):
        if obj.assignee:
            return obj.assignee.get_full_name() or obj.assignee.email
        return ""

    def _get_raci_names(self, obj, role):
        """نام کاربران با نقش RACI مشخص برای تسک."""
        if not hasattr(obj, "_prefetched_raci"):
            # fallback — اگر prefetch نشده بود
            assignments = obj.raci_assignments.filter(role=role).select_related("user")
        else:
            assignments = [a for a in obj._prefetched_raci if a.role == role]
        names = []
        for a in assignments:
            if a.user:
                name = (
                    a.user.get_full_name()
                    or getattr(a.user, "display_name", "")
                    or a.user.email
                )
                names.append(name)
        return ", ".join(names)

    def get_responsible(self, obj):
        return self._get_raci_names(obj, "R")

    def get_accountable(self, obj):
        return self._get_raci_names(obj, "A")

    def get_consulted(self, obj):
        return self._get_raci_names(obj, "C")

    def get_informed(self, obj):
        return self._get_raci_names(obj, "I")


class TaskDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskModel
        fields = "__all__"
        read_only_fields = ["id", "tenant", "created_at", "updated_at"]


class TaskCreateSerializer(serializers.ModelSerializer):
    code = serializers.CharField(required=False, allow_blank=True, default="")

    class Meta:
        model = TaskModel
        fields = [
            "id", "project", "code", "title", "description", "parent",
            "sort_order", "task_type", "planned_start", "planned_end",
            "duration", "planned_cost", "assignee",
            "color", "tags", "notes",
        ]
        read_only_fields = ["id"]


class TaskUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskModel
        fields = [
            "title", "description", "parent", "sort_order", "task_type",
            "status", "priority", "weight",
            "planned_start", "planned_end", "actual_start", "actual_end",
            "duration", "progress",
            "planned_cost", "actual_cost", "assignee",
            "color", "tags", "notes",
        ]


class TaskStatusSerializer(serializers.Serializer):
    status = serializers.ChoiceField(choices=TaskModel.Status.choices)


class TaskMoveSerializer(serializers.Serializer):
    parent_id = serializers.UUIDField(required=False, allow_null=True)
    sort_order = serializers.IntegerField(required=False)


class TaskProgressSerializer(serializers.Serializer):
    """سریالایزر ثبت پیشرفت تسک."""
    progress = serializers.IntegerField(min_value=0, max_value=100)
    notes = serializers.CharField(required=False, allow_blank=True, default="")


# ═══════════════════════════════════════════════════
# Dependency Serializers
# ═══════════════════════════════════════════════════

class DependencySerializer(serializers.ModelSerializer):
    predecessor_title = serializers.CharField(
        source="predecessor.title", read_only=True, default=None,
    )
    successor_title = serializers.CharField(
        source="successor.title", read_only=True, default=None,
    )

    class Meta:
        model = DependencyModel
        fields = [
            "id", "project", "predecessor", "predecessor_title",
            "successor", "successor_title",
            "dependency_type", "lag_days", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class DependencyCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = DependencyModel
        fields = ["project", "predecessor", "successor", "dependency_type", "lag_days"]


# ═══════════════════════════════════════════════════
# Resource Serializers
# ═══════════════════════════════════════════════════

class ResourceListSerializer(serializers.ModelSerializer):
    class Meta:
        model = ResourceModel
        fields = [
            "id", "name", "code", "resource_type", "user", "company",
            "standard_rate", "max_units", "is_active", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class ResourceDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = ResourceModel
        fields = "__all__"
        read_only_fields = ["id", "tenant", "created_at", "updated_at"]


class ResourceCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ResourceModel
        fields = [
            "name", "code", "resource_type", "employee_id", "user", "company",
            "standard_rate", "overtime_rate", "cost_per_use", "currency",
            "max_units", "calendar", "email", "phone", "notes",
        ]


# ═══════════════════════════════════════════════════
# Resource Assignment Serializers
# ═══════════════════════════════════════════════════

class AssignmentSerializer(serializers.ModelSerializer):
    resource_name = serializers.CharField(source="resource.name", read_only=True)

    class Meta:
        model = ResourceAssignmentModel
        fields = [
            "id", "project", "task", "resource", "resource_name",
            "units", "planned_hours", "actual_hours",
            "planned_cost", "actual_cost",
            "start_date", "end_date", "is_active", "notes",
            "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class AssignmentCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ResourceAssignmentModel
        fields = [
            "project", "task", "resource", "units",
            "planned_hours", "planned_cost", "start_date", "end_date", "notes",
        ]


# ═══════════════════════════════════════════════════
# Budget & Cost Serializers
# ═══════════════════════════════════════════════════

class BudgetSerializer(serializers.ModelSerializer):
    variance = serializers.SerializerMethodField()

    class Meta:
        model = BudgetModel
        fields = [
            "id", "project", "task", "name", "description",
            "original_budget", "revised_budget", "committed_cost", "actual_cost",
            "currency", "period_start", "period_end", "is_active", "notes",
            "variance", "created_at",
        ]
        read_only_fields = ["id", "created_at"]

    def get_variance(self, obj):
        return obj.revised_budget - obj.actual_cost


class BudgetCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = BudgetModel
        fields = [
            "project", "task", "name", "description",
            "original_budget", "currency", "period_start", "period_end", "notes",
        ]


class CostEntrySerializer(serializers.ModelSerializer):
    class Meta:
        model = CostEntryModel
        fields = [
            "id", "project", "task", "resource", "budget",
            "description", "amount", "cost_type", "currency",
            "entry_date", "reference_number", "notes",
            "created_at", "created_by",
        ]
        read_only_fields = ["id", "created_at"]


class CostEntryCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = CostEntryModel
        fields = [
            "project", "task", "resource", "budget",
            "description", "amount", "cost_type", "currency",
            "entry_date", "reference_number", "notes",
        ]


# ═══════════════════════════════════════════════════
# Risk Serializers
# ═══════════════════════════════════════════════════

class RiskListSerializer(serializers.ModelSerializer):
    risk_score = serializers.IntegerField(read_only=True)

    class Meta:
        model = RiskModel
        fields = [
            "id", "project", "code", "title", "category",
            "probability", "impact", "status",
            "response_strategy", "owner", "risk_score",
            "cost_impact", "schedule_impact_days",
            "identified_date", "due_date", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class RiskDetailSerializer(serializers.ModelSerializer):
    risk_score = serializers.IntegerField(read_only=True)

    class Meta:
        model = RiskModel
        fields = "__all__"
        read_only_fields = ["id", "tenant", "created_at", "updated_at"]


class RiskCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = RiskModel
        fields = [
            "project", "code", "title", "description", "category",
            "probability", "impact", "response_strategy",
            "response_plan", "mitigation_actions", "owner",
            "cost_impact", "schedule_impact_days", "affected_tasks",
            "identified_date", "due_date",
        ]


# ═══════════════════════════════════════════════════
# Baseline Serializers
# ═══════════════════════════════════════════════════

class BaselineSerializer(serializers.ModelSerializer):
    class Meta:
        model = BaselineModel
        fields = [
            "id", "project", "name", "description", "baseline_type",
            "is_active", "snapshot_date", "total_tasks", "total_cost",
            "planned_start", "planned_end", "created_at", "created_by",
        ]
        read_only_fields = ["id", "created_at", "snapshot_date"]


class BaselineCreateSerializer(serializers.Serializer):
    project = serializers.UUIDField()
    name = serializers.CharField(max_length=255)
    description = serializers.CharField(required=False, default="")
    baseline_type = serializers.ChoiceField(
        choices=BaselineModel.BaselineType.choices,
        default="initial",
    )


# ═══════════════════════════════════════════════════
# Calendar & Holiday Serializers
# ═══════════════════════════════════════════════════

class CalendarSerializer(serializers.ModelSerializer):
    class Meta:
        model = CalendarModel
        fields = [
            "id", "name", "description", "is_default",
            "work_start", "work_end", "hours_per_day",
            "working_days", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class HolidaySerializer(serializers.ModelSerializer):
    class Meta:
        model = HolidayModel
        fields = [
            "id", "calendar", "name", "holiday_date",
            "is_recurring", "notes", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


# ═══════════════════════════════════════════════════
# Change Request Serializers
# ═══════════════════════════════════════════════════

class ChangeRequestListSerializer(serializers.ModelSerializer):
    class Meta:
        model = ChangeRequestModel
        fields = [
            "id", "project", "code", "title", "status", "priority",
            "cost_impact", "schedule_impact_days",
            "requester", "submitted_date", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class ChangeRequestDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = ChangeRequestModel
        fields = "__all__"
        read_only_fields = ["id", "tenant", "created_at", "updated_at"]


class ChangeRequestCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ChangeRequestModel
        fields = [
            "project", "code", "title", "description", "justification",
            "priority", "scope_impact", "cost_impact", "schedule_impact_days",
        ]


# ═══════════════════════════════════════════════════
# Timesheet Serializers
# ═══════════════════════════════════════════════════

class TimesheetSerializer(serializers.ModelSerializer):
    total_hours = serializers.DecimalField(
        max_digits=5, decimal_places=2, read_only=True,
    )

    class Meta:
        model = TimesheetModel
        fields = [
            "id", "project", "task", "resource", "user",
            "work_date", "regular_hours", "overtime_hours", "total_hours",
            "description", "status", "approved_by", "approved_date",
            "notes", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class TimesheetCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = TimesheetModel
        fields = [
            "project", "task", "resource", "work_date",
            "regular_hours", "overtime_hours", "description", "notes",
        ]


# ═══════════════════════════════════════════════════
# Project Member Serializers
# ═══════════════════════════════════════════════════

class MemberSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProjectMemberModel
        fields = [
            "id", "project", "user", "role", "is_active",
            "joined_date", "left_date", "notes", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class MemberCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProjectMemberModel
        fields = ["project", "user", "role", "joined_date", "notes"]


# ═══════════════════════════════════════════════════
# Comment Serializers
# ═══════════════════════════════════════════════════

class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = CommentModel
        fields = [
            "id", "project", "task", "user", "content",
            "parent", "mentions", "is_edited", "is_deleted",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class CommentCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = CommentModel
        fields = ["project", "task", "content", "parent", "mentions"]


# ═══════════════════════════════════════════════════
# Activity Log Serializer
# ═══════════════════════════════════════════════════

class ActivityLogSerializer(serializers.ModelSerializer):
    class Meta:
        model = ActivityLogModel
        fields = [
            "id", "project", "task", "user", "action",
            "entity_type", "entity_id", "description",
            "changes", "ip_address", "created_at",
        ]
        read_only_fields = fields


# ═══════════════════════════════════════════════════
# Task Label Serializers (Kanban)
# ═══════════════════════════════════════════════════

class TaskLabelSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskLabelModel
        fields = [
            "id", "project", "name", "color", "description",
            "sort_order", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class TaskLabelCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskLabelModel
        fields = ["project", "name", "color", "description", "sort_order"]


class TaskLabelAssignmentSerializer(serializers.ModelSerializer):
    label_name = serializers.CharField(source="label.name", read_only=True)
    label_color = serializers.CharField(source="label.color", read_only=True)

    class Meta:
        model = TaskLabelAssignmentModel
        fields = ["id", "task", "label", "label_name", "label_color", "created_at"]
        read_only_fields = ["id", "created_at"]


class TaskLabelAssignmentCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskLabelAssignmentModel
        fields = ["task", "label"]


# ═══════════════════════════════════════════════════
# Task Attachment Serializers (Kanban)
# ═══════════════════════════════════════════════════

class TaskAttachmentSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskAttachmentModel
        fields = [
            "id", "task", "file_name", "file_url", "file_size",
            "mime_type", "uploaded_by", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class TaskAttachmentCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskAttachmentModel
        fields = ["task", "file_name", "file_url", "file_size", "mime_type"]


# ═══════════════════════════════════════════════════
# Task Checklist Serializers (Kanban)
# ═══════════════════════════════════════════════════

class TaskChecklistItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskChecklistItemModel
        fields = [
            "id", "checklist", "title", "is_checked", "assignee",
            "due_date", "sort_order", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class TaskChecklistItemCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskChecklistItemModel
        fields = ["checklist", "title", "assignee", "due_date", "sort_order"]


class TaskChecklistSerializer(serializers.ModelSerializer):
    items = TaskChecklistItemSerializer(many=True, read_only=True)
    progress = serializers.IntegerField(read_only=True)

    class Meta:
        model = TaskChecklistModel
        fields = [
            "id", "task", "title", "sort_order",
            "items", "progress", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class TaskChecklistCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskChecklistModel
        fields = ["task", "title", "sort_order"]


# ═══════════════════════════════════════════════════
# RACI Assignment Serializers
# ═══════════════════════════════════════════════════

class RACIAssignmentSerializer(serializers.ModelSerializer):
    role_display = serializers.CharField(source="get_role_display", read_only=True)
    user_name = serializers.CharField(source="user.get_full_name", read_only=True, default=None)
    resource_name = serializers.CharField(source="resource.name", read_only=True, default=None)
    task_title = serializers.CharField(source="task.title", read_only=True, default=None)

    class Meta:
        model = RACIAssignmentModel
        fields = [
            "id", "project", "task", "task_title", "user", "user_name",
            "resource", "resource_name", "role", "role_display", "notes",
            "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class RACIAssignmentCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = RACIAssignmentModel
        fields = ["project", "task", "user", "resource", "role", "notes"]


# ═══════════════════════════════════════════════════
# Kanban Board Serializer (Composite)
# ═══════════════════════════════════════════════════

class KanbanCardSerializer(serializers.ModelSerializer):
    """سریالایزر کارت کانبان — تسک با اطلاعات اضافی."""
    labels = serializers.SerializerMethodField()
    attachment_count = serializers.SerializerMethodField()
    comment_count = serializers.SerializerMethodField()
    checklist_progress = serializers.SerializerMethodField()
    assignee_name = serializers.CharField(source="assignee.get_full_name", read_only=True, default=None)
    priority = serializers.CharField(read_only=True)

    class Meta:
        model = TaskModel
        fields = [
            "id", "project", "code", "title", "description",
            "status", "priority", "task_type", "assignee", "assignee_name",
            "color", "tags",
            "planned_start", "planned_end", "duration", "progress",
            "is_critical", "is_milestone", "sort_order",
            "labels", "attachment_count", "comment_count",
            "checklist_progress", "created_at",
        ]

    def get_labels(self, obj):
        assignments = obj.label_assignments.select_related("label").all()
        return [
            {
                "id": str(a.label_id),
                "name": a.label.name,
                "color": a.label.color,
            }
            for a in assignments
        ]

    def get_attachment_count(self, obj):
        return obj.attachments.count()

    def get_comment_count(self, obj):
        return obj.comments.filter(is_deleted=False).count()

    def get_checklist_progress(self, obj):
        checklists = obj.checklists.prefetch_related("items").all()
        if not checklists:
            return None
        total = 0
        done = 0
        for cl in checklists:
            items = cl.items.all()
            total += len(items)
            done += sum(1 for i in items if i.is_checked)
        if total == 0:
            return None
        return {"total": total, "checked": done, "percent": round(done / total * 100)}


# ═══════════════════════════════════════════════════
# Task Assignment Serializers (Multi-assignment)
# ═══════════════════════════════════════════════════

class TaskAssignmentSerializer(serializers.ModelSerializer):
    user_display = serializers.CharField(
        source="user.get_full_name", read_only=True, default=None,
    )

    class Meta:
        model = TaskAssignmentModel
        fields = [
            "id", "task", "user", "user_display", "role", "units",
            "is_active", "notes", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class TaskAssignmentCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskAssignmentModel
        fields = ["task", "user", "role", "units", "notes"]


# ═══════════════════════════════════════════════════
# Activity Code Serializers
# ═══════════════════════════════════════════════════

class ActivityCodeTypeSerializer(serializers.ModelSerializer):
    value_count = serializers.SerializerMethodField()

    class Meta:
        model = ActivityCodeTypeModel
        fields = [
            "id", "name", "code", "description", "scope",
            "project", "is_active", "sort_order",
            "value_count", "created_at",
        ]
        read_only_fields = ["id", "created_at"]

    def get_value_count(self, obj):
        return obj.values.count() if hasattr(obj, "values") else 0


class ActivityCodeTypeCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ActivityCodeTypeModel
        fields = ["name", "code", "description", "scope", "project", "sort_order"]


class ActivityCodeValueSerializer(serializers.ModelSerializer):
    class Meta:
        model = ActivityCodeValueModel
        fields = [
            "id", "code_type", "parent", "code", "name",
            "description", "color", "sort_order", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class ActivityCodeValueCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ActivityCodeValueModel
        fields = ["code_type", "parent", "code", "name", "description", "color", "sort_order"]


class TaskActivityCodeSerializer(serializers.ModelSerializer):
    code_type_name = serializers.CharField(
        source="code_value.code_type.name", read_only=True, default="",
    )
    code_value_name = serializers.CharField(
        source="code_value.name", read_only=True, default="",
    )

    class Meta:
        model = TaskActivityCodeModel
        fields = [
            "id", "task", "code_value", "code_type_name",
            "code_value_name", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class TaskActivityCodeCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskActivityCodeModel
        fields = ["task", "code_value"]


# ═══════════════════════════════════════════════════
# UDF Serializers (User Defined Fields)
# ═══════════════════════════════════════════════════

class UDFDefinitionSerializer(serializers.ModelSerializer):
    class Meta:
        model = UDFDefinitionModel
        fields = [
            "id", "name", "code", "description", "field_type",
            "entity_type", "default_value", "options",
            "is_required", "is_active", "sort_order", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class UDFDefinitionCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = UDFDefinitionModel
        fields = [
            "name", "code", "description", "field_type", "entity_type",
            "default_value", "options", "is_required", "sort_order",
        ]


class UDFValueSerializer(serializers.ModelSerializer):
    definition_name = serializers.CharField(
        source="definition.name", read_only=True, default="",
    )
    definition_code = serializers.CharField(
        source="definition.code", read_only=True, default="",
    )

    class Meta:
        model = UDFValueModel
        fields = [
            "id", "definition", "definition_name", "definition_code",
            "entity_id", "entity_type",
            "value_text", "value_number", "value_date", "value_boolean",
            "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class UDFValueCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = UDFValueModel
        fields = [
            "definition", "entity_id", "entity_type",
            "value_text", "value_number", "value_date", "value_boolean",
        ]


# ═══════════════════════════════════════════════════
# Resource Skill Serializers
# ═══════════════════════════════════════════════════

class ResourceSkillSerializer(serializers.ModelSerializer):
    class Meta:
        model = ResourceSkillModel
        fields = [
            "id", "resource", "skill_name", "proficiency_level",
            "notes", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class ResourceSkillCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ResourceSkillModel
        fields = ["resource", "skill_name", "proficiency_level", "notes"]


# ═══════════════════════════════════════════════════
# Resource Availability Serializers
# ═══════════════════════════════════════════════════

class ResourceAvailabilitySerializer(serializers.ModelSerializer):
    class Meta:
        model = ResourceAvailabilityModel
        fields = [
            "id", "resource", "start_date", "end_date",
            "available_units", "notes", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class ResourceAvailabilityCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ResourceAvailabilityModel
        fields = ["resource", "start_date", "end_date", "available_units", "notes"]


# ═══════════════════════════════════════════════════
# Resource Cost Rate Serializers
# ═══════════════════════════════════════════════════

class ResourceCostRateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ResourceCostRateModel
        fields = [
            "id", "resource", "effective_date",
            "standard_rate", "overtime_rate", "cost_per_use",
            "notes", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class ResourceCostRateCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ResourceCostRateModel
        fields = [
            "resource", "effective_date",
            "standard_rate", "overtime_rate", "cost_per_use", "notes",
        ]


# ═══════════════════════════════════════════════════
# Cost Account Serializers (CBS)
# ═══════════════════════════════════════════════════

class CostAccountSerializer(serializers.ModelSerializer):
    variance = serializers.SerializerMethodField()

    class Meta:
        model = CostAccountModel
        fields = [
            "id", "project", "parent", "code", "name", "description",
            "budget_amount", "actual_amount", "sort_order",
            "variance", "created_at",
        ]
        read_only_fields = ["id", "created_at"]

    def get_variance(self, obj):
        return obj.budget_amount - obj.actual_amount


class CostAccountCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = CostAccountModel
        fields = ["project", "parent", "code", "name", "description", "budget_amount", "sort_order"]


# ═══════════════════════════════════════════════════
# Funding Source Serializers
# ═══════════════════════════════════════════════════

class FundingSourceSerializer(serializers.ModelSerializer):
    class Meta:
        model = FundingSourceModel
        fields = [
            "id", "project", "name", "description",
            "total_amount", "allocated_amount", "remaining_amount",
            "start_date", "end_date", "is_active", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class FundingSourceCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = FundingSourceModel
        fields = [
            "project", "name", "description", "total_amount",
            "start_date", "end_date",
        ]


# ═══════════════════════════════════════════════════
# Cash Flow Serializers
# ═══════════════════════════════════════════════════

class CashFlowEntrySerializer(serializers.ModelSerializer):
    net_planned = serializers.SerializerMethodField()
    net_actual = serializers.SerializerMethodField()

    class Meta:
        model = CashFlowEntryModel
        fields = [
            "id", "project", "period_start", "period_end",
            "planned_income", "planned_expense",
            "actual_income", "actual_expense",
            "net_planned", "net_actual", "notes", "created_at",
        ]
        read_only_fields = ["id", "created_at"]

    def get_net_planned(self, obj):
        return obj.planned_income - obj.planned_expense

    def get_net_actual(self, obj):
        return obj.actual_income - obj.actual_expense


class CashFlowEntryCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = CashFlowEntryModel
        fields = [
            "project", "period_start", "period_end",
            "planned_income", "planned_expense",
            "actual_income", "actual_expense", "notes",
        ]


# ═══════════════════════════════════════════════════
# Schedule Health Serializers
# ═══════════════════════════════════════════════════

class ScheduleHealthSnapshotSerializer(serializers.ModelSerializer):
    class Meta:
        model = ScheduleHealthSnapshotModel
        fields = [
            "id", "project", "snapshot_date", "health_score",
            "bei", "cpli", "spi",
            "critical_tasks_count", "total_tasks_count",
            "out_of_sequence_count", "missing_logic_count",
            "negative_float_count", "high_float_count",
            "details", "created_at",
        ]
        read_only_fields = fields


class ScheduleHealthRunSerializer(serializers.Serializer):
    project_id = serializers.UUIDField()
    baseline_end = serializers.DateField(required=False, allow_null=True)


# ═══════════════════════════════════════════════════
# Project Template Serializers
# ═══════════════════════════════════════════════════

class ProjectTemplateListSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProjectTemplateModel
        fields = [
            "id", "name", "description", "category",
            "is_active", "usage_count", "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class ProjectTemplateDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProjectTemplateModel
        fields = "__all__"
        read_only_fields = ["id", "tenant", "created_at", "updated_at"]


class ProjectTemplateCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProjectTemplateModel
        fields = ["name", "description", "category", "template_data"]


class SaveProjectAsTemplateSerializer(serializers.Serializer):
    project_id = serializers.UUIDField()
    name = serializers.CharField(max_length=255)
    description = serializers.CharField(required=False, default="")


# ═══════════════════════════════════════════════════
# Monte Carlo Simulation Serializers
# ═══════════════════════════════════════════════════

class TaskEstimateSerializer(serializers.Serializer):
    task_id = serializers.UUIDField()
    optimistic = serializers.FloatField(min_value=0)
    most_likely = serializers.FloatField(min_value=0)
    pessimistic = serializers.FloatField(min_value=0)


class MonteCarloRunSerializer(serializers.Serializer):
    project_id = serializers.UUIDField()
    estimates = TaskEstimateSerializer(many=True)
    iterations = serializers.IntegerField(default=1000, min_value=100, max_value=10000)


class MonteCarloResultSerializer(serializers.Serializer):
    mean = serializers.FloatField()
    std_dev = serializers.FloatField()
    p50 = serializers.FloatField()
    p80 = serializers.FloatField()
    p90 = serializers.FloatField()
    p95 = serializers.FloatField()
    histogram = serializers.ListField()
    confidence_range = serializers.DictField()


# ═══════════════════════════════════════════════════
# Resource Leveling Serializers
# ═══════════════════════════════════════════════════

class ResourceLevelingRunSerializer(serializers.Serializer):
    project_id = serializers.UUIDField()
    apply_results = serializers.BooleanField(default=False)


class ResourceLevelingResultSerializer(serializers.Serializer):
    leveled_tasks = serializers.DictField()
    overallocated_resources = serializers.ListField()
    iterations = serializers.IntegerField()
    success = serializers.BooleanField()


# ═══════════════════════════════════════════════════
# Issue Serializers
# ═══════════════════════════════════════════════════

class IssueListSerializer(serializers.ModelSerializer):
    is_overdue = serializers.SerializerMethodField()
    is_critical = serializers.SerializerMethodField()

    class Meta:
        model = IssueModel
        fields = [
            "id", "project", "code", "title", "category",
            "severity", "priority", "status",
            "reporter", "assignee",
            "cost_impact", "schedule_impact_days",
            "identified_date", "due_date",
            "is_overdue", "is_critical", "created_at",
        ]
        read_only_fields = ["id", "created_at"]

    def get_is_overdue(self, obj):
        from datetime import date as _date
        if obj.due_date and obj.status not in ("resolved", "closed"):
            return _date.today() > obj.due_date
        return False

    def get_is_critical(self, obj):
        return obj.severity == "critical" or obj.priority == "critical"


class IssueDetailSerializer(serializers.ModelSerializer):
    is_overdue = serializers.SerializerMethodField()
    is_critical = serializers.SerializerMethodField()

    class Meta:
        model = IssueModel
        fields = "__all__"
        read_only_fields = ["id", "tenant", "created_at", "updated_at"]

    def get_is_overdue(self, obj):
        from datetime import date as _date
        if obj.due_date and obj.status not in ("resolved", "closed"):
            return _date.today() > obj.due_date
        return False

    def get_is_critical(self, obj):
        return obj.severity == "critical" or obj.priority == "critical"


class IssueCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = IssueModel
        fields = [
            "project", "code", "title", "description", "category",
            "severity", "priority", "reporter", "assignee",
            "affected_tasks", "related_risk",
            "impact_description", "cost_impact", "schedule_impact_days",
            "identified_date", "due_date",
        ]


class IssueAssignSerializer(serializers.Serializer):
    assignee_id = serializers.UUIDField()


class IssueResolveSerializer(serializers.Serializer):
    resolution = serializers.CharField()
    tasks_updated = serializers.IntegerField(default=0)


# ═══════════════════════════════════════════════════
# OBS Serializers
# ═══════════════════════════════════════════════════

class OBSNodeListSerializer(serializers.ModelSerializer):
    children_count = serializers.SerializerMethodField()

    class Meta:
        model = OBSNodeModel
        fields = [
            "id", "project", "parent", "code", "name",
            "node_type", "level", "manager", "is_active",
            "sort_order", "children_count", "created_at",
        ]

    def get_children_count(self, obj):
        return obj.children.count()


class OBSNodeDetailSerializer(serializers.ModelSerializer):
    children_count = serializers.SerializerMethodField()

    class Meta:
        model = OBSNodeModel
        fields = "__all__"

    def get_children_count(self, obj):
        return obj.children.count()


class OBSNodeCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = OBSNodeModel
        fields = [
            "project", "parent", "code", "name", "description",
            "node_type", "manager", "org_unit_id",
            "responsibilities", "sort_order",
        ]


class OBSNodeTreeSerializer(serializers.ModelSerializer):
    """Serializer برای نمایش درختی OBS."""
    children = serializers.SerializerMethodField()

    class Meta:
        model = OBSNodeModel
        fields = [
            "id", "code", "name", "node_type", "level",
            "manager", "is_active", "sort_order", "children",
        ]

    def get_children(self, obj):
        children = obj.children.filter(is_active=True).order_by("sort_order", "code")
        return OBSNodeTreeSerializer(children, many=True).data


# ═══════════════════════════════════════════════════
# RBS Serializers
# ═══════════════════════════════════════════════════

class RBSNodeListSerializer(serializers.ModelSerializer):
    children_count = serializers.SerializerMethodField()

    class Meta:
        model = RBSNodeModel
        fields = [
            "id", "project", "parent", "code", "name",
            "node_type", "level", "resource_type", "unit",
            "default_rate", "is_active", "sort_order",
            "children_count", "created_at",
        ]

    def get_children_count(self, obj):
        return obj.children.count()


class RBSNodeDetailSerializer(serializers.ModelSerializer):
    children_count = serializers.SerializerMethodField()

    class Meta:
        model = RBSNodeModel
        fields = "__all__"

    def get_children_count(self, obj):
        return obj.children.count()


class RBSNodeCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = RBSNodeModel
        fields = [
            "project", "parent", "code", "name", "description",
            "node_type", "resource_type", "unit",
            "default_rate", "sort_order",
        ]


class RBSNodeTreeSerializer(serializers.ModelSerializer):
    """Serializer برای نمایش درختی RBS."""
    children = serializers.SerializerMethodField()

    class Meta:
        model = RBSNodeModel
        fields = [
            "id", "code", "name", "node_type", "level",
            "resource_type", "unit", "default_rate",
            "is_active", "sort_order", "children",
        ]

    def get_children(self, obj):
        children = obj.children.filter(is_active=True).order_by("sort_order", "code")
        return RBSNodeTreeSerializer(children, many=True).data


# ═══════════════════════════════════════════════════
# Quality Plan Serializers
# ═══════════════════════════════════════════════════

class QualityPlanListSerializer(serializers.ModelSerializer):
    class Meta:
        model = QualityPlanModel
        fields = [
            "id", "project", "name", "status", "version",
            "quality_manager", "effective_date", "review_date",
            "created_at",
        ]


class QualityPlanDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = QualityPlanModel
        fields = "__all__"


class QualityPlanCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = QualityPlanModel
        fields = [
            "project", "name", "description", "status",
            "criteria", "standards", "objectives", "scope",
            "quality_manager", "effective_date", "review_date",
            "version", "notes",
        ]


# ═══════════════════════════════════════════════════
# Inspection Serializers
# ═══════════════════════════════════════════════════

class InspectionListSerializer(serializers.ModelSerializer):
    class Meta:
        model = InspectionModel
        fields = [
            "id", "project", "code", "title",
            "inspection_type", "status", "result",
            "inspector", "planned_date", "actual_date",
            "created_at",
        ]


class InspectionDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = InspectionModel
        fields = "__all__"


class InspectionCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = InspectionModel
        fields = [
            "project", "code", "title", "description",
            "inspection_type", "status", "result",
            "quality_plan", "task", "inspector",
            "findings", "recommendations",
            "planned_date", "actual_date", "notes",
        ]


# ═══════════════════════════════════════════════════
# NCR Serializers
# ═══════════════════════════════════════════════════

class NCRListSerializer(serializers.ModelSerializer):
    class Meta:
        model = NCRModel
        fields = [
            "id", "project", "code", "title",
            "severity", "status", "reported_by",
            "assigned_to", "identified_date", "due_date",
            "created_at",
        ]


class NCRDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = NCRModel
        fields = "__all__"


class NCRCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = NCRModel
        fields = [
            "project", "code", "title", "description",
            "severity", "status", "inspection", "task",
            "reported_by", "assigned_to",
            "root_cause", "corrective_action", "preventive_action",
            "cost_impact", "schedule_impact_days",
            "identified_date", "due_date", "notes",
        ]


# ═══════════════════════════════════════════════════
# Quality Checklist Serializers
# ═══════════════════════════════════════════════════

class QualityChecklistListSerializer(serializers.ModelSerializer):
    items_count = serializers.SerializerMethodField()

    class Meta:
        model = QualityChecklistModel
        fields = [
            "id", "project", "name", "quality_plan", "task",
            "is_completed", "completed_date", "items_count",
            "created_at",
        ]

    def get_items_count(self, obj):
        return obj.items.count()


class QualityChecklistDetailSerializer(serializers.ModelSerializer):
    items = serializers.SerializerMethodField()

    class Meta:
        model = QualityChecklistModel
        fields = "__all__"

    def get_items(self, obj):
        items = obj.items.order_by("sort_order")
        return QualityChecklistItemSerializer(items, many=True).data


class QualityChecklistCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = QualityChecklistModel
        fields = [
            "project", "name", "description",
            "quality_plan", "task", "notes",
        ]


class QualityChecklistItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = QualityChecklistItemModel
        fields = "__all__"


class QualityChecklistItemCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = QualityChecklistItemModel
        fields = [
            "checklist", "title", "description",
            "sort_order",
        ]


class QualityChecklistItemUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = QualityChecklistItemModel
        fields = [
            "title", "description", "sort_order",
            "is_checked", "checked_by", "result", "remarks",
        ]


# ═══════════════════════════════════════════════════
# Project Document Serializers
# ═══════════════════════════════════════════════════

class ProjectDocumentListSerializer(serializers.ModelSerializer):
    linked_by_name = serializers.SerializerMethodField()

    class Meta:
        model = ProjectDocumentModel
        fields = [
            "id", "project", "document_id", "entity_type", "entity_id",
            "title", "document_code", "linked_by", "linked_by_name",
            "notes", "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]

    def get_linked_by_name(self, obj):
        if obj.linked_by:
            return obj.linked_by.get_full_name() or obj.linked_by.username
        return None


class ProjectDocumentCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProjectDocumentModel
        fields = [
            "project", "document_id", "entity_type", "entity_id",
            "title", "document_code", "notes",
        ]
