"""
HRM DTOs - Data Transfer Objects.

DTO‌ها برای انتقال داده بین لایه‌ها و API.
"""
from dataclasses import dataclass, field
from datetime import date, datetime
from decimal import Decimal
from typing import Optional, List
from uuid import UUID

from shared.dto.base import BaseDTO


# ─────────────────────────────────────────────
# Legal Entity DTOs
# ─────────────────────────────────────────────

@dataclass
class CreateLegalEntityDTO(BaseDTO):
    """DTO ایجاد شخصیت حقوقی."""
    name: str = ""
    name_en: str = ""
    registration_number: str = ""
    national_id: str = ""
    economic_code: str = ""
    registration_date: Optional[date] = None
    entity_type: str = "COMPANY"
    parent_entity_id: Optional[UUID] = None
    address: str = ""
    phone: str = ""
    email: str = ""
    city: str = ""
    province: str = ""


@dataclass
class UpdateLegalEntityDTO(BaseDTO):
    """DTO بروزرسانی شخصیت حقوقی."""
    name: Optional[str] = None
    name_en: Optional[str] = None
    address: Optional[str] = None
    phone: Optional[str] = None
    email: Optional[str] = None
    is_active: Optional[bool] = None


@dataclass
class LegalEntityResponseDTO(BaseDTO):
    """DTO پاسخ شخصیت حقوقی."""
    id: UUID = None
    name: str = ""
    name_en: str = ""
    registration_number: str = ""
    national_id: str = ""
    economic_code: str = ""
    entity_type: str = ""
    is_active: bool = True
    created_at: Optional[datetime] = None


# ─────────────────────────────────────────────
# Location DTOs
# ─────────────────────────────────────────────

@dataclass
class CreateLocationDTO(BaseDTO):
    """DTO ایجاد مکان."""
    name: str = ""
    code: str = ""
    location_type: str = "OFFICE"
    legal_entity_id: Optional[UUID] = None
    org_unit_id: Optional[UUID] = None
    address: str = ""
    city: str = ""
    province: str = ""
    latitude: Optional[float] = None
    longitude: Optional[float] = None
    capacity: int = 0
    timezone: str = "Asia/Tehran"


@dataclass
class LocationResponseDTO(BaseDTO):
    """DTO پاسخ مکان."""
    id: UUID = None
    name: str = ""
    code: str = ""
    location_type: str = ""
    address: str = ""
    city: str = ""
    is_active: bool = True
    created_at: Optional[datetime] = None


# ─────────────────────────────────────────────
# Employee DTOs
# ─────────────────────────────────────────────

@dataclass
class HireEmployeeDTO(BaseDTO):
    """DTO استخدام کارمند."""
    employee_code: str = ""
    first_name: str = ""
    last_name: str = ""
    first_name_en: str = ""
    last_name_en: str = ""
    national_code: str = ""
    date_of_birth: Optional[date] = None
    gender: str = "MALE"
    marital_status: str = "SINGLE"
    military_status: str = "NOT_APPLICABLE"
    phone: str = ""
    mobile: str = ""
    email: str = ""
    address: str = ""
    hire_date: Optional[date] = None
    employment_type: str = "FULL_TIME"
    legal_entity_id: Optional[UUID] = None
    org_unit_id: Optional[UUID] = None
    location_id: Optional[UUID] = None
    position_id: Optional[UUID] = None


@dataclass
class UpdateEmployeeDTO(BaseDTO):
    """DTO بروزرسانی اطلاعات کارمند."""
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    phone: Optional[str] = None
    mobile: Optional[str] = None
    email: Optional[str] = None
    address: Optional[str] = None
    marital_status: Optional[str] = None
    emergency_contact_name: Optional[str] = None
    emergency_contact_phone: Optional[str] = None
    emergency_contact_relation: Optional[str] = None


@dataclass
class TerminateEmployeeDTO(BaseDTO):
    """DTO خاتمه همکاری."""
    employee_id: UUID = None
    termination_date: date = None
    reason: str = ""


@dataclass
class TransferEmployeeDTO(BaseDTO):
    """DTO انتقال کارمند."""
    employee_id: UUID = None
    new_org_unit_id: UUID = None
    new_position_id: Optional[UUID] = None
    effective_date: date = None


@dataclass
class EmployeeResponseDTO(BaseDTO):
    """DTO پاسخ کارمند."""
    id: UUID = None
    employee_code: str = ""
    first_name: str = ""
    last_name: str = ""
    full_name: str = ""
    national_code: str = ""
    gender: str = ""
    employment_status: str = ""
    employment_type: str = ""
    hire_date: Optional[date] = None
    org_unit_id: Optional[UUID] = None
    position_id: Optional[UUID] = None
    is_active: bool = True
    created_at: Optional[datetime] = None


@dataclass
class EmployeeListDTO(BaseDTO):
    """DTO لیست کارمندان - خلاصه."""
    id: UUID = None
    employee_code: str = ""
    full_name: str = ""
    employment_status: str = ""
    org_unit_id: Optional[UUID] = None


# ─────────────────────────────────────────────
# Position & Job DTOs
# ─────────────────────────────────────────────

@dataclass
class CreateJobTitleDTO(BaseDTO):
    """DTO ایجاد عنوان شغلی."""
    title: str = ""
    title_en: str = ""
    code: str = ""
    job_family_id: Optional[UUID] = None
    level: str = "MID"
    description: str = ""
    responsibilities: str = ""
    qualifications: str = ""
    min_experience_years: int = 0


