﻿"""
HRM ORM Models - Time, Attendance, Leave, Payroll.

Ø¨Ø®Ø´ Ø¯ÙˆÙ… Ù…Ø¯Ù„â€ŒÙ‡Ø§ÛŒ ORM: Ø­Ø¶ÙˆØ± Ùˆ ØºÛŒØ§Ø¨ØŒ Ù…Ø±Ø®ØµÛŒ Ùˆ Ø­Ù‚ÙˆÙ‚.
"""
import uuid

from django.db import models
from django.utils.translation import gettext_lazy as _
from apps.core.tenant.models import TenantAwareModel
from .models import EmployeeModel, LegalEntityModel


# â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
# 4ï¸âƒ£ Time & Attendance Models
# â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•

class WorkScheduleModel(TenantAwareModel):
    """Ù…Ø¯Ù„ ORM - Ø¨Ø±Ù†Ø§Ù…Ù‡ Ú©Ø§Ø±ÛŒ."""

    class ScheduleType(models.TextChoices):
        STANDARD = "STANDARD", _("Ø§Ø³ØªØ§Ù†Ø¯Ø§Ø±Ø¯")
        SHIFT = "SHIFT", _("Ø´ÛŒÙØªÛŒ")
        FLEXIBLE = "FLEXIBLE", _("Ø´Ù†Ø§ÙˆØ±")
        COMPRESSED = "COMPRESSED", _("ÙØ´Ø±Ø¯Ù‡")
        REMOTE = "REMOTE", _("Ø¯ÙˆØ±Ú©Ø§Ø±ÛŒ")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("Ù†Ø§Ù…"), max_length=255)
    code = models.CharField(_("Ú©Ø¯"), max_length=50)
    schedule_type = models.CharField(
        _("Ù†ÙˆØ¹ Ø¨Ø±Ù†Ø§Ù…Ù‡"),
        max_length=15,
        choices=ScheduleType.choices,
        default=ScheduleType.STANDARD,
    )
    start_time = models.TimeField(_("Ø³Ø§Ø¹Øª Ø´Ø±ÙˆØ¹"), null=True, blank=True)
    end_time = models.TimeField(_("Ø³Ø§Ø¹Øª Ù¾Ø§ÛŒØ§Ù†"), null=True, blank=True)
    break_duration_minutes = models.PositiveIntegerField(
        _("Ù…Ø¯Øª Ø§Ø³ØªØ±Ø§Ø­Øª (Ø¯Ù‚ÛŒÙ‚Ù‡)"), default=60
    )
    working_days = models.JSONField(
        _("Ø±ÙˆØ²Ù‡Ø§ÛŒ Ú©Ø§Ø±ÛŒ"), default=list
    )
    daily_hours = models.DecimalField(
        _("Ø³Ø§Ø¹Øª Ú©Ø§Ø±ÛŒ Ø±ÙˆØ²Ø§Ù†Ù‡"),
        max_digits=4,
        decimal_places=2,
        default=8.00,
    )
    weekly_hours = models.DecimalField(
        _("Ø³Ø§Ø¹Øª Ú©Ø§Ø±ÛŒ Ù‡ÙØªÚ¯ÛŒ"),
        max_digits=5,
        decimal_places=2,
        default=44.00,
    )
    is_night_shift = models.BooleanField(_("Ø´ÛŒÙØª Ø´Ø¨"), default=False)
    overtime_threshold_daily = models.DecimalField(
        _("Ø¢Ø³ØªØ§Ù†Ù‡ Ø§Ø¶Ø§ÙÙ‡â€ŒÚ©Ø§Ø±ÛŒ Ø±ÙˆØ²Ø§Ù†Ù‡"),
        max_digits=4,
        decimal_places=2,
        default=8.00,
    )
    overtime_threshold_weekly = models.DecimalField(
        _("Ø¢Ø³ØªØ§Ù†Ù‡ Ø§Ø¶Ø§ÙÙ‡â€ŒÚ©Ø§Ø±ÛŒ Ù‡ÙØªÚ¯ÛŒ"),
        max_digits=5,
        decimal_places=2,
        default=44.00,
    )
    is_active = models.BooleanField(_("ÙØ¹Ø§Ù„"), default=True)
    metadata = models.JSONField(_("Ù…ØªØ§Ø¯ÛŒØªØ§"), default=dict, blank=True)
    created_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø§ÛŒØ¬Ø§Ø¯"), auto_now_add=True)
    updated_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø¨Ø±ÙˆØ²Ø±Ø³Ø§Ù†ÛŒ"), auto_now=True)

    class Meta:
        app_label = "hrm"
        db_table = "hrm_work_schedule"
        verbose_name = _("Ø¨Ø±Ù†Ø§Ù…Ù‡ Ú©Ø§Ø±ÛŒ")
        verbose_name_plural = _("Ø¨Ø±Ù†Ø§Ù…Ù‡â€ŒÙ‡Ø§ÛŒ Ú©Ø§Ø±ÛŒ")
        unique_together = [["tenant", "code"]]

    def __str__(self):
        return f"{self.name} ({self.code})"


