from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from Work.models import WorkLog, TaskType

# ------------------------------------------------------------------
# 1. تابع کمکی محاسبه امتیاز (برای استفاده در Salary)
# ------------------------------------------------------------------
def calculate_user_period_score(user, start_date, end_date):
    """
    محاسبه امتیاز نهایی کاربر در بازه زمانی.
    """
    logs = WorkLog.objects.filter(
        user=user,
        status='done',
        start_time__gte=start_date,
        end_time__lte=end_date
    ).select_related('scoring_detail')

    total_score = 0

    for log in logs:
        if hasattr(log, 'scoring_detail'):
            total_score += log.scoring_detail.final_task_score

    return {
        'final_score': total_score,
        'total_task_value': total_score,
        'penalty_score': 0
    }

# ------------------------------------------------------------------
# 2. مدل‌های پایه امتیازدهی
# ------------------------------------------------------------------

class EmployeeLevel(models.Model):
    title = models.CharField(max_length=50, verbose_name="عنوان سطح", default="کارمند عادی")
    seniority_coefficient = models.FloatField(default=1.0, verbose_name="ضریب تجربه")
    def __str__(self): return f"{self.title} (x{self.seniority_coefficient})"
    class Meta: verbose_name = "سطح تجربه"; verbose_name_plural = "سطوح تجربه"

class EmployeeProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='scoring_profile')
    scoring_level = models.ForeignKey(EmployeeLevel, on_delete=models.SET_NULL, null=True, blank=True)
    def __str__(self): return self.user.username
    class Meta: verbose_name = "پروفایل امتیازی"; verbose_name_plural = "پروفایل‌های امتیازی"

class TaskValue(models.Model):
    task_type = models.OneToOneField(TaskType, on_delete=models.CASCADE, related_name='scoring_value', verbose_name="نوع فعالیت")
    complexity_coefficient = models.FloatField(default=1.0, verbose_name="ضریب سختی")

    def __str__(self):
        return f"{self.task_type.title} (سختی: {self.complexity_coefficient})"

    class Meta:
        verbose_name = "ارزش‌گذاری فعالیت"
        verbose_name_plural = "ارزش‌گذاری فعالیت‌ها"


class WorkScore(models.Model):
    work_log = models.OneToOneField(WorkLog, on_delete=models.CASCADE, related_name='scoring_detail', verbose_name="گزارش کار مرتبط")

    RATING_CHOICES = (
        (1, '۱ ستاره (0.6)'),
        (2, '۲ ستاره (0.8)'),
        (3, '۳ ستاره (1.0)'),
        (4, '۴ ستاره (1.2)'),
        (5, '۵ ستاره (1.5)'),
    )
    quality_rating = models.PositiveSmallIntegerField(default=3, choices=RATING_CHOICES, verbose_name="امتیاز کیفی")

    manual_complexity = models.FloatField(
        blank=True, null=True,
        verbose_name="سختی دستی (اختیاری)",
        help_text="اگر خالی باشد، از سختی پیش‌فرض نوع فعالیت استفاده می‌شود."
    )

    manual_seniority = models.FloatField(
        blank=True, null=True,
        verbose_name="تجربه دستی (اختیاری)",
        help_text="اگر خالی باشد، از ضریب تجربه پیش‌فرض کاربر استفاده می‌شود."
    )

    manager_note = models.TextField(blank=True, null=True, verbose_name="یادداشت مدیر")
    final_task_score = models.FloatField(default=0, verbose_name="امتیاز نهایی", editable=False)

    def save(self, *args, **kwargs):
        self.final_task_score = self.calculate_score()
        super(WorkScore, self).save(*args, **kwargs)

    @property
    def quality_coefficient(self):
        return {1: 0.6, 2: 0.8, 3: 1.0, 4: 1.2, 5: 1.5}.get(self.quality_rating, 1.0)

    def calculate_score(self):
        """
        محاسبه امتیاز بر اساس فیلد final_time (زمان نهایی تایید شده)
        """
        standard_task_minutes = self.work_log.estimated_minutes or 0

        # ۱. سختی (Complexity)
        complexity = 1.0
        if self.manual_complexity:
            complexity = self.manual_complexity
        elif self.work_log.task_type and hasattr(self.work_log.task_type, 'scoring_value'):
            complexity = self.work_log.task_type.scoring_value.complexity_coefficient

        # ۲. تجربه (Seniority)
        seniority = 1.0
        if self.manual_seniority:
            seniority = self.manual_seniority
        elif hasattr(self.work_log.user, 'scoring_profile') and self.work_log.user.scoring_profile.scoring_level:
            seniority = self.work_log.user.scoring_profile.scoring_level.seniority_coefficient

        if seniority == 0: seniority = 1.0

        # ۳. زمان هدف شخصی‌سازی شده
        personalized_target_time = standard_task_minutes / seniority

        # ۴. ارزش پایه کار
        base_value = standard_task_minutes * complexity * self.quality_coefficient

        # ۵. بازدهی (Efficiency)
        # --- تغییر حیاتی اینجاست ---
        # به جای محاسبه مجدد، زمان نهایی را از WorkLog می‌خوانیم
        # این زمان شامل کسر توقف‌ها و تغییرات دستی مدیر است
        actual_time = self.work_log.final_time
        
        efficiency_points = personalized_target_time - actual_time
        EFFICIENCY_FACTOR = 1.0 
        
        final_score = base_value + (efficiency_points * EFFICIENCY_FACTOR)
        
        return max(0, final_score)
    
    class Meta:
        verbose_name = "امتیاز و ارزیابی"
        verbose_name_plural = "امتیازات"