@dataclass
class JobTitleResponseDTO(BaseDTO):
    """DTO پاسخ عنوان شغلی."""
    id: UUID = None
    title: str = ""
    code: str = ""
    level: str = ""
    is_active: bool = True


@dataclass
class CreatePositionDTO(BaseDTO):
    """DTO ایجاد پست سازمانی."""
    title: str = ""
    code: str = ""
    job_title_id: Optional[UUID] = None
    org_unit_id: Optional[UUID] = None
    legal_entity_id: Optional[UUID] = None
    location_id: Optional[UUID] = None
    reports_to_position_id: Optional[UUID] = None
    is_key_position: bool = False
    budget_amount: float = 0.0
    headcount: int = 1
    fte: float = 1.0


@dataclass
class PositionResponseDTO(BaseDTO):
    """DTO پاسخ پست سازمانی."""
    id: UUID = None
    title: str = ""
    code: str = ""
    status: str = ""
    is_vacant: bool = True
    incumbent_employee_id: Optional[UUID] = None
    org_unit_id: Optional[UUID] = None


# ─────────────────────────────────────────────
# Time & Attendance DTOs
# ─────────────────────────────────────────────

@dataclass
class CreateWorkScheduleDTO(BaseDTO):
    """DTO ایجاد برنامه کاری."""
    name: str = ""
    code: str = ""
    schedule_type: str = "STANDARD"
    start_time: str = ""
    end_time: str = ""
    break_duration_minutes: int = 60
    working_days: list = field(default_factory=lambda: [0, 1, 2, 3, 4])
    daily_hours: str = "8.0"
    weekly_hours: str = "44.0"


@dataclass
class RecordAttendanceDTO(BaseDTO):
    """DTO ثبت حضور."""
    employee_id: UUID = None
    attendance_date: date = None
    check_in: Optional[datetime] = None
    check_out: Optional[datetime] = None
    source: str = "MANUAL"
    location_id: Optional[UUID] = None


@dataclass
class SubmitTimesheetDTO(BaseDTO):
    """DTO ارسال تایم‌شیت."""
    employee_id: UUID = None
    period_start: date = None
    period_end: date = None
    notes: str = ""


@dataclass
class AttendanceResponseDTO(BaseDTO):
    """DTO پاسخ حضور."""
    id: UUID = None
    employee_id: UUID = None
    attendance_date: date = None
    status: str = ""
    check_in: Optional[datetime] = None
    check_out: Optional[datetime] = None
    effective_hours: str = "0"


# ─────────────────────────────────────────────
# Leave DTOs
# ─────────────────────────────────────────────

@dataclass
class RequestLeaveDTO(BaseDTO):
    """DTO درخواست مرخصی."""
    employee_id: UUID = None
    leave_type: str = "ANNUAL"
    start_date: date = None
    end_date: date = None
    days_count: str = "1"
    is_half_day: bool = False
    half_day_period: str = ""
    reason: str = ""
    substitute_employee_id: Optional[UUID] = None


@dataclass
class ApproveLeaveDTO(BaseDTO):
    """DTO تأیید مرخصی."""
    request_id: UUID = None
    approver_id: UUID = None


@dataclass
class RejectLeaveDTO(BaseDTO):
    """DTO رد مرخصی."""
    request_id: UUID = None
    approver_id: UUID = None
    reason: str = ""


@dataclass
class LeaveRequestResponseDTO(BaseDTO):
    """DTO پاسخ درخواست مرخصی."""
    id: UUID = None
    employee_id: UUID = None
    leave_type: str = ""
    start_date: Optional[date] = None
    end_date: Optional[date] = None
    days_count: str = "0"
    status: str = ""
    reason: str = ""


@dataclass
class LeaveBalanceResponseDTO(BaseDTO):
    """DTO پاسخ مانده مرخصی."""
    employee_id: UUID = None
    leave_type: str = ""
    year: int = 0
    entitled_days: str = "0"
    used_days: str = "0"
    pending_days: str = "0"
    available_days: str = "0"


# ─────────────────────────────────────────────
# Payroll DTOs
# ─────────────────────────────────────────────

@dataclass
class SetSalaryDTO(BaseDTO):
    """DTO تنظیم حقوق."""
    employee_id: UUID = None
    pay_grade_id: Optional[UUID] = None
    base_salary: str = "0"
    housing_allowance: str = "0"
    transportation_allowance: str = "0"
    food_allowance: str = "0"
    family_allowance: str = "0"
    effective_date: date = None
    reason: str = ""


@dataclass
class CompensationResponseDTO(BaseDTO):
    """DTO پاسخ حقوق و مزایا."""
    id: UUID = None
    employee_id: UUID = None
    base_salary: str = "0"
    total_monthly: str = "0"
    currency: str = "IRR"
    effective_date: Optional[date] = None
    is_current: bool = True


@dataclass
class CreateBankAccountDTO(BaseDTO):
    """DTO ایجاد حساب بانکی."""
    employee_id: UUID = None
    bank_name: str = ""
    branch_name: str = ""
    account_number: str = ""
    sheba_number: str = ""
    card_number: str = ""
    account_holder_name: str = ""
    is_primary: bool = False


@dataclass
class CostAllocationResponseDTO(BaseDTO):
    """DTO پاسخ تخصیص هزینه."""
    id: UUID = None
    employee_id: UUID = None
    allocation_type: str = ""
    target_code: str = ""
    percentage: str = "100"
    gl_account_code: str = ""