class ShiftPatternModel(TenantAwareModel):
    """Ù…Ø¯Ù„ ORM - Ø§Ù„Ú¯ÙˆÛŒ Ø´ÛŒÙØª."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("Ù†Ø§Ù…"), max_length=255)
    code = models.CharField(_("Ú©Ø¯"), max_length=50)
    cycle_days = models.PositiveIntegerField(_("Ø±ÙˆØ²Ù‡Ø§ÛŒ Ø¯ÙˆØ±Ù‡"), default=7)
    shifts = models.JSONField(
        _("Ø´ÛŒÙØªâ€ŒÙ‡Ø§"),
        default=list,
        help_text=_("Ø¢Ø±Ø§ÛŒÙ‡â€ŒØ§ÛŒ Ø§Ø² Ø´ÛŒÙØªâ€ŒÙ‡Ø§ Ø¨Ø§ Ø±ÙˆØ² Ùˆ Ø¨Ø±Ù†Ø§Ù…Ù‡ Ú©Ø§Ø±ÛŒ"),
    )
    is_active = models.BooleanField(_("ÙØ¹Ø§Ù„"), default=True)
    created_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø§ÛŒØ¬Ø§Ø¯"), auto_now_add=True)
    updated_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø¨Ø±ÙˆØ²Ø±Ø³Ø§Ù†ÛŒ"), auto_now=True)

    class Meta:
        app_label = "hrm"
        db_table = "hrm_shift_pattern"
        verbose_name = _("Ø§Ù„Ú¯ÙˆÛŒ Ø´ÛŒÙØª")
        verbose_name_plural = _("Ø§Ù„Ú¯ÙˆÙ‡Ø§ÛŒ Ø´ÛŒÙØª")
        unique_together = [["tenant", "code"]]

    def __str__(self):
        return self.name


class TimesheetModel(TenantAwareModel):
    """Ù…Ø¯Ù„ ORM - ØªØ§ÛŒÙ…â€ŒØ´ÛŒØª."""

    class TimesheetStatus(models.TextChoices):
        DRAFT = "DRAFT", _("Ù¾ÛŒØ´â€ŒÙ†ÙˆÛŒØ³")
        SUBMITTED = "SUBMITTED", _("Ø§Ø±Ø³Ø§Ù„â€ŒØ´Ø¯Ù‡")
        APPROVED = "APPROVED", _("ØªØ£ÛŒÛŒØ¯â€ŒØ´Ø¯Ù‡")
        REJECTED = "REJECTED", _("Ø±Ø¯â€ŒØ´Ø¯Ù‡")
        REVISED = "REVISED", _("Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒâ€ŒØ´Ø¯Ù‡")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    employee = models.ForeignKey(
        EmployeeModel,
        on_delete=models.CASCADE,
        related_name="timesheets",
        verbose_name=_("Ú©Ø§Ø±Ù…Ù†Ø¯"),
    )
    period_start = models.DateField(_("Ø´Ø±ÙˆØ¹ Ø¯ÙˆØ±Ù‡"))
    period_end = models.DateField(_("Ù¾Ø§ÛŒØ§Ù† Ø¯ÙˆØ±Ù‡"))
    status = models.CharField(
        _("ÙˆØ¶Ø¹ÛŒØª"),
        max_length=15,
        choices=TimesheetStatus.choices,
        default=TimesheetStatus.DRAFT,
        db_index=True,
    )
    total_regular_hours = models.DecimalField(
        _("Ø³Ø§Ø¹Ø§Øª Ø¹Ø§Ø¯ÛŒ"),
        max_digits=7,
        decimal_places=2,
        default=0,
    )
    total_overtime_hours = models.DecimalField(
        _("Ø³Ø§Ø¹Ø§Øª Ø§Ø¶Ø§ÙÙ‡â€ŒÚ©Ø§Ø±ÛŒ"),
        max_digits=7,
        decimal_places=2,
        default=0,
    )
    total_working_days = models.PositiveIntegerField(
        _("Ø±ÙˆØ²Ù‡Ø§ÛŒ Ú©Ø§Ø±ÛŒ"), default=0
    )
    submitted_at = models.DateTimeField(
        _("ØªØ§Ø±ÛŒØ® Ø§Ø±Ø³Ø§Ù„"), null=True, blank=True
    )
    approved_at = models.DateTimeField(
        _("ØªØ§Ø±ÛŒØ® ØªØ£ÛŒÛŒØ¯"), null=True, blank=True
    )
    approved_by = models.UUIDField(
        _("ØªØ£ÛŒÛŒØ¯ ØªÙˆØ³Ø·"), null=True, blank=True
    )
    rejection_reason = models.TextField(_("Ø¯Ù„ÛŒÙ„ Ø±Ø¯"), blank=True)
    notes = models.TextField(_("ÛŒØ§Ø¯Ø¯Ø§Ø´Øª"), blank=True)
    metadata = models.JSONField(_("Ù…ØªØ§Ø¯ÛŒØªØ§"), default=dict, blank=True)
    created_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø§ÛŒØ¬Ø§Ø¯"), auto_now_add=True)
    updated_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø¨Ø±ÙˆØ²Ø±Ø³Ø§Ù†ÛŒ"), auto_now=True)

    class Meta:
        app_label = "hrm"
        db_table = "hrm_timesheet"
        verbose_name = _("ØªØ§ÛŒÙ…â€ŒØ´ÛŒØª")
        verbose_name_plural = _("ØªØ§ÛŒÙ…â€ŒØ´ÛŒØªâ€ŒÙ‡Ø§")
        unique_together = [["tenant", "employee", "period_start", "period_end"]]
        indexes = [
            models.Index(fields=["tenant", "status"]),
            models.Index(fields=["tenant", "employee", "period_start"]),
        ]

    def __str__(self):
        return f"{self.employee} ({self.period_start} - {self.period_end})"


class AttendanceRecordModel(TenantAwareModel):
    """Ù…Ø¯Ù„ ORM - Ø±Ú©ÙˆØ±Ø¯ Ø­Ø¶ÙˆØ± Ùˆ ØºÛŒØ§Ø¨."""

    class AttendanceStatus(models.TextChoices):
        PRESENT = "PRESENT", _("Ø­Ø§Ø¶Ø±")
        ABSENT = "ABSENT", _("ØºØ§ÛŒØ¨")
        LATE = "LATE", _("ØªØ£Ø®ÛŒØ±")
        EARLY_DEPARTURE = "EARLY_DEPARTURE", _("Ø®Ø±ÙˆØ¬ Ø²ÙˆØ¯Ù‡Ù†Ú¯Ø§Ù…")
        ON_LEAVE = "ON_LEAVE", _("Ù…Ø±Ø®ØµÛŒ")
        HOLIDAY = "HOLIDAY", _("ØªØ¹Ø·ÛŒÙ„")
        REMOTE = "REMOTE", _("Ø¯ÙˆØ±Ú©Ø§Ø±ÛŒ")
        BUSINESS_TRIP = "BUSINESS_TRIP", _("Ù…Ø£Ù…ÙˆØ±ÛŒØª")

    class AttendanceSource(models.TextChoices):
        MANUAL = "MANUAL", _("Ø¯Ø³ØªÛŒ")
        BIOMETRIC = "BIOMETRIC", _("Ø¨ÛŒÙˆÙ…ØªØ±ÛŒÚ©")
        GPS = "GPS", _("GPS")
        MOBILE = "MOBILE", _("Ù…ÙˆØ¨Ø§ÛŒÙ„")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    employee = models.ForeignKey(
        EmployeeModel,
        on_delete=models.CASCADE,
        related_name="attendance_records",
        verbose_name=_("Ú©Ø§Ø±Ù…Ù†Ø¯"),
    )
    attendance_date = models.DateField(_("ØªØ§Ø±ÛŒØ®"), db_index=True)
    check_in = models.DateTimeField(_("ÙˆØ±ÙˆØ¯"), null=True, blank=True)
    check_out = models.DateTimeField(_("Ø®Ø±ÙˆØ¬"), null=True, blank=True)
    status = models.CharField(
        _("ÙˆØ¶Ø¹ÛŒØª"),
        max_length=20,
        choices=AttendanceStatus.choices,
        default=AttendanceStatus.PRESENT,
    )
    scheduled_start = models.TimeField(
        _("Ø³Ø§Ø¹Øª Ø´Ø±ÙˆØ¹ Ø¨Ø±Ù†Ø§Ù…Ù‡"), null=True, blank=True
    )
    scheduled_end = models.TimeField(
        _("Ø³Ø§Ø¹Øª Ù¾Ø§ÛŒØ§Ù† Ø¨Ø±Ù†Ø§Ù…Ù‡"), null=True, blank=True
    )
    late_minutes = models.PositiveIntegerField(_("ØªØ£Ø®ÛŒØ± (Ø¯Ù‚ÛŒÙ‚Ù‡)"), default=0)
    early_departure_minutes = models.PositiveIntegerField(
        _("Ø®Ø±ÙˆØ¬ Ø²ÙˆØ¯Ù‡Ù†Ú¯Ø§Ù… (Ø¯Ù‚ÛŒÙ‚Ù‡)"), default=0
    )
    overtime_minutes = models.PositiveIntegerField(
        _("Ø§Ø¶Ø§ÙÙ‡â€ŒÚ©Ø§Ø±ÛŒ (Ø¯Ù‚ÛŒÙ‚Ù‡)"), default=0
    )
    break_minutes = models.PositiveIntegerField(
        _("Ø§Ø³ØªØ±Ø§Ø­Øª (Ø¯Ù‚ÛŒÙ‚Ù‡)"), default=0
    )
    effective_hours = models.DecimalField(
        _("Ø³Ø§Ø¹Ø§Øª Ù…Ø¤Ø«Ø±"),
        max_digits=5,
        decimal_places=2,
        default=0,
    )
    source = models.CharField(
        _("Ù…Ù†Ø¨Ø¹"),
        max_length=15,
        choices=AttendanceSource.choices,
        default=AttendanceSource.MANUAL,
    )
    location = models.ForeignKey(
        "LocationModel",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name=_("Ù…Ú©Ø§Ù†"),
    )
    notes = models.TextField(_("ÛŒØ§Ø¯Ø¯Ø§Ø´Øª"), blank=True)
    metadata = models.JSONField(_("Ù…ØªØ§Ø¯ÛŒØªØ§"), default=dict, blank=True)
    created_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø§ÛŒØ¬Ø§Ø¯"), auto_now_add=True)
    updated_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø¨Ø±ÙˆØ²Ø±Ø³Ø§Ù†ÛŒ"), auto_now=True)

    class Meta:
        app_label = "hrm"
        db_table = "hrm_attendance_record"
        verbose_name = _("Ø±Ú©ÙˆØ±Ø¯ Ø­Ø¶ÙˆØ±")
        verbose_name_plural = _("Ø±Ú©ÙˆØ±Ø¯Ù‡Ø§ÛŒ Ø­Ø¶ÙˆØ±")
        unique_together = [["tenant", "employee", "attendance_date"]]
        indexes = [
            models.Index(fields=["tenant", "employee", "attendance_date"]),
            models.Index(fields=["tenant", "attendance_date", "status"]),
        ]

    def __str__(self):
        return f"{self.employee} - {self.attendance_date} ({self.status})"


# â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
# 5ï¸âƒ£ Leave Management Models
# â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•

class LeavePolicyModel(TenantAwareModel):
    """Ù…Ø¯Ù„ ORM - Ø³ÛŒØ§Ø³Øª Ù…Ø±Ø®ØµÛŒ."""

    class LeaveType(models.TextChoices):
        ANNUAL = "ANNUAL", _("Ø§Ø³ØªØ­Ù‚Ø§Ù‚ÛŒ")
        SICK = "SICK", _("Ø§Ø³ØªØ¹Ù„Ø§Ø¬ÛŒ")
        MATERNITY = "MATERNITY", _("Ø²Ø§ÛŒÙ…Ø§Ù†")
        PATERNITY = "PATERNITY", _("Ù¾Ø¯Ø±ÛŒ")
        UNPAID = "UNPAID", _("Ø¨Ø¯ÙˆÙ† Ø­Ù‚ÙˆÙ‚")
        STUDY = "STUDY", _("ØªØ­ØµÛŒÙ„ÛŒ")
        COMPENSATORY = "COMPENSATORY", _("Ø¬Ø¨Ø±Ø§Ù†ÛŒ")
        BEREAVEMENT = "BEREAVEMENT", _("ÙÙˆØª Ø¨Ø³ØªÚ¯Ø§Ù†")
        MARRIAGE = "MARRIAGE", _("Ø§Ø²Ø¯ÙˆØ§Ø¬")
        PILGRIMAGE = "PILGRIMAGE", _("Ø­Ø¬")
        HOURLY = "HOURLY", _("Ø³Ø§Ø¹ØªÛŒ")

    class AccrualMethod(models.TextChoices):
        ANNUAL = "ANNUAL", _("Ø³Ø§Ù„Ø§Ù†Ù‡")
        MONTHLY = "MONTHLY", _("Ù…Ø§Ù‡Ø§Ù†Ù‡")
        DAILY = "DAILY", _("Ø±ÙˆØ²Ø§Ù†Ù‡")
        CUSTOM = "CUSTOM", _("Ø³ÙØ§Ø±Ø´ÛŒ")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("Ù†Ø§Ù…"), max_length=255)
    code = models.CharField(_("Ú©Ø¯"), max_length=50)
    leave_type = models.CharField(
        _("Ù†ÙˆØ¹ Ù…Ø±Ø®ØµÛŒ"),
        max_length=20,
        choices=LeaveType.choices,
        default=LeaveType.ANNUAL,
    )
    annual_entitlement_days = models.DecimalField(
        _("Ø­Ù‚ Ù…Ø±Ø®ØµÛŒ Ø³Ø§Ù„Ø§Ù†Ù‡ (Ø±ÙˆØ²)"),
        max_digits=5,
        decimal_places=2,
        default=26.00,
    )
    max_carryover_days = models.DecimalField(
        _("Ø­Ø¯Ø§Ú©Ø«Ø± Ø°Ø®ÛŒØ±Ù‡ (Ø±ÙˆØ²)"),
        max_digits=5,
        decimal_places=2,
        default=10.00,
    )
    max_accumulation_days = models.DecimalField(
        _("Ø­Ø¯Ø§Ú©Ø«Ø± Ø§Ù†Ø¨Ø§Ø´Øª (Ø±ÙˆØ²)"),
        max_digits=5,
        decimal_places=2,
        default=36.00,
    )
    min_service_days_required = models.PositiveIntegerField(
        _("Ø­Ø¯Ø§Ù‚Ù„ Ø³Ø§Ø¨Ù‚Ù‡ Ù…ÙˆØ±Ø¯ Ù†ÛŒØ§Ø² (Ø±ÙˆØ²)"), default=0
    )
    accrual_method = models.CharField(
        _("Ø±ÙˆØ´ Ù…Ø­Ø§Ø³Ø¨Ù‡"),
        max_length=15,
        choices=AccrualMethod.choices,
        default=AccrualMethod.MONTHLY,
    )
    requires_approval = models.BooleanField(_("Ù†ÛŒØ§Ø² Ø¨Ù‡ ØªØ£ÛŒÛŒØ¯"), default=True)
    max_consecutive_days = models.PositiveIntegerField(
        _("Ø­Ø¯Ø§Ú©Ø«Ø± Ø±ÙˆØ² Ù…ØªÙˆØ§Ù„ÛŒ"), default=30
    )
    min_notice_days = models.PositiveIntegerField(
        _("Ø­Ø¯Ø§Ù‚Ù„ Ø§Ø·Ù„Ø§Ø¹ Ù‚Ø¨Ù„ÛŒ (Ø±ÙˆØ²)"), default=1
    )
    allow_half_day = models.BooleanField(_("Ù…Ø±Ø®ØµÛŒ Ù†ÛŒÙ…â€ŒØ±ÙˆØ²"), default=True)
    allow_hourly = models.BooleanField(_("Ù…Ø±Ø®ØµÛŒ Ø³Ø§Ø¹ØªÛŒ"), default=False)
    is_paid = models.BooleanField(_("Ø¨Ø§ Ø­Ù‚ÙˆÙ‚"), default=True)
    applicable_genders = models.JSONField(
        _("Ø¬Ù†Ø³ÛŒØªâ€ŒÙ‡Ø§ÛŒ Ù…Ø´Ù…ÙˆÙ„"), default=list
    )
    applicable_employment_types = models.JSONField(
        _("Ø§Ù†ÙˆØ§Ø¹ Ø§Ø³ØªØ®Ø¯Ø§Ù… Ù…Ø´Ù…ÙˆÙ„"), default=list
    )
    is_active = models.BooleanField(_("ÙØ¹Ø§Ù„"), default=True)
    metadata = models.JSONField(_("Ù…ØªØ§Ø¯ÛŒØªØ§"), default=dict, blank=True)
    created_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø§ÛŒØ¬Ø§Ø¯"), auto_now_add=True)
    updated_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø¨Ø±ÙˆØ²Ø±Ø³Ø§Ù†ÛŒ"), auto_now=True)

    class Meta:
        app_label = "hrm"
        db_table = "hrm_leave_policy"
        verbose_name = _("Ø³ÛŒØ§Ø³Øª Ù…Ø±Ø®ØµÛŒ")
        verbose_name_plural = _("Ø³ÛŒØ§Ø³Øªâ€ŒÙ‡Ø§ÛŒ Ù…Ø±Ø®ØµÛŒ")
        unique_together = [["tenant", "code"]]
        indexes = [
            models.Index(fields=["tenant", "leave_type"]),
        ]

    def __str__(self):
        return f"{self.name} ({self.leave_type})"


class LeaveBalanceModel(TenantAwareModel):
    """Ù…Ø¯Ù„ ORM - Ù…Ø§Ù†Ø¯Ù‡ Ù…Ø±Ø®ØµÛŒ."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    employee = models.ForeignKey(
        EmployeeModel,
        on_delete=models.CASCADE,
        related_name="leave_balances",
        verbose_name=_("Ú©Ø§Ø±Ù…Ù†Ø¯"),
    )
    leave_policy = models.ForeignKey(
        LeavePolicyModel,
        on_delete=models.CASCADE,
        related_name="balances",
        verbose_name=_("Ø³ÛŒØ§Ø³Øª Ù…Ø±Ø®ØµÛŒ"),
    )
    leave_type = models.CharField(_("Ù†ÙˆØ¹ Ù…Ø±Ø®ØµÛŒ"), max_length=20)
    year = models.PositiveIntegerField(_("Ø³Ø§Ù„"))
    entitled_days = models.DecimalField(
        _("Ø­Ù‚ Ù…Ø±Ø®ØµÛŒ"),
        max_digits=6,
        decimal_places=2,
        default=0,
    )
    carried_over_days = models.DecimalField(
        _("Ø°Ø®ÛŒØ±Ù‡ Ø§Ø² Ø³Ø§Ù„ Ù‚Ø¨Ù„"),
        max_digits=6,
        decimal_places=2,
        default=0,
    )
    used_days = models.DecimalField(
        _("Ù…ØµØ±Ùâ€ŒØ´Ø¯Ù‡"),
        max_digits=6,
        decimal_places=2,
        default=0,
    )
    pending_days = models.DecimalField(
        _("Ø¯Ø± Ø§Ù†ØªØ¸Ø§Ø± ØªØ£ÛŒÛŒØ¯"),
        max_digits=6,
        decimal_places=2,
        default=0,
    )
    adjustment_days = models.DecimalField(
        _("ØªØ¹Ø¯ÛŒÙ„"),
        max_digits=6,
        decimal_places=2,
        default=0,
    )
    metadata = models.JSONField(_("Ù…ØªØ§Ø¯ÛŒØªØ§"), default=dict, blank=True)
    created_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø§ÛŒØ¬Ø§Ø¯"), auto_now_add=True)
    updated_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø¨Ø±ÙˆØ²Ø±Ø³Ø§Ù†ÛŒ"), auto_now=True)

    class Meta:
        app_label = "hrm"
        db_table = "hrm_leave_balance"
        verbose_name = _("Ù…Ø§Ù†Ø¯Ù‡ Ù…Ø±Ø®ØµÛŒ")
        verbose_name_plural = _("Ù…Ø§Ù†Ø¯Ù‡ Ù…Ø±Ø®ØµÛŒâ€ŒÙ‡Ø§")
        unique_together = [
            ["tenant", "employee", "leave_type", "year"]
        ]
        indexes = [
            models.Index(fields=["tenant", "employee", "year"]),
        ]

    def __str__(self):
        return f"{self.employee} - {self.leave_type} ({self.year})"

    @property
    def available_days(self):
        return (
            self.entitled_days
            + self.carried_over_days
            + self.adjustment_days
            - self.used_days
            - self.pending_days
        )


