from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .models import Resource, AppointmentType, AvailabilityRule, BlockedPeriod, ExceptionDay, CustomField, Business
from .forms import ResourceForm, AppointmentTypeForm, AvailabilityRuleForm, BlockedPeriodForm, ExceptionDayForm, CustomFieldForm, BusinessForm

from django.http import JsonResponse
from django.utils import timezone
from django.utils.text import slugify
import re
import json

@login_required
def appointment_type_list(request):
    types = AppointmentType.objects.filter(user=request.user, deleted_at__isnull=True).order_by('-created_at')
    form = AppointmentTypeForm(user=request.user)
    return render(request, 'scheduler/appointment_type_list.html', {'types': types, 'form': form})

@login_required
def appt_type_upsert(request, pk=None):
    if request.method == 'POST':
        instance = get_object_or_404(AppointmentType, pk=pk, user=request.user) if pk else None
        form = AppointmentTypeForm(request.POST, instance=instance, user=request.user)
        
        if form.is_valid():
            appt_type = form.save(commit=False)
            if not appt_type.slug:
                appt_type.slug = slugify(appt_type.name)
            
            # Check for existing active slug by this user
            existing = AppointmentType.objects.filter(
                user=request.user, 
                slug=appt_type.slug, 
                deleted_at__isnull=True
            ).exclude(pk=pk).exists()

            if existing:
                return JsonResponse({
                    'success': False,
                    'error': f"Ya tienes un servicio activo con el nombre '{appt_type.name}'. Por favor elige otro."
                }, status=400)

            appt_type.user = request.user
            appt_type.save()
            form.save_m2m() # Importante antes de la auto-asignación lógica

            # Lógica de auto-asignación de profesionales si no hay ninguno seleccionado
            if appt_type.resources.count() == 0:
                all_resources = Resource.objects.filter(user=request.user, deleted_at__isnull=True, is_active=True)
                appt_type.resources.set(all_resources)

            return JsonResponse({'success': True, 'message': "Servicio guardado correctamente."})
        else:
            # Formatear errores del formulario para el frontend
            error_msg = "Error en el formulario: "
            for field, errors in form.errors.items():
                error_msg += f"{field}: {', '.join(errors)}. "
            return JsonResponse({'success': False, 'error': error_msg}, status=400)
            
    return JsonResponse({'success': False, 'error': "Método no permitido."}, status=405)

@login_required
def appt_type_delete(request, pk):
    if request.method == 'POST':
        appt_type = get_object_or_404(AppointmentType, pk=pk, user=request.user)
        appt_type.deleted_at = timezone.now()
        appt_type.is_active = False
        appt_type.save()
        return JsonResponse({'success': True, 'message': "Servicio eliminado."})
    return JsonResponse({'success': False, 'error': "Método no permitido."}, status=405)

@login_required
def appt_type_get(request, pk):
    appt_type = get_object_or_404(AppointmentType, pk=pk, user=request.user)
    data = {
        'id': appt_type.id,
        'name': appt_type.name,
        'slug': appt_type.slug,
        'description': appt_type.description,
        'duration_minutes': appt_type.duration_minutes,
        'slot_capacity': appt_type.slot_capacity,
        'is_active': appt_type.is_active,
        'resource_ids': list(appt_type.resources.values_list('id', flat=True)),
    }
    return JsonResponse(data)

@login_required
def resource_list(request):
    from booking.models import Appointment
    resources = Resource.objects.filter(user=request.user, deleted_at__isnull=True).order_by('-created_at')
    active_count = resources.filter(is_active=True).count()
    
    # Analytics for the chart: Appointments this month per resource
    today = timezone.localdate()
    start_of_month = today.replace(day=1)
    
    resource_stats = []
    for res in resources:
        count = Appointment.objects.filter(
            resource=res,
            date__range=[start_of_month, today],
            status='confirmed'
        ).count()
        resource_stats.append({
            'name': res.name,
            'count': count
        })

    form = ResourceForm()
    return render(request, 'scheduler/resource_list.html', {
        'resources': resources, 
        'form': form,
        'active_count': active_count,
        'resource_stats_json': json.dumps(resource_stats)
    })

