"""
HRM Public Events - Module Contract.

رویدادهای عمومی ماژول HRM که سایر ماژول‌ها می‌توانند subscribe کنند.
هیچ ماژول دیگری نباید مستقیم از domain events وارد کند.
"""
from dataclasses import dataclass, field
from datetime import date, datetime
from typing import Optional
from uuid import UUID


# ═══════════════════════════════════════════════════
# Base
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class HRMEvent:
    """رویداد پایه ماژول HRM."""
    event_id: UUID
    tenant_id: UUID
    occurred_at: datetime
    version: int = 1


# ═══════════════════════════════════════════════════
# Employee Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class EmployeeHired(HRMEvent):
    """کارمند جدید استخدام شد."""
    event_type: str = "hrm.employee.hired"
    employee_id: UUID = None
    employee_code: str = ""
    full_name: str = ""
    org_unit_id: Optional[UUID] = None
    position_id: Optional[UUID] = None
    hire_date: Optional[date] = None


@dataclass(frozen=True)
class EmployeeTerminated(HRMEvent):
    """همکاری کارمند خاتمه یافت."""
    event_type: str = "hrm.employee.terminated"
    employee_id: UUID = None
    employee_code: str = ""
    termination_date: Optional[date] = None
    reason: str = ""


@dataclass(frozen=True)
class EmployeeTransferred(HRMEvent):
    """کارمند منتقل شد."""
    event_type: str = "hrm.employee.transferred"
    employee_id: UUID = None
    employee_code: str = ""
    from_org_unit_id: Optional[UUID] = None
    to_org_unit_id: Optional[UUID] = None
    from_position_id: Optional[UUID] = None
    to_position_id: Optional[UUID] = None
    effective_date: Optional[date] = None


@dataclass(frozen=True)
class EmployeeUpdated(HRMEvent):
    """اطلاعات کارمند بروزرسانی شد."""
    event_type: str = "hrm.employee.updated"
    employee_id: UUID = None
    employee_code: str = ""
    changed_fields: list = field(default_factory=list)


# ═══════════════════════════════════════════════════
# Position Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class PositionCreated(HRMEvent):
    """پست سازمانی ایجاد شد."""
    event_type: str = "hrm.position.created"
    position_id: UUID = None
    position_code: str = ""
    title: str = ""
    org_unit_id: Optional[UUID] = None


@dataclass(frozen=True)
class PositionFilled(HRMEvent):
    """پست تکمیل شد."""
    event_type: str = "hrm.position.filled"
    position_id: UUID = None
    position_code: str = ""
    employee_id: UUID = None


@dataclass(frozen=True)
class PositionVacated(HRMEvent):
    """پست خالی شد."""
    event_type: str = "hrm.position.vacated"
    position_id: UUID = None
    position_code: str = ""
    former_employee_id: Optional[UUID] = None


# ═══════════════════════════════════════════════════
# Leave Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class LeaveRequested(HRMEvent):
    """درخواست مرخصی ثبت شد."""
    event_type: str = "hrm.leave.requested"
    leave_request_id: UUID = None
    employee_id: UUID = None
    leave_type: str = ""
    start_date: Optional[date] = None
    end_date: Optional[date] = None
    days_count: float = 0


@dataclass(frozen=True)
class LeaveApproved(HRMEvent):
    """مرخصی تأیید شد."""
    event_type: str = "hrm.leave.approved"
    leave_request_id: UUID = None
    employee_id: UUID = None
    leave_type: str = ""
    approved_by: Optional[UUID] = None


@dataclass(frozen=True)
class LeaveRejected(HRMEvent):
    """مرخصی رد شد."""
    event_type: str = "hrm.leave.rejected"
    leave_request_id: UUID = None
    employee_id: UUID = None
    reason: str = ""


@dataclass(frozen=True)
class LeaveCancelled(HRMEvent):
    """مرخصی لغو شد."""
    event_type: str = "hrm.leave.cancelled"
    leave_request_id: UUID = None
    employee_id: UUID = None


# ═══════════════════════════════════════════════════
# Attendance Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class AttendanceRecorded(HRMEvent):
    """حضور ثبت شد."""
    event_type: str = "hrm.attendance.recorded"
    employee_id: UUID = None
    attendance_date: Optional[date] = None
    status: str = ""


@dataclass(frozen=True)
class TimesheetSubmitted(HRMEvent):
    """تایم‌شیت ارسال شد."""
    event_type: str = "hrm.timesheet.submitted"
    timesheet_id: UUID = None
    employee_id: UUID = None
    period_start: Optional[date] = None
    period_end: Optional[date] = None


@dataclass(frozen=True)
class TimesheetApproved(HRMEvent):
    """تایم‌شیت تأیید شد."""
    event_type: str = "hrm.timesheet.approved"
    timesheet_id: UUID = None
    employee_id: UUID = None
    approved_by: Optional[UUID] = None


# ═══════════════════════════════════════════════════
# Payroll Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class SalaryChanged(HRMEvent):
    """حقوق تغییر کرد."""
    event_type: str = "hrm.salary.changed"
    employee_id: UUID = None
    new_base_salary: float = 0
    effective_date: Optional[date] = None
    change_reason: str = ""


@dataclass(frozen=True)
class CostAllocated(HRMEvent):
    """هزینه تخصیص داده شد."""
    event_type: str = "hrm.cost.allocated"
    employee_id: UUID = None
    allocation_type: str = ""
    target_id: Optional[UUID] = None
    percentage: float = 0


# ═══════════════════════════════════════════════════
# Organization Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class LegalEntityCreated(HRMEvent):
    """شخصیت حقوقی ایجاد شد."""
    event_type: str = "hrm.legal_entity.created"
    legal_entity_id: UUID = None
    name: str = ""
    entity_type: str = ""


@dataclass(frozen=True)
class LocationCreated(HRMEvent):
    """مکان ایجاد شد."""
    event_type: str = "hrm.location.created"
    location_id: UUID = None
    name: str = ""
    code: str = ""
    location_type: str = ""