class LeaveRequestModel(TenantAwareModel):
    """Ù…Ø¯Ù„ ORM - Ø¯Ø±Ø®ÙˆØ§Ø³Øª Ù…Ø±Ø®ØµÛŒ."""

    class LeaveRequestStatus(models.TextChoices):
        DRAFT = "DRAFT", _("Ù¾ÛŒØ´â€ŒÙ†ÙˆÛŒØ³")
        PENDING = "PENDING", _("Ø¯Ø± Ø§Ù†ØªØ¸Ø§Ø± ØªØ£ÛŒÛŒØ¯")
        APPROVED = "APPROVED", _("ØªØ£ÛŒÛŒØ¯â€ŒØ´Ø¯Ù‡")
        REJECTED = "REJECTED", _("Ø±Ø¯â€ŒØ´Ø¯Ù‡")
        CANCELLED = "CANCELLED", _("Ù„ØºÙˆâ€ŒØ´Ø¯Ù‡")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    employee = models.ForeignKey(
        EmployeeModel,
        on_delete=models.CASCADE,
        related_name="leave_requests",
        verbose_name=_("Ú©Ø§Ø±Ù…Ù†Ø¯"),
    )
    leave_type = models.CharField(_("Ù†ÙˆØ¹ Ù…Ø±Ø®ØµÛŒ"), max_length=20)
    leave_policy = models.ForeignKey(
        LeavePolicyModel,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name=_("Ø³ÛŒØ§Ø³Øª Ù…Ø±Ø®ØµÛŒ"),
    )
    start_date = models.DateField(_("ØªØ§Ø±ÛŒØ® Ø´Ø±ÙˆØ¹"))
    end_date = models.DateField(_("ØªØ§Ø±ÛŒØ® Ù¾Ø§ÛŒØ§Ù†"))
    days_count = models.DecimalField(
        _("ØªØ¹Ø¯Ø§Ø¯ Ø±ÙˆØ²"),
        max_digits=5,
        decimal_places=2,
        default=1,
    )
    is_half_day = models.BooleanField(_("Ù†ÛŒÙ…â€ŒØ±ÙˆØ²"), default=False)
    half_day_period = models.CharField(
        _("Ø¨Ø§Ø²Ù‡ Ù†ÛŒÙ…â€ŒØ±ÙˆØ²"), max_length=15, blank=True
    )
    status = models.CharField(
        _("ÙˆØ¶Ø¹ÛŒØª"),
        max_length=15,
        choices=LeaveRequestStatus.choices,
        default=LeaveRequestStatus.DRAFT,
        db_index=True,
    )
    reason = models.TextField(_("Ø¯Ù„ÛŒÙ„"), blank=True)
    substitute = models.ForeignKey(
        EmployeeModel,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="substituted_leaves",
        verbose_name=_("Ø¬Ø§Ù†Ø´ÛŒÙ†"),
    )
    approved_by = models.UUIDField(
        _("ØªØ£ÛŒÛŒØ¯ ØªÙˆØ³Ø·"), null=True, blank=True
    )
    approved_at = models.DateTimeField(
        _("ØªØ§Ø±ÛŒØ® ØªØ£ÛŒÛŒØ¯"), null=True, blank=True
    )
    rejection_reason = models.TextField(_("Ø¯Ù„ÛŒÙ„ Ø±Ø¯"), blank=True)
    attachment = models.FileField(
        _("Ù¾ÛŒÙˆØ³Øª"), upload_to="hrm/leave_attachments/", blank=True
    )
    notes = models.TextField(_("ÛŒØ§Ø¯Ø¯Ø§Ø´Øª"), blank=True)
    metadata = models.JSONField(_("Ù…ØªØ§Ø¯ÛŒØªØ§"), default=dict, blank=True)
    created_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø§ÛŒØ¬Ø§Ø¯"), auto_now_add=True)
    updated_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø¨Ø±ÙˆØ²Ø±Ø³Ø§Ù†ÛŒ"), auto_now=True)

    class Meta:
        app_label = "hrm"
        db_table = "hrm_leave_request"
        verbose_name = _("Ø¯Ø±Ø®ÙˆØ§Ø³Øª Ù…Ø±Ø®ØµÛŒ")
        verbose_name_plural = _("Ø¯Ø±Ø®ÙˆØ§Ø³Øªâ€ŒÙ‡Ø§ÛŒ Ù…Ø±Ø®ØµÛŒ")
        indexes = [
            models.Index(fields=["tenant", "employee", "status"]),
            models.Index(fields=["tenant", "status"]),
            models.Index(fields=["tenant", "start_date", "end_date"]),
        ]

    def __str__(self):
        return f"{self.employee} - {self.leave_type} ({self.start_date})"