@login_required
def resource_upsert(request, pk=None):
    if request.method == 'POST':
        instance = get_object_or_404(Resource, pk=pk, user=request.user) if pk else None
        form = ResourceForm(request.POST, request.FILES, instance=instance)

        if form.is_valid():
            res = form.save(commit=False)
            res.user = request.user
            res.save()
            return JsonResponse({'success': True, 'message': "Profesional guardado correctamente."})
        return JsonResponse({'success': False, 'errors': form.errors}, status=400)
    return JsonResponse({'success': False, 'error': "Método no permitido."}, status=405)

@login_required
def resource_delete(request, pk):
    if request.method == 'POST':
        res = get_object_or_404(Resource, pk=pk, user=request.user)
        res.deleted_at = timezone.now()
        res.is_active = False
        res.save()
        return JsonResponse({'success': True, 'message': "Profesional eliminado."})
    return JsonResponse({'success': False, 'error': "Método no permitido."}, status=405)

@login_required
def resource_get(request, pk):
    res = get_object_or_404(Resource, pk=pk, user=request.user)
    return JsonResponse({
        'id': res.id,
        'name': res.name,
        'email': res.email or '',
        'photo_url': res.photo.url if res.photo else None,
        'is_active': res.is_active,
    })

@login_required
def business_settings(request):
    business, created = Business.objects.get_or_create(
        user=request.user,
        defaults={'name': request.user.get_full_name() or request.user.email}
    )
    if request.method == 'POST':
        form = BusinessForm(request.POST, request.FILES, instance=business)
        if form.is_valid():
            form.save()
            messages.success(request, "Configuración de negocio actualizada.")
            return redirect('business_settings')
    else:
        form = BusinessForm(instance=business)
    return render(request, 'scheduler/business_settings.html', {'form': form, 'business': business})

@login_required
def weekly_availability_list(request):
    availability = AvailabilityRule.objects.filter(user=request.user).order_by('weekday', 'start_time')
    form = AvailabilityRuleForm(user=request.user)
    return render(request, 'scheduler/weekly_availability.html', {'availability': availability, 'form': form})

@login_required
def availability_upsert(request, pk=None):
    if request.method == 'POST':
        instance = get_object_or_404(AvailabilityRule, pk=pk, user=request.user) if pk else None
        form = AvailabilityRuleForm(request.POST, instance=instance, user=request.user)
        if form.is_valid():
            item = form.save(commit=False)
            item.user = request.user
            item.save()
            return JsonResponse({'success': True, 'message': "Regla de disponibilidad guardada."})
        else:
            return JsonResponse({'success': False, 'errors': form.errors}, status=400)
    return JsonResponse({'success': False, 'error': "Método no permitido."}, status=405)

@login_required
def availability_delete(request, pk):
    if request.method == 'POST':
        item = get_object_or_404(AvailabilityRule, pk=pk, user=request.user)
        item.delete()
        return JsonResponse({'success': True, 'message': "Regla de disponibilidad eliminada."})
    return JsonResponse({'success': False, 'error': "Método no permitido."}, status=405)

@login_required
def availability_get(request, pk):
    item = get_object_or_404(AvailabilityRule, pk=pk, user=request.user)
    data = {
        'id': item.id,
        'resource_id': item.resource.id if item.resource else '',
        'weekday': item.weekday,
        'start_time': item.start_time.strftime('%H:%M'),
        'end_time': item.end_time.strftime('%H:%M'),
        'break_start': item.break_start.strftime('%H:%M') if item.break_start else '',
        'break_end': item.break_end.strftime('%H:%M') if item.break_end else '',
        'is_active': item.is_active,
    }
    return JsonResponse(data)

@login_required
def blocked_day_list(request):
    days = BlockedPeriod.objects.filter(user=request.user).order_by('-start_date')
    resources = Resource.objects.filter(user=request.user, deleted_at__isnull=True)
    form = BlockedPeriodForm(user=request.user)
    return render(request, 'scheduler/blocked_days.html', {
        'days': days, 
        'form': form,
        'resources': resources
    })

