import json
from io import BytesIO
from django.shortcuts import render, redirect, get_object_or_404
from django.views.generic import ListView, DetailView, CreateView, UpdateView, TemplateView, View
from django.urls import reverse_lazy, reverse
from django import forms
from django.db.models import Count, Q
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponse
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from .models import FleetUnit, Maintenance, Breakdown, PartRequest, Category, Document

# Forms
class FleetUnitForm(forms.ModelForm):
    class Meta:
        model = FleetUnit
        fields = ['name', 'category', 'model_name', 'vin', 'plate_number', 'year', 'photo', 'status', 'commissioning_date', 'notes']
        widgets = {
            'commissioning_date': forms.DateInput(attrs={'type': 'date'}),
            'notes': forms.Textarea(attrs={'rows': 3}),
        }

class MaintenanceForm(forms.ModelForm):
    class Meta:
        model = Maintenance
        fields = ['fleet_unit', 'm_type', 'planned_date', 'planned_runtime', 'mechanic', 'notes']
        widgets = {
            'planned_date': forms.DateInput(attrs={'type': 'date'}),
            'notes': forms.Textarea(attrs={'rows': 3}),
        }

class BreakdownForm(forms.ModelForm):
    class Meta:
        model = Breakdown
        fields = ['fleet_unit', 'system_node', 'description', 'photo', 'status', 'notes']
        widgets = {
            'description': forms.Textarea(attrs={'rows': 3}),
            'notes': forms.Textarea(attrs={'rows': 3}),
        }

class PartRequestForm(forms.ModelForm):
    class Meta:
        model = PartRequest
        fields = ['fleet_unit', 'breakdown', 'part_name', 'article_number', 'quantity', 'photo', 'notes']
        widgets = {
            'notes': forms.Textarea(attrs={'rows': 3}),
        }

# Views
class IndexView(TemplateView):
    template_name = 'core/index.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['total_units'] = FleetUnit.objects.count()
        context['active_units'] = FleetUnit.objects.filter(status='active').count()
        context['broken_units'] = FleetUnit.objects.filter(status='broken').count()
        context['repair_units'] = FleetUnit.objects.filter(status='repair').count()
        
        context['status_counts'] = FleetUnit.objects.values('status').annotate(total=Count('status'))
        context['recent_maintenances'] = Maintenance.objects.all().order_by('-planned_date')[:5]
        context['recent_breakdowns'] = Breakdown.objects.all().order_by('-date')[:5]
        
        return context

# Fleet Views
class FleetListView(ListView):
    model = FleetUnit
    template_name = 'core/fleet_list.html'
    context_object_name = 'units'
    paginate_by = 12

    def get_queryset(self):
        queryset = super().get_queryset()
        status = self.request.GET.get('status')
        if status:
            queryset = queryset.filter(status=status)
        search = self.request.GET.get('search')
        if search:
            queryset = queryset.filter(
                Q(name__icontains=search) | 
                Q(plate_number__icontains=search) | 
                Q(vin__icontains=search)
            )
        return queryset

class FleetDetailView(DetailView):
    model = FleetUnit
    template_name = 'core/fleet_detail.html'
    context_object_name = 'unit'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['maintenances'] = self.object.maintenances.all().order_by('-planned_date')
        context['breakdowns'] = self.object.breakdowns.all().order_by('-date')
        context['part_requests'] = self.object.part_requests.all().order_by('-created_at')
        return context

class FleetCreateView(CreateView):
    model = FleetUnit
    template_name = 'core/fleet_form.html'
    form_class = FleetUnitForm
    success_url = reverse_lazy('fleet_list')

class FleetUpdateView(UpdateView):
    model = FleetUnit
    template_name = 'core/fleet_form.html'
    form_class = FleetUnitForm
    
    def get_success_url(self):
        return reverse_lazy('fleet_detail', kwargs={'pk': self.object.pk})

# Maintenance Views
class MaintenanceListView(ListView):
    model = Maintenance
    template_name = 'core/maintenance_list.html'
    context_object_name = 'maintenances'
    paginate_by = 15

class MaintenanceDetailView(DetailView):
    model = Maintenance
    template_name = 'core/maintenance_detail.html'
    context_object_name = 'maintenance'

class MaintenanceCreateView(CreateView):
    model = Maintenance
    template_name = 'core/maintenance_form.html'
    form_class = MaintenanceForm
    success_url = reverse_lazy('maintenance_list')
    
    def get_initial(self):
        initial = super().get_initial()
        fleet_id = self.request.GET.get('fleet_unit')
        if fleet_id:
            initial['fleet_unit'] = get_object_or_404(FleetUnit, pk=fleet_id)
        return initial

    def form_valid(self, form):
        m_type = form.cleaned_data.get('m_type')
        checklist = []
        if m_type == 'TO-250':
            checklist = [{"task": "Замена масла в двигателе", "done": False}, {"task": "Замена масляного фильтра", "done": False}]
        elif m_type == 'TO-500':
            checklist = [{"task": "Замена масла в двигателе", "done": False}, {"task": "Замена фильтров", "done": False}, {"task": "Осмотр ходовой", "done": False}]
        else:
            checklist = [{"task": "Общий осмотр", "done": False}]
        
        form.instance.checklist = checklist
        return super().form_valid(form)