# â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
# 6ï¸âƒ£ Payroll Foundation Models
# â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•

class PayGradeModel(TenantAwareModel):
    """Ù…Ø¯Ù„ ORM - Ø±ØªØ¨Ù‡ Ø­Ù‚ÙˆÙ‚ÛŒ."""

    class GradeType(models.TextChoices):
        HOURLY = "HOURLY", _("Ø³Ø§Ø¹ØªÛŒ")
        MONTHLY = "MONTHLY", _("Ù…Ø§Ù‡Ø§Ù†Ù‡")
        ANNUAL = "ANNUAL", _("Ø³Ø§Ù„Ø§Ù†Ù‡")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("Ù†Ø§Ù…"), max_length=255)
    code = models.CharField(_("Ú©Ø¯"), max_length=50)
    grade_type = models.CharField(
        _("Ù†ÙˆØ¹"),
        max_length=15,
        choices=GradeType.choices,
        default=GradeType.MONTHLY,
    )
    min_amount = models.DecimalField(
        _("Ø­Ø¯Ø§Ù‚Ù„"),
        max_digits=18,
        decimal_places=0,
        default=0,
    )
    mid_amount = models.DecimalField(
        _("Ù…ÛŒØ§Ù†Ù‡"),
        max_digits=18,
        decimal_places=0,
        default=0,
    )
    max_amount = models.DecimalField(
        _("Ø­Ø¯Ø§Ú©Ø«Ø±"),
        max_digits=18,
        decimal_places=0,
        default=0,
    )
    currency = models.CharField(_("Ø§Ø±Ø²"), max_length=5, default="IRR")
    step_count = models.PositiveIntegerField(_("ØªØ¹Ø¯Ø§Ø¯ Ù¾Ù„Ù‡"), default=1)
    step_increment = models.DecimalField(
        _("Ø§ÙØ²Ø§ÛŒØ´ Ù‡Ø± Ù¾Ù„Ù‡"),
        max_digits=18,
        decimal_places=0,
        default=0,
    )
    is_active = models.BooleanField(_("ÙØ¹Ø§Ù„"), default=True)
    metadata = models.JSONField(_("Ù…ØªØ§Ø¯ÛŒØªØ§"), default=dict, blank=True)
    created_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø§ÛŒØ¬Ø§Ø¯"), auto_now_add=True)
    updated_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø¨Ø±ÙˆØ²Ø±Ø³Ø§Ù†ÛŒ"), auto_now=True)

    class Meta:
        app_label = "hrm"
        db_table = "hrm_pay_grade"
        verbose_name = _("Ø±ØªØ¨Ù‡ Ø­Ù‚ÙˆÙ‚ÛŒ")
        verbose_name_plural = _("Ø±ØªØ¨Ù‡â€ŒÙ‡Ø§ÛŒ Ø­Ù‚ÙˆÙ‚ÛŒ")
        unique_together = [["tenant", "code"]]

    def __str__(self):
        return f"{self.name} ({self.code})"