@login_required
def blocked_day_upsert(request, pk=None):
    if request.method == 'POST':
        instance = get_object_or_404(BlockedPeriod, pk=pk, user=request.user) if pk else None
        form = BlockedPeriodForm(request.POST, instance=instance, user=request.user)
        if form.is_valid():
            item = form.save(commit=False)
            item.user = request.user
            item.save()
            return JsonResponse({'success': True, 'message': "Periodo bloqueado guardado."})
        return JsonResponse({'success': False, 'errors': form.errors}, status=400)
    return JsonResponse({'success': False, 'error': "Método no permitido."}, status=405)

@login_required
def blocked_day_get(request, pk):
    item = get_object_or_404(BlockedPeriod, pk=pk, user=request.user)
    data = {
        'id': item.id,
        'resource_id': item.resource.id if item.resource else '',
        'start_date': item.start_date.strftime('%Y-%m-%d'),
        'end_date': item.end_date.strftime('%Y-%m-%d'),
        'reason': item.reason,
        'is_active': item.is_active,
    }
    return JsonResponse(data)

@login_required
def blocked_day_update(request, pk):
    item = get_object_or_404(BlockedPeriod, pk=pk, user=request.user)
    if request.method == 'POST':
        form = BlockedPeriodForm(request.POST, instance=item, user=request.user)
        if form.is_valid():
            form.save()
            return JsonResponse({'success': True, 'message': 'Periodo actualizado correctamente'})
        return JsonResponse({'success': False, 'errors': form.errors}, status=400)
    return JsonResponse({'error': 'Invalid method'}, status=405)

@login_required
def blocked_day_delete(request, pk):
    if request.method == 'POST':
        item = get_object_or_404(BlockedPeriod, pk=pk, user=request.user)
        item.delete()
        return JsonResponse({'success': True, 'message': "Periodo bloqueado eliminado."})
    return JsonResponse({'success': False, 'error': "Método no permitido."}, status=405)

@login_required
def exception_list(request):
    exceptions = ExceptionDay.objects.filter(user=request.user).order_by('-date')
    form = ExceptionDayForm(user=request.user)
    return render(request, 'scheduler/exceptions.html', {'exceptions': exceptions, 'form': form})

@login_required
def exception_upsert(request, pk=None):
    if request.method == 'POST':
        instance = get_object_or_404(ExceptionDay, pk=pk, user=request.user) if pk else None
        form = ExceptionDayForm(request.POST, instance=instance, user=request.user)
        if form.is_valid():
            item = form.save(commit=False)
            item.user = request.user
            item.save()
            return JsonResponse({'success': True, 'message': "Excepción de día guardada."})
        return JsonResponse({'success': False, 'errors': form.errors}, status=400)
    return JsonResponse({'success': False, 'error': "Método no permitido."}, status=405)

@login_required
def exception_delete(request, pk):
    if request.method == 'POST':
        item = get_object_or_404(ExceptionDay, pk=pk, user=request.user)
        item.delete()
        return JsonResponse({'success': True, 'message': "Excepción eliminada."})
    return JsonResponse({'success': False, 'error': "Método no permitido."}, status=405)

@login_required
def exception_get(request, pk):
    item = get_object_or_404(ExceptionDay, pk=pk, user=request.user)
    return JsonResponse({
        'id': item.id,
        'resource_id': item.resource.id if item.resource else '',
        'date': item.date.strftime('%Y-%m-%d'),
        'is_available': item.is_available,
        'start_time': item.start_time.strftime('%H:%M') if item.start_time else '',
        'end_time': item.end_time.strftime('%H:%M') if item.end_time else '',
        'reason': item.reason,
    })

@login_required
def custom_field_list(request):
    fields = CustomField.objects.filter(user=request.user)
    if request.method == 'POST':
        form = CustomFieldForm(request.POST)
        if form.is_valid():
            item = form.save(commit=False)
            item.user = request.user
            item.save()
            return redirect('custom_field_list')
    else:
        form = CustomFieldForm()
    return render(request, 'scheduler/custom_field_list.html', {'fields': fields, 'form': form})
