from django import forms
from django.contrib import admin, messages
from django.utils.html import format_html
from django.urls import reverse
from django.utils import timezone
from django.db.models import Sum, Avg
from datetime import timedelta
from urllib.parse import urlencode
from django.db.models.functions import Coalesce
from django.contrib.auth.models import User
from Work.models import WorkLog, Attendance
from .models import (
    EmployeeLevel, EmployeeProfile, TaskValue, WorkScore, SalaryPeriod, SalaryDetail, EmployeeReport
)

# ------------------------------------------------------------------
# 1. فرم اختصاصی حقوق
# ------------------------------------------------------------------
class SalaryPeriodForm(forms.ModelForm):
    class Meta:
        model = SalaryPeriod
        fields = '__all__'
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['selected_users'].label_from_instance = lambda obj: f"{obj.get_full_name()} ({obj.username})" if obj.get_full_name() else obj.username
        self.fields['selected_users'].queryset = User.objects.filter(is_active=True)

# ------------------------------------------------------------------
# 2. تنظیمات سطح تجربه (اصلاح شده برای رفع ارور)
# ------------------------------------------------------------------
@admin.register(EmployeeLevel)
class EmployeeLevelAdmin(admin.ModelAdmin):
    # اینجا دیگر نباید دنبال نام کاربر بگردیم، چون این فقط تعریف سطح است
    list_display = ('title', 'seniority_coefficient')
    list_editable = ('seniority_coefficient',)

# این بخش جدید است: برای اینکه بتوانید به کاربران سطح بدهید
@admin.register(EmployeeProfile)
class EmployeeProfileAdmin(admin.ModelAdmin):
    list_display = ('user_full_name', 'scoring_level')
    list_editable = ('scoring_level',)
    
    @admin.display(description="کاربر")
    def user_full_name(self, obj):
        return obj.user.get_full_name() if obj.user.get_full_name() else obj.user.username

@admin.register(TaskValue)
class TaskValueAdmin(admin.ModelAdmin):
    list_display = ('task_type', 'complexity_coefficient')
    list_editable = ('complexity_coefficient',)

# ------------------------------------------------------------------
# 3. سیستم حقوق (Salary)
# ------------------------------------------------------------------
class SalaryDetailInline(admin.TabularInline):
    model = SalaryDetail
    fields = ('get_full_name_display', 'base_amount', 'performance_amount', 'final_payment', 'total_score_gained')
    readonly_fields = ('get_full_name_display', 'base_amount', 'performance_amount', 'final_payment', 'total_score_gained')
    can_delete = False
    extra = 0
    verbose_name_plural = "نتایج محاسبه حقوق (تومان)"

    @admin.display(description="کارمند")
    def get_full_name_display(self, obj):
        return obj.user.get_full_name() if obj.user.get_full_name() else obj.user.username
    def has_add_permission(self, request, obj): return False
    def has_change_permission(self, request, obj=None): return False

@admin.register(SalaryPeriod)
class SalaryPeriodAdmin(admin.ModelAdmin):
    form = SalaryPeriodForm
    list_display = ('title', 'start_date', 'end_date', 'total_revenue_display', 'get_total_payout')
    fields = (('title', 'total_revenue'), ('start_date', 'end_date'), 'selected_users')
    filter_horizontal = ('selected_users',) 
    inlines = [SalaryDetailInline]

    @admin.display(description="درآمد دوره")
    def total_revenue_display(self, obj): return f"{obj.total_revenue:,}"

    @admin.display(description="جمع کل پرداختی")
    def get_total_payout(self, obj):
        if not obj.pk: return "-"
        total = sum([d.final_payment for d in obj.details.all()])
        return f"{int(total):,} تومان"

    def save_related(self, request, form, formsets, change):
        super().save_related(request, form, formsets, change)
        obj = form.instance
        try:
            obj.calculate_payouts()
            self.message_user(request, f"محاسبات دوره '{obj.title}' انجام شد.", level=messages.SUCCESS)
        except Exception as e:
            self.message_user(request, f"خطا در محاسبه: {str(e)}", level=messages.ERROR)