class CompensationRecordModel(TenantAwareModel):
    """Ù…Ø¯Ù„ ORM - Ø³Ø§Ø¨Ù‚Ù‡ Ø­Ù‚ÙˆÙ‚ Ùˆ Ù…Ø²Ø§ÛŒØ§."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    employee = models.ForeignKey(
        EmployeeModel,
        on_delete=models.CASCADE,
        related_name="compensation_records",
        verbose_name=_("Ú©Ø§Ø±Ù…Ù†Ø¯"),
    )
    pay_grade = models.ForeignKey(
        PayGradeModel,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name=_("Ø±ØªØ¨Ù‡ Ø­Ù‚ÙˆÙ‚ÛŒ"),
    )
    base_salary = models.DecimalField(
        _("Ø­Ù‚ÙˆÙ‚ Ù¾Ø§ÛŒÙ‡"),
        max_digits=18,
        decimal_places=0,
        default=0,
    )
    housing_allowance = models.DecimalField(
        _("Ø­Ù‚ Ù…Ø³Ú©Ù†"),
        max_digits=18,
        decimal_places=0,
        default=0,
    )
    transportation_allowance = models.DecimalField(
        _("Ø­Ù‚ Ø§ÛŒØ§Ø¨ Ùˆ Ø°Ù‡Ø§Ø¨"),
        max_digits=18,
        decimal_places=0,
        default=0,
    )
    food_allowance = models.DecimalField(
        _("Ø­Ù‚ Ø®ÙˆØ§Ø±Ø¨Ø§Ø±"),
        max_digits=18,
        decimal_places=0,
        default=0,
    )
    family_allowance = models.DecimalField(
        _("Ø­Ù‚ Ø¹Ø§Ø¦Ù„Ù‡â€ŒÙ…Ù†Ø¯ÛŒ"),
        max_digits=18,
        decimal_places=0,
        default=0,
    )
    overtime_rate = models.DecimalField(
        _("Ø¶Ø±ÛŒØ¨ Ø§Ø¶Ø§ÙÙ‡â€ŒÚ©Ø§Ø±ÛŒ"),
        max_digits=4,
        decimal_places=2,
        default=1.40,
    )
    holiday_rate = models.DecimalField(
        _("Ø¶Ø±ÛŒØ¨ ØªØ¹Ø·ÛŒÙ„â€ŒÚ©Ø§Ø±ÛŒ"),
        max_digits=4,
        decimal_places=2,
        default=1.40,
    )
    night_shift_rate = models.DecimalField(
        _("Ø¶Ø±ÛŒØ¨ Ø´Ø¨â€ŒÚ©Ø§Ø±ÛŒ"),
        max_digits=4,
        decimal_places=2,
        default=1.35,
    )
    currency = models.CharField(_("Ø§Ø±Ø²"), max_length=5, default="IRR")
    pay_grade_step = models.PositiveIntegerField(_("Ù¾Ù„Ù‡ Ø­Ù‚ÙˆÙ‚ÛŒ"), default=1)
    effective_date = models.DateField(_("ØªØ§Ø±ÛŒØ® Ù…Ø¤Ø«Ø±"))
    end_date = models.DateField(_("ØªØ§Ø±ÛŒØ® Ù¾Ø§ÛŒØ§Ù†"), null=True, blank=True)
    is_current = models.BooleanField(
        _("ÙØ¹Ù„ÛŒ"), default=True, db_index=True
    )
    change_reason = models.TextField(_("Ø¯Ù„ÛŒÙ„ ØªØºÛŒÛŒØ±"), blank=True)
    metadata = models.JSONField(_("Ù…ØªØ§Ø¯ÛŒØªØ§"), default=dict, blank=True)
    created_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø§ÛŒØ¬Ø§Ø¯"), auto_now_add=True)
    updated_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø¨Ø±ÙˆØ²Ø±Ø³Ø§Ù†ÛŒ"), auto_now=True)

    class Meta:
        app_label = "hrm"
        db_table = "hrm_compensation_record"
        verbose_name = _("Ø³Ø§Ø¨Ù‚Ù‡ Ø­Ù‚ÙˆÙ‚ÛŒ")
        verbose_name_plural = _("Ø³ÙˆØ§Ø¨Ù‚ Ø­Ù‚ÙˆÙ‚ÛŒ")
        indexes = [
            models.Index(fields=["tenant", "employee", "is_current"]),
            models.Index(fields=["tenant", "effective_date"]),
        ]
        ordering = ["-effective_date"]

    def __str__(self):
        return f"{self.employee} - {self.base_salary} ({self.effective_date})"

    @property
    def total_monthly(self):
        return (
            self.base_salary
            + self.housing_allowance
            + self.transportation_allowance
            + self.food_allowance
            + self.family_allowance
        )


class BankAccountModel(TenantAwareModel):
    """Ù…Ø¯Ù„ ORM - Ø­Ø³Ø§Ø¨ Ø¨Ø§Ù†Ú©ÛŒ."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    employee = models.ForeignKey(
        EmployeeModel,
        on_delete=models.CASCADE,
        related_name="bank_accounts",
        verbose_name=_("Ú©Ø§Ø±Ù…Ù†Ø¯"),
    )
    bank_name = models.CharField(_("Ù†Ø§Ù… Ø¨Ø§Ù†Ú©"), max_length=100)
    branch_name = models.CharField(_("Ù†Ø§Ù… Ø´Ø¹Ø¨Ù‡"), max_length=100, blank=True)
    branch_code = models.CharField(_("Ú©Ø¯ Ø´Ø¹Ø¨Ù‡"), max_length=20, blank=True)
    account_number = models.CharField(_("Ø´Ù…Ø§Ø±Ù‡ Ø­Ø³Ø§Ø¨"), max_length=50)
    sheba_number = models.CharField(
        _("Ø´Ù…Ø§Ø±Ù‡ Ø´Ø¨Ø§"), max_length=26, blank=True
    )
    card_number = models.CharField(
        _("Ø´Ù…Ø§Ø±Ù‡ Ú©Ø§Ø±Øª"), max_length=16, blank=True
    )
    account_holder_name = models.CharField(
        _("Ù†Ø§Ù… ØµØ§Ø­Ø¨ Ø­Ø³Ø§Ø¨"), max_length=200, blank=True
    )
    is_primary = models.BooleanField(_("Ø­Ø³Ø§Ø¨ Ø§ØµÙ„ÛŒ"), default=False)
    is_active = models.BooleanField(_("ÙØ¹Ø§Ù„"), default=True)
    metadata = models.JSONField(_("Ù…ØªØ§Ø¯ÛŒØªØ§"), default=dict, blank=True)
    created_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø§ÛŒØ¬Ø§Ø¯"), auto_now_add=True)
    updated_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø¨Ø±ÙˆØ²Ø±Ø³Ø§Ù†ÛŒ"), auto_now=True)

    class Meta:
        app_label = "hrm"
        db_table = "hrm_bank_account"
        verbose_name = _("Ø­Ø³Ø§Ø¨ Ø¨Ø§Ù†Ú©ÛŒ")
        verbose_name_plural = _("Ø­Ø³Ø§Ø¨â€ŒÙ‡Ø§ÛŒ Ø¨Ø§Ù†Ú©ÛŒ")
        indexes = [
            models.Index(fields=["tenant", "employee"]),
        ]

    def __str__(self):
        return f"{self.employee} - {self.bank_name} ({self.account_number})"