# ------------------------------------------------------------------
# 3. سیستم حقوق و دستمزد (Salary)
# ------------------------------------------------------------------

class SalaryPeriod(models.Model):
    title = models.CharField(max_length=100, verbose_name="عنوان دوره")
    start_date = models.DateField(verbose_name="از تاریخ")
    end_date = models.DateField(verbose_name="تا تاریخ")
    total_revenue = models.BigIntegerField(verbose_name="درآمد کل دوره (تومان)")
    
    selected_users = models.ManyToManyField(User, verbose_name="کارمندان مشمول محاسبه", blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def calculate_payouts(self):
        self.details.all().delete()
        target_users = self.selected_users.all()
        if not target_users.exists():
            target_users = User.objects.filter(is_active=True)

        user_count = target_users.count()
        if user_count == 0: return

        base_pool = self.total_revenue * 0.5
        performance_pool = self.total_revenue * 0.5
        base_share_per_user = int(base_pool / user_count)

        total_system_score = 0
        user_scores = {}
        
        start_dt = timezone.make_aware(timezone.datetime.combine(self.start_date, timezone.datetime.min.time()))
        end_dt = timezone.make_aware(timezone.datetime.combine(self.end_date, timezone.datetime.max.time()))

        for user in target_users:
            data = calculate_user_period_score(user, start_dt, end_dt)
            score = data['final_score']
            user_scores[user.id] = score
            total_system_score += score

        price_per_score = 0
        if total_system_score > 0:
            price_per_score = performance_pool / total_system_score

        for user in target_users:
            score = user_scores.get(user.id, 0)
            performance_share = int(score * price_per_score)
            final_pay = base_share_per_user + performance_share
            
            SalaryDetail.objects.create(
                period=self,
                user=user,
                base_amount=base_share_per_user,
                performance_amount=performance_share,
                final_payment=final_pay,
                total_score_gained=score
            )

    def __str__(self):
        return f"{self.title} ({self.total_revenue:,} تومان)"

    class Meta:
        verbose_name = "دوره محاسبه حقوق"
        verbose_name_plural = "دوره‌های محاسبه حقوق"


class SalaryDetail(models.Model):
    period = models.ForeignKey(SalaryPeriod, on_delete=models.CASCADE, related_name='details')
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="کارمند")
    
    base_amount = models.BigIntegerField(verbose_name="مبلغ پایه (۵۰٪)")
    performance_amount = models.BigIntegerField(verbose_name="مبلغ عملکردی")
    final_payment = models.BigIntegerField(verbose_name="مبلغ کل پرداختی")
    total_score_gained = models.FloatField(verbose_name="امتیاز")

    def __str__(self):
        return f"فیش حقوقی: {self.user.get_full_name()}"

    class Meta:
        verbose_name = "جزئیات حقوق"
        verbose_name_plural = "جزئیات حقوق"
        ordering = ('-final_payment',)

# مدل مجازی گزارش
class EmployeeReport(User):
    class Meta:
        proxy = True
        verbose_name = "گزارش وضعیت کارمند"
        verbose_name_plural = "گزارش کار کارکنان"