from django.views.generic import ListView, CreateView, UpdateView, TemplateView, DetailView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from .models import Employee, Department, Attendance, LeaveRequest, JobPosition, BiometricDevice
from .forms import EmployeeForm
from django.db.models import Count
from django.shortcuts import get_object_or_404, redirect
from django.contrib import messages
import socket
from django.utils import timezone

class HRDashboardView(LoginRequiredMixin, TemplateView):
    template_name = 'hr/dashboard.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['total_employees'] = Employee.objects.count()
        context['active_employees'] = Employee.objects.filter(status='active').count()
        context['departments_count'] = Department.objects.count()
        context['pending_leaves'] = LeaveRequest.objects.filter(status='pending').count()
        return context

class EmployeeListView(LoginRequiredMixin, ListView):
    model = Employee
    template_name = 'hr/employee_list.html'
    context_object_name = 'employees'

class EmployeeCreateView(LoginRequiredMixin, CreateView):
    model = Employee
    form_class = EmployeeForm
    template_name = 'hr/employee_form.html'
    success_url = reverse_lazy('hr:employee_list')
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = _("Add New Employee")
        return context

class EmployeeUpdateView(LoginRequiredMixin, UpdateView):
    model = Employee
    form_class = EmployeeForm
    template_name = 'hr/employee_form.html'
    success_url = reverse_lazy('hr:employee_list')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = _("Edit Employee")
        return context

class EmployeeDetailView(LoginRequiredMixin, DetailView):
    model = Employee
    template_name = 'hr/employee_detail.html'

class DepartmentListView(LoginRequiredMixin, ListView):
    model = Department
    template_name = 'hr/department_list.html'
    context_object_name = 'departments'

class AttendanceListView(LoginRequiredMixin, ListView):
    model = Attendance
    template_name = 'hr/attendance_list.html'
    context_object_name = 'attendances'
    paginate_by = 50

class LeaveRequestListView(LoginRequiredMixin, ListView):
    model = LeaveRequest
    template_name = 'hr/leave_list.html'
    context_object_name = 'leaves'

class LeaveRequestCreateView(LoginRequiredMixin, CreateView):
    model = LeaveRequest
    fields = ['employee', 'leave_type', 'start_date', 'end_date', 'reason']
    template_name = 'hr/leave_form.html'
    success_url = reverse_lazy('hr:leave_list')

class BiometricDeviceListView(LoginRequiredMixin, ListView):
    model = BiometricDevice
    template_name = 'hr/biometric_device_list.html'
    context_object_name = 'devices'

class BiometricDeviceCreateView(LoginRequiredMixin, CreateView):
    model = BiometricDevice
    fields = ['name', 'ip_address', 'port', 'device_type', 'status']
    template_name = 'hr/biometric_device_form.html'
    success_url = reverse_lazy('hr:device_list')
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = _("Add Biometric Device")
        return context

class BiometricDeviceUpdateView(LoginRequiredMixin, UpdateView):
    model = BiometricDevice
    fields = ['name', 'ip_address', 'port', 'device_type', 'status']
    template_name = 'hr/biometric_device_form.html'
    success_url = reverse_lazy('hr:device_list')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = _("Edit Biometric Device")
        return context

class BiometricDeviceDeleteView(LoginRequiredMixin, DeleteView):
    model = BiometricDevice
    template_name = 'hr/biometric_device_confirm_delete.html'
    success_url = reverse_lazy('hr:device_list')

def test_device_connection(request, pk):
    device = get_object_or_404(BiometricDevice, pk=pk)
    
    try:
        # Simple socket connect to see if port is open (timeout 3s)
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(3)
        result = sock.connect_ex((device.ip_address, device.port))
        sock.close()
        
        if result == 0:
            messages.success(request, _("Connection successful! Device is online."))
            device.status = 'active'
            device.last_sync = timezone.now()
            device.save()
        else:
            # If failed, we still report it but since this is often run in dev/cloud
            # where the device isn't reachable, we warn.
            messages.warning(request, _("Connection failed: Port closed or host unreachable. (Error Code: %(code)s)") % {'code': result})
            device.status = 'inactive'
            device.save()
            
    except Exception as e:
         messages.error(request, _("Connection Error: %(error)s") % {'error': str(e)})

    return redirect('hr:device_list')

def sync_device_logs(request, pk):
    device = get_object_or_404(BiometricDevice, pk=pk)
    result = device.sync_data() # This method we added to the model
    
    if result.get('error'):
        messages.error(request, _("Sync Failed: %(error)s") % {'error': result['error']})
    else:
        messages.success(request, _("Sync Successful! Fetched %(total)s records, %(new)s new.") % {'total': result['total'], 'new': result['new']})
        
    return redirect('hr:device_list')