class CostAllocationModel(TenantAwareModel):
    """Ù…Ø¯Ù„ ORM - ØªØ®ØµÛŒØµ Ù‡Ø²ÛŒÙ†Ù‡."""

    class AllocationType(models.TextChoices):
        POSITION = "POSITION", _("Ù¾Ø³Øª")
        DEPARTMENT = "DEPARTMENT", _("ÙˆØ§Ø­Ø¯")
        PROJECT = "PROJECT", _("Ù¾Ø±ÙˆÚ˜Ù‡")
        COST_CENTER = "COST_CENTER", _("Ù…Ø±Ú©Ø² Ù‡Ø²ÛŒÙ†Ù‡")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    employee = models.ForeignKey(
        EmployeeModel,
        on_delete=models.CASCADE,
        related_name="cost_allocations",
        verbose_name=_("Ú©Ø§Ø±Ù…Ù†Ø¯"),
    )
    allocation_type = models.CharField(
        _("Ù†ÙˆØ¹ ØªØ®ØµÛŒØµ"),
        max_length=20,
        choices=AllocationType.choices,
        default=AllocationType.DEPARTMENT,
    )
    target_id = models.UUIDField(_("Ø´Ù†Ø§Ø³Ù‡ Ù…Ù‚ØµØ¯"))
    target_code = models.CharField(_("Ú©Ø¯ Ù…Ù‚ØµØ¯"), max_length=50, blank=True)
    percentage = models.DecimalField(
        _("Ø¯Ø±ØµØ¯"),
        max_digits=5,
        decimal_places=2,
        default=100.00,
    )
    gl_account_code = models.CharField(
        _("Ú©Ø¯ Ø­Ø³Ø§Ø¨ Ø¯ÙØªØ± Ú©Ù„"), max_length=50, blank=True
    )
    effective_date = models.DateField(
        _("ØªØ§Ø±ÛŒØ® Ù…Ø¤Ø«Ø±"), null=True, blank=True
    )
    end_date = models.DateField(
        _("ØªØ§Ø±ÛŒØ® Ù¾Ø§ÛŒØ§Ù†"), null=True, blank=True
    )
    is_active = models.BooleanField(_("ÙØ¹Ø§Ù„"), default=True)
    metadata = models.JSONField(_("Ù…ØªØ§Ø¯ÛŒØªØ§"), default=dict, blank=True)
    created_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø§ÛŒØ¬Ø§Ø¯"), auto_now_add=True)
    updated_at = models.DateTimeField(_("ØªØ§Ø±ÛŒØ® Ø¨Ø±ÙˆØ²Ø±Ø³Ø§Ù†ÛŒ"), auto_now=True)

    class Meta:
        app_label = "hrm"
        db_table = "hrm_cost_allocation"
        verbose_name = _("ØªØ®ØµÛŒØµ Ù‡Ø²ÛŒÙ†Ù‡")
        verbose_name_plural = _("ØªØ®ØµÛŒØµâ€ŒÙ‡Ø§ÛŒ Ù‡Ø²ÛŒÙ†Ù‡")
        indexes = [
            models.Index(fields=["tenant", "employee"]),
            models.Index(fields=["tenant", "allocation_type", "target_id"]),
        ]

    def __str__(self):
        return f"{self.employee} - {self.allocation_type} ({self.percentage}%)"