class MaintenanceUpdateView(UpdateView):
    model = Maintenance
    template_name = 'core/maintenance_form.html'
    form_class = MaintenanceForm
    
    def get_success_url(self):
        return reverse('maintenance_detail', kwargs={'pk': self.object.pk})

class MaintenanceProcessView(View):
    def post(self, request, pk):
        maintenance = get_object_or_404(Maintenance, pk=pk)
        task_index = request.POST.get('task_index')
        done = request.POST.get('done') == 'true'
        
        if task_index is not None:
            idx = int(task_index)
            if 0 <= idx < len(maintenance.checklist):
                maintenance.checklist[idx]['done'] = done
                maintenance.save()
        
        return redirect('maintenance_detail', pk=pk)

class MaintenanceCompleteView(View):
    def post(self, request, pk):
        maintenance = get_object_or_404(Maintenance, pk=pk)
        maintenance.status = 'completed'
        maintenance.actual_date = request.POST.get('actual_date') or None
        maintenance.actual_runtime = request.POST.get('actual_runtime') or None
        maintenance.parts_used = request.POST.get('parts_used')
        maintenance.save()
        
        unit = maintenance.fleet_unit
        unit.status = 'active'
        unit.save()
        
        return redirect('maintenance_detail', pk=pk)

class MaintenancePDFView(View):
    def get(self, request, pk):
        maintenance = get_object_or_404(Maintenance, pk=pk)
        buffer = BytesIO()
        p = canvas.Canvas(buffer, pagesize=A4)
        
        # Draw PDF content (basic for now as we don't have Cyrillic fonts loaded by default in reportlab without setup)
        # Note: For real Cyrillic support we need to register a TTF font.
        p.drawString(100, 800, f"Maintenance Act - {maintenance.m_type}")
        p.drawString(100, 780, f"Unit: {maintenance.fleet_unit.name}")
        p.drawString(100, 760, f"Date: {maintenance.actual_date}")
        p.drawString(100, 740, f"Runtime: {maintenance.actual_runtime}")
        
        y = 700
        p.drawString(100, y, "Checklist:")
        y -= 20
        for item in maintenance.checklist:
            status = "[x]" if item['done'] else "[ ]"
            p.drawString(120, y, f"{status} {item['task']}")
            y -= 20
        
        p.showPage()
        p.save()
        
        buffer.seek(0)
        return HttpResponse(buffer, content_type='application/pdf', 
                            headers={'Content-Disposition': f'attachment; filename="maintenance-{pk}.pdf"'})

# Breakdown Views
class BreakdownListView(ListView):
    model = Breakdown
    template_name = 'core/breakdown_list.html'
    context_object_name = 'breakdowns'

class BreakdownCreateView(CreateView):
    model = Breakdown
    form_class = BreakdownForm
    template_name = 'core/breakdown_form.html'
    
    def get_initial(self):
        initial = super().get_initial()
        fleet_id = self.request.GET.get('fleet_unit')
        if fleet_id:
            initial['fleet_unit'] = get_object_or_404(FleetUnit, pk=fleet_id)
        return initial

    def form_valid(self, form):
        response = super().form_valid(form)
        unit = self.object.fleet_unit
        if self.object.status == 'reported':
            unit.status = 'broken'
        elif self.object.status == 'need_part':
            unit.status = 'waiting_parts'
        unit.save()
        return response

    def get_success_url(self):
        return reverse('fleet_detail', kwargs={'pk': self.object.fleet_unit.pk})

# Part Request Views
class PartRequestListView(ListView):
    model = PartRequest
    template_name = 'core/part_request_list.html'
    context_object_name = 'requests'

class PartRequestCreateView(CreateView):
    model = PartRequest
    form_class = PartRequestForm
    template_name = 'core/part_request_form.html'
    
    def get_initial(self):
        initial = super().get_initial()
        breakdown_id = self.request.GET.get('breakdown')
        if breakdown_id:
            breakdown = get_object_or_404(Breakdown, pk=breakdown_id)
            initial['breakdown'] = breakdown
            initial['fleet_unit'] = breakdown.fleet_unit
        fleet_id = self.request.GET.get('fleet_unit')
        if fleet_id:
            initial['fleet_unit'] = get_object_or_404(FleetUnit, pk=fleet_id)
        return initial

    def get_success_url(self):
        return reverse('fleet_detail', kwargs={'pk': self.object.fleet_unit.pk})