# ------------------------------------------------------------------
# 4. گزارش کار کارکنان
# ------------------------------------------------------------------
@admin.register(EmployeeReport)
class EmployeeReportAdmin(admin.ModelAdmin):
    list_display = (
        'get_full_name_link',
        'get_total_attendance',
        'get_total_work',
        'get_avg_score',
        'get_avg_complexity',
        'get_last_30_days_score'
    )
    
    def has_add_permission(self, request): return False
    def has_delete_permission(self, request, obj=None): return False
    
    def get_queryset(self, request):
        return super().get_queryset(request).filter(is_active=True)

    def get_user_stats(self, user):
        days = 30
        end_dt = timezone.now()
        start_dt = end_dt - timedelta(days=days)

        # Attendance: چون فیلد date داری، بهتره با date مقایسه بشه
        attendances = Attendance.objects.filter(
            user=user,
            date__range=(start_dt.date(), end_dt.date())
        )
        total_attendance_seconds = attendances.aggregate(
            total=Coalesce(Sum('total_seconds'), 0)
        )['total']

        logs = WorkLog.objects.filter(
            user=user,
            status='done',
            end_time__range=(start_dt, end_dt)
        ).select_related('task_type', 'task_type__scoring_value').prefetch_related('scoring_detail')

        total_work_minutes = 0
        total_final_score = 0
        total_complexity = 0
        total_quality = 0
        count = 0

        for log in logs:
            # ✅ معیار اصلی: actual_minutes (همون "زمان ثبت شده")
            if getattr(log, 'actual_minutes', None) is not None:
                total_work_minutes += (log.actual_minutes or 0)
            else:
                # fallback فقط اگر actual_minutes نداری
                if log.start_time and log.end_time:
                    diff = log.end_time - log.start_time
                    total_work_minutes += max(0, int(diff.total_seconds() // 60))

            if hasattr(log, 'scoring_detail'):
                score = log.scoring_detail
                total_final_score += score.final_task_score
                total_quality += score.quality_rating

                if score.manual_complexity:
                    total_complexity += score.manual_complexity
                elif log.task_type and hasattr(log.task_type, 'scoring_value'):
                    total_complexity += log.task_type.scoring_value.complexity_coefficient
                else:
                    total_complexity += 1.0

                count += 1

        return {
            'att_seconds': int(total_attendance_seconds),
            'work_seconds': int(total_work_minutes * 60),
            'avg_quality': (total_quality / count) if count else 0,
            'avg_complexity': (total_complexity / count) if count else 0,
            'total_score_raw': total_final_score,
            'final_score': total_final_score,
            'count': count,
        }

    # --- نمایش ستون‌ها ---
    @admin.display(description="نام کارمند (ریز کارها)", ordering='last_name')
    def get_full_name_link(self, obj):
        full_name = obj.get_full_name() if obj.get_full_name() else obj.username
        url = reverse('admin:Work_worklog_changelist')

        params = urlencode({
            "user__id__exact": obj.id,
        })

        return format_html(
            '<a href="{}?{}" style="font-weight:bold; color:#3498db; text-decoration:none;">👤 {}</a>',
            url, params, full_name
        )


    @admin.display(description="حضور (۳۰ روز)")
    def get_total_attendance(self, obj):
        stats = self.get_user_stats(obj)
        seconds = stats['att_seconds']
        h = int(seconds // 3600)
        m = int((seconds % 3600) // 60)
        return format_html(
            '<span style="font-weight:bold;">{}</span>h : <span style="font-weight:bold;">{}</span>m',
            h, m
        )

    @admin.display(description="کار مفید (۳۰ روز)")
    def get_total_work(self, obj):
        stats = self.get_user_stats(obj)
        seconds = stats['work_seconds']
        h = int(seconds // 3600)
        m = int((seconds % 3600) // 60)
        
        is_low = seconds < (stats['att_seconds'] / 2)
        color = "red" if is_low else "green"
        
        time_str = f"{h}h : {m:02d}m"
        return format_html('<span style="color:{}; font-weight:bold;">{}</span>', color, time_str)

    @admin.display(description="کیفیت (۳۰ روز)")
    def get_avg_score(self, obj):
        stats = self.get_user_stats(obj)
        if stats['count'] == 0: return "-"
        return f"{stats['avg_quality']:.1f} ⭐"

    @admin.display(description="سختی (۳۰ روز)")
    def get_avg_complexity(self, obj):
        stats = self.get_user_stats(obj)
        if stats['count'] == 0: return "-"
        return f"{stats['avg_complexity']:.1f}"

    @admin.display(description="امتیاز کل (۳۰ روز)")
    def get_last_30_days_score(self, obj):
        stats = self.get_user_stats(obj)
        final = stats['final_score']
        
        tooltip = f"مجموع دقیق تمام امتیازات: {final:.1f}"
        color = "green" if final > 0 else "gray"
        
        score_str = f"{final:.1f}"
        return format_html(
            '<span title="{}" style="color:{}; font-weight:bold; font-size:1.1em; cursor:help;">{}</span>', 
            tooltip, color, score_str
        )