from rest_framework import viewsets, permissions, status
from rest_framework.response import Response
from rest_framework.decorators import action
from django.utils import timezone
from django.db import transaction
from datetime import timedelta, datetime, time
import jdatetime
from django.contrib.auth.models import User
# --- تغییر ۱: اضافه شدن TaskType به ایمپورت‌ها ---
from .models import Project, UserProfile, WorkLog, Request, RequestType, Attendance, TaskType
# --- تغییر ۲: اضافه شدن TaskTypeSerializer به ایمپورت‌ها ---
from .serializers import (
    ProjectSerializer, UserProfileSerializer, 
    WorkLogSerializer, RequestSerializer, RequestTypeSerializer, AttendanceSerializer, TaskTypeSerializer
)
import pytz


# 1. ویو لیست پروژه‌ها
class ProjectViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectSerializer
    permission_classes = [permissions.IsAuthenticated]


# 2. ویو پروفایل کاربر
class UserProfileViewSet(viewsets.ModelViewSet):
    serializer_class = UserProfileSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        return UserProfile.objects.filter(user=self.request.user)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)


# 3. ویو مدیریت کارها
class WorkLogViewSet(viewsets.ModelViewSet):
    serializer_class = WorkLogSerializer
    permission_classes = [permissions.IsAuthenticated]



    def get_queryset(self):
        # کارهایی که هنوز "done" یا "suspended" نشده‌اند را برگردان (یعنی pending و doing)
        # یا اگر می‌خواهی همه را ببینی، فیلتر نکن. اما برای داشبورد معمولا کارهای باز مهم است.
        return WorkLog.objects.filter(user=self.request.user).order_by('-created_date', '-start_time')

    def perform_create(self, serializer):
        # هنگام ساخت، وضعیت پیش‌فرض مدل (pending) اعمال می‌شود
        serializer.save(user=self.request.user)

    # --- اکشن ۱: شروع کار (تغییر از pending به doing) ---
    @action(detail=True, methods=['post'])
    def start_task(self, request, pk=None):
        work_log = self.get_object()
        if work_log.status != 'pending':
            return Response({'detail': 'فقط کارهای در حال انتظار را می‌توان شروع کرد.'}, status=status.HTTP_400_BAD_REQUEST)
        
        work_log.status = 'doing'
        work_log.start_time = timezone.now() # زمان شروع واقعی را الان ست می‌کنیم
        work_log.save()
        return Response(WorkLogSerializer(work_log).data)

    # --- اکشن ۲: پایان کار (تغییر به done یا suspended) ---
    @action(detail=True, methods=['post'])
    def finish_task(self, request, pk=None):
        with transaction.atomic():
            work_log = WorkLog.objects.select_for_update().get(pk=pk, user=request.user)

            target_status = request.data.get('status', 'done')
            if target_status not in ['done', 'suspended']:
                return Response({'detail': 'وضعیت نامعتبر است.'}, status=status.HTTP_400_BAD_REQUEST)

            if work_log.status == 'pending':
                return Response({'detail': 'این کار هنوز شروع نشده است.'}, status=status.HTTP_400_BAD_REQUEST)

            now = timezone.now()

            if target_status == 'suspended' and work_log.status != 'doing':
                return Response({'detail': 'فقط کارهای در حال انجام را می‌توان متوقف کرد.'}, status=status.HTTP_400_BAD_REQUEST)

            # محاسبه‌ی final_time فقط وقتی done می‌شود
            final_minutes = work_log.final_time

            if target_status == 'done':
                if work_log.manual_final_time is not None:
                    final_minutes = work_log.manual_final_time
                else:
                    total_seconds = (now - work_log.start_time).total_seconds()
                    pause = work_log.pause_duration or 0
                    net_seconds = max(0, total_seconds - pause)
                    final_minutes = int(net_seconds // 60)

            WorkLog.objects.filter(pk=work_log.pk, user=request.user).update(
                end_time=now,
                status=target_status,
                final_time=final_minutes
                # manual_final_time را دست نمی‌زنیم
            )

            work_log.refresh_from_db()
            return Response(WorkLogSerializer(work_log).data)

    # --- اکشن ۳: ادامه کار (بازگشت از حالت تعویق به در حال انجام) ---
    @action(detail=True, methods=['post'])
    def resume_task(self, request, pk=None):
        with transaction.atomic():
            work_log = WorkLog.objects.select_for_update().get(pk=pk, user=request.user)

            if work_log.status != 'suspended':
                return Response({'detail': 'فقط کارهای متوقف شده قابل ادامه هستند.'}, status=status.HTTP_400_BAD_REQUEST)

            if work_log.end_time:
                now = timezone.now()
                pause_seconds = (now - work_log.end_time).total_seconds()
                work_log.pause_duration = (work_log.pause_duration or 0) + int(pause_seconds)

            work_log.status = 'doing'
            work_log.end_time = None
            work_log.save()

            return Response(WorkLogSerializer(work_log).data)


# 4. ویو درخواست‌ها
class RequestTypeViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = RequestType.objects.filter(is_active=True)
    serializer_class = RequestTypeSerializer
    permission_classes = [permissions.IsAuthenticated]

class RequestViewSet(viewsets.ModelViewSet):
    serializer_class = RequestSerializer
    permission_classes = [permissions.IsAuthenticated]

    # کاربر فقط درخواست‌های خودش را ببیند
    def get_queryset(self):
        return Request.objects.filter(user=self.request.user).order_by('-created_at')

    # وقتی دکمه ثبت زده شد، کاربر جاری را به درخواست وصل کن
    def perform_create(self, serializer):
        serializer.save(user=self.request.user)


# 5. ویو ساعت کاری
class AttendanceViewSet(viewsets.ModelViewSet):
    serializer_class = AttendanceSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        return Attendance.objects.filter(user=self.request.user).order_by('-date')

    @action(detail=False, methods=['post'])
    def clock_in(self, request):
        now = timezone.now()
        tehran_tz = pytz.timezone('Asia/Tehran')
        local_now = timezone.localtime(now, tehran_tz)
        today = local_now.date()   # ← این خط مهمه (به‌جای now.date())

        attendance, created = Attendance.objects.get_or_create(
            user=request.user,
            date=today,
            defaults={'first_clock_in': now, 'total_seconds': 0}
        )

        if attendance.current_session_start:
            return Response({'detail': 'شما قبلاً وارد شده‌اید.'}, status=status.HTTP_400_BAD_REQUEST)

        attendance.current_session_start = now
        if not attendance.first_clock_in:
            attendance.first_clock_in = now
        attendance.save()

        return Response(AttendanceSerializer(attendance).data)

    @action(detail=False, methods=['post'])
    def clock_out(self, request):
        now = timezone.now()
        tehran_tz = pytz.timezone('Asia/Tehran')
        local_now = now.astimezone(tehran_tz)
        today = local_now.date()

        # 1. پیدا کردن ردیفی که "ساعت شروع باز" دارد
        # این ردیف ممکن است مال امروز باشد یا دیروز
        active_attendance = Attendance.objects.filter(user=request.user, current_session_start__isnull=False).last()

        if not active_attendance:
            return Response({'detail': 'ساعت کاری فعالی ندارید.'}, status=status.HTTP_400_BAD_REQUEST)

        start_time = active_attendance.current_session_start

        # --- سناریوی ۱: خروج در همان روز ---
        if active_attendance.date == today:
            diff = (now - start_time).total_seconds()
            active_attendance.total_seconds += int(diff)
            active_attendance.last_clock_out = now
            active_attendance.current_session_start = None # بستن نوبت
            active_attendance.save()

            final_seconds = active_attendance.total_seconds

        # --- سناریوی ۲: خروج در روز بعد (شیفت شبانه) ---
        else:
            # الف) بستن پرونده روز قبل (از شروع تا نیمه‌شب)
            # ساخت زمان نیمه‌شبِ فردایِ روزِ شروع
            next_day_date = active_attendance.date + timedelta(days=1)
            midnight_naive = datetime.combine(next_day_date, time.min)
            midnight = timezone.make_aware(midnight_naive, tehran_tz)

            seconds_yesterday = (midnight - start_time).total_seconds()
            active_attendance.total_seconds += int(seconds_yesterday)
            active_attendance.last_clock_out = midnight # خروج دیروز می‌شود نیمه‌شب
            active_attendance.current_session_start = None # بستن نوبت دیروز
            active_attendance.save()

            # ب) ساخت یا آپدیت پرونده امروز (از نیمه‌شب تا الان)
            attendance_today, created = Attendance.objects.get_or_create(
                user=request.user,
                date=today,
                defaults={
                    'first_clock_in': midnight, # شروع امروز می‌شود نیمه‌شب
                    'total_seconds': 0
                }
            )

            seconds_today = (now - midnight).total_seconds()
            attendance_today.total_seconds += int(seconds_today)
            attendance_today.last_clock_out = now
            attendance_today.current_session_start = None # امروز هم بسته شد
            attendance_today.save()

            # برای نمایش به کاربر، مجموع کارکرد امروز را می‌فرستیم
            final_seconds = attendance_today.total_seconds

        # فرمت پیام خروجی
        h = final_seconds // 3600
        m = (final_seconds % 3600) // 60

        return Response({
            'detail': 'خروج ثبت شد.',
            'duration_msg': f"مجموع امروز: {h:02}:{m:02}",
            'data': AttendanceSerializer(active_attendance).data
        })


# 6. ویو داشبورد
class DashboardView(viewsets.ViewSet):
    permission_classes = [permissions.IsAuthenticated]

    def list(self, request):
        user = request.user
        now = timezone.now()
        today_g = now.date()
        tehran_tz = pytz.timezone('Asia/Tehran')
        local_now = now.astimezone(tehran_tz)
        today_g = local_now.date()

        # --- 1. محاسبه وضعیت بر اساس سیستم جدید ---
        
        # آیا رکوردی هست که نوبت جاری آن باز باشد؟ (چه امروز چه دیروز)
        active_attendance = Attendance.objects.filter(user=user, current_session_start__isnull=False).last()
        attendance_status = 'in' if active_attendance else 'out'

        clock_in_time = ''
        if active_attendance:
            # نمایش ساعت شروع نوبت فعلی
            local_clock_in = active_attendance.current_session_start.astimezone(tehran_tz)
            clock_in_time = local_clock_in.strftime("%H:%M")

        # --- 2. محاسبه مجموع کارکرد امروز ---
        total_seconds_today = 0
        attendance_today = Attendance.objects.filter(user=user, date=today_g).first()
        
        if attendance_today:
            total_seconds_today = attendance_today.total_seconds
            
            # اگر الان هم مشغول کار است، مدت زمان از آخرین شروع تا الان را هم اضافه کن
            if attendance_today.current_session_start:
                diff = (now - attendance_today.current_session_start).total_seconds()
                total_seconds_today += diff

        # فرمت‌دهی ساعت
        hours = int(total_seconds_today // 3600)
        minutes = int((total_seconds_today % 3600) // 60)
        total_worked_display = f"{hours:02d}:{minutes:02d} ساعت"

        # --- 3. لیست کارهای فعال (بدون تغییر) ---
        active_tasks = WorkLog.objects.filter(user=user, status='doing').order_by('-start_time')
        active_tasks_data = WorkLogSerializer(active_tasks, many=True).data

        # --- 4. لیست همکاران (اصلاح شده برای جلوگیری از خطا) ---
        colleagues_data = []
        users = User.objects.filter(is_active=True).exclude(id=user.id)
        
        for u in users:
            # دریافت امن پروفایل
            profile = getattr(u, 'profile', None)
            
            colleagues_data.append({
                'id': u.id,
                'username': u.username,
                'name': u.get_full_name() or u.username,
                'daily_status': profile.daily_status if profile else "-",
                'phone': profile.phone if profile else "-",
                'avatar': profile.avatar.url if (profile and profile.avatar) else None
            })

        # --- 5. محاسبه هیت‌مپ سالانه (بر اساس مدل جدید) ---
        heatmap_data = []
        j_today = jdatetime.date.fromgregorian(date=today_g)
        j_start_of_year = jdatetime.date(j_today.year, 1, 1)
        g_start_of_year = j_start_of_year.togregorian()
        
        # دریافت کل رکوردهای امسال
        year_attendances = Attendance.objects.filter(user=user, date__gte=g_start_of_year)
        
        # تبدیل به دیکشنری {تاریخ_شمسی: ثانیه}
        daily_seconds_map = {}
        for att in year_attendances:
            # تبدیل تاریخ رکورد به شمسی
            j_date = jdatetime.date.fromgregorian(date=att.date)
            j_date_str = j_date.strftime('%Y-%m-%d')
            
            seconds = att.total_seconds
            # اگر مال امروز است و باز است، زمان زنده را هم اضافه کن
            if att.date == today_g and att.current_session_start:
                seconds += (now - att.current_session_start).total_seconds()
                
            daily_seconds_map[j_date_str] = daily_seconds_map.get(j_date_str, 0) + seconds

        days_in_year = 366 if j_today.isleap() else 365
        
        for i in range(days_in_year):
            loop_j_date = j_start_of_year + jdatetime.timedelta(days=i)
            loop_j_str = loop_j_date.strftime('%Y-%m-%d')
            
            # روزهای آینده را خالی بگذار
            if loop_j_date > j_today:
                heatmap_data.append("") 
                continue
            
            seconds = daily_seconds_map.get(loop_j_str, 0)
            h = seconds / 3600
            
            css_class = "day-show-level-1"
            if h > 10: css_class = "day-show-level-5"
            elif h > 7: css_class = "day-show-level-4"
            elif h > 4: css_class = "day-show-level-3"
            elif h > 0: css_class = "day-show-level-2"
            
            heatmap_data.append(css_class)

        return Response({
            'attendance_status': attendance_status,
            'clock_in_time': clock_in_time,
            'total_worked_today': total_worked_display,
            'total_seconds': total_seconds_today,
            'active_tasks': active_tasks_data,
            'colleagues': colleagues_data,
            'heatmap': heatmap_data
        })


# 7. ویو نوع فعالیت
class TaskTypeViewSet(viewsets.ReadOnlyModelViewSet):
    """
    لیست انواع فعالیت‌ها برای نمایش در فرم ثبت کار
    """
    queryset = TaskType.objects.filter(is_active=True)
    serializer_class = TaskTypeSerializer
    permission_classes = [permissions.IsAuthenticated]