from django.shortcuts import render, get_object_or_404, redirect
from django.urls import reverse

from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import JsonResponse
from django.views.decorators.http import require_POST, require_GET
from django.db import transaction
from django.contrib.auth import get_user_model
from .models import Process, ProcessInstance, StepInstance
from wells.models import Well
from accounts.models import Profile
from accounts.forms import CustomerForm
from wells.forms import WellForm
from wells.models import WaterMeterManufacturer


@login_required
def request_list(request):
    """نمایش لیست درخواست‌ها با جدول و مدال ایجاد"""
    instances = ProcessInstance.objects.select_related('well', 'representative', 'requester').prefetch_related('step_instances__step').filter(is_deleted=False).order_by('-created')
    processes = Process.objects.filter(is_active=True)
    manufacturers = WaterMeterManufacturer.objects.all().order_by('name')
    
    # Calculate progress for each instance
    instances_with_progress = []
    for instance in instances:
        total_steps = instance.process.steps.count()
        completed_steps = instance.step_instances.filter(status='completed').count()
        progress_percentage = (completed_steps / total_steps * 100) if total_steps > 0 else 0
        
        instances_with_progress.append({
            'instance': instance,
            'progress_percentage': round(progress_percentage),
            'completed_steps': completed_steps,
            'total_steps': total_steps,
        })
    
    # Summary stats for header cards
    total_count = instances.count()
    completed_count = instances.filter(status='completed').count()
    in_progress_count = instances.filter(status='in_progress').count()
    pending_count = instances.filter(status='pending').count()
    
    return render(request, 'processes/request_list.html', {
        'instances_with_progress': instances_with_progress,
        'customer_form': CustomerForm(),
        'well_form': WellForm(),
        'processes': processes,
        'manufacturers': manufacturers,
        'total_count': total_count,
        'completed_count': completed_count,
        'in_progress_count': in_progress_count,
        'pending_count': pending_count,
    })


@require_GET
@login_required
def lookup_well_by_subscription(request):
    sub = request.GET.get('water_subscription_number', '').strip()
    if not sub:
        return JsonResponse({'ok': False, 'error': 'شماره اشتراک الزامی است'}, status=400)
    try:
        well = Well.objects.select_related('representative', 'water_meter_manufacturer').get(water_subscription_number=sub)
        data = {
            'id': well.id,
            'water_subscription_number': well.water_subscription_number,
            'electricity_subscription_number': well.electricity_subscription_number,
            'water_meter_serial_number': well.water_meter_serial_number,
            'water_meter_old_serial_number': well.water_meter_old_serial_number,
            'water_meter_manufacturer': well.water_meter_manufacturer.id if well.water_meter_manufacturer else None,
            'utm_x': str(well.utm_x) if well.utm_x is not None else None,
            'utm_y': str(well.utm_y) if well.utm_y is not None else None,
            'utm_zone': well.utm_zone,
            'utm_hemisphere': well.utm_hemisphere,
            'well_power': well.well_power,
            'reference_letter_number': well.reference_letter_number,
            'reference_letter_date': well.reference_letter_date.isoformat() if well.reference_letter_date else None,
            'representative_letter_file_url': well.representative_letter_file.url if well.representative_letter_file else '',
            'representative_letter_file_name': well.representative_letter_file.name.split('/')[-1] if well.representative_letter_file else '',
            'representative_id': well.representative.id if well.representative else None,
            'representative_full_name': well.representative.get_full_name() if well.representative else None,
        }
        return JsonResponse({'ok': True, 'exists': True, 'well': data})
    except Well.DoesNotExist:
        return JsonResponse({'ok': True, 'exists': False})


@require_GET
@login_required
def lookup_representative_by_national_code(request):
    national_code = request.GET.get('national_code', '').strip()
    if not national_code:
        return JsonResponse({'ok': False, 'error': 'کد ملی الزامی است'}, status=400)
    profile = Profile.objects.select_related('user').filter(national_code=national_code).first()
    if not profile:
        return JsonResponse({'ok': True, 'exists': False})
    user = profile.user
    return JsonResponse({
        'ok': True,
        'exists': True,
        'user': {
            'id': user.id,
            'username': user.username,
            'first_name': user.first_name,
            'last_name': user.last_name,
            'full_name': user.get_full_name(),
            'profile': {
                'national_code': profile.national_code,
                'phone_number_1': profile.phone_number_1,
                'phone_number_2': profile.phone_number_2,
                'card_number': profile.card_number,
                'account_number': profile.account_number,
                'bank_name': profile.bank_name,
                'address': profile.address,
            }
        }
    })


@require_POST
@login_required
@transaction.atomic
def create_request_with_entities(request):
    """ایجاد/به‌روزرسانی چاه و نماینده و سپس ایجاد درخواست"""
    User = get_user_model()
    process_id = request.POST.get('process')
    process = Process.objects.get(id=process_id)
    description = request.POST.get('description', '')
    # Well fields
    water_subscription_number = request.POST.get('water_subscription_number')
    well_id = request.POST.get('well_id')  # optional if existing
    # Representative fields
    representative_id = request.POST.get('representative_id')

    if not process_id:
        return JsonResponse({'ok': False, 'errors': {'request': {'process': ['فرآیند الزامی است']}}}, status=400)
    if not water_subscription_number:
        return JsonResponse({'ok': False, 'errors': {'well': {'water_subscription_number': ['شماره اشتراک آب الزامی است']}}}, status=400)
    if not representative_id and not request.POST.get('national_code'):
        return JsonResponse({'ok': False, 'errors': {'customer': {'national_code': ['کد ملی نماینده را وارد کنید یا دکمه بررسی/افزودن نماینده را بزنید']}}}, status=400)

    representative_user = None
    representative_profile = None
    if representative_id:
        representative_profile = Profile.objects.select_related('user').filter(user_id=representative_id).first()
        if not representative_profile:
            return JsonResponse({'ok': False, 'errors': {'customer': {'__all__': ['نماینده انتخاب‌شده یافت نشد']}}}, status=400)
        # Use CustomerForm with request.POST data, merging with existing values
        customer_form = CustomerForm(request.POST, instance=representative_profile)
        customer_form.request = request
        if not customer_form.is_valid():
            return JsonResponse({'ok': False, 'errors': {'customer': customer_form.errors}}, status=400)
        representative_profile = customer_form.save()
        representative_user = representative_profile.user
    else:
        # Use CustomerForm to validate/create/update representative profile by national code
        profile_instance = None
        national_code = request.POST.get('national_code')
        if national_code:
            profile_instance = Profile.objects.filter(national_code=national_code).first()
        customer_form = CustomerForm(request.POST, instance=profile_instance)
        customer_form.request = request
        if not customer_form.is_valid():
            return JsonResponse({'ok': False, 'errors': {'customer': customer_form.errors}}, status=400)
        representative_profile = customer_form.save()
        representative_user = representative_profile.user

    # Resolve/create/update well
    # Build WellForm data from POST
    well = None
    if well_id:
        well = Well.objects.filter(id=well_id).first()
        if not well:
            return JsonResponse({'ok': False, 'error': 'شناسه چاه نامعتبر است'}, status=400)
    else:
        existing = Well.objects.filter(water_subscription_number=water_subscription_number).first()
        if existing:
            well = existing

    well_data = request.POST.copy()
    # Ensure representative set from created/selected user if not provided
    if representative_user and not well_data.get('representative'):
        well_data['representative'] = str(representative_user.id)
    if not well_data.get('water_subscription_number'):
        well_data['water_subscription_number'] = water_subscription_number

    # Preserve existing values on partial updates
    if well:
        for field_name in WellForm.Meta.fields:
            if field_name in ('representative_letter_file',):
                # File field handled via request.FILES; skip if not provided
                continue
            incoming = well_data.get(field_name, None)
            if incoming is None or incoming == '':
                current_value = getattr(well, field_name, None)
                if current_value is None:
                    continue
                # Convert FK to id
                if hasattr(current_value, 'pk'):
                    well_data[field_name] = str(current_value.pk)
                else:
                    # Convert dates/decimals/others to string
                    try:
                        well_data[field_name] = current_value.isoformat()  # dates
                    except AttributeError:
                        well_data[field_name] = str(current_value)

    well_form = WellForm(well_data, request.FILES, instance=well)
    if not well_form.is_valid():
        return JsonResponse({'ok': False, 'errors': {'well': well_form.errors}}, status=400)
    # Save with ability to remove existing file
    well = well_form.save(commit=False)
    try:
        if request.POST.get('remove_file') == 'true' and getattr(well, 'representative_letter_file', None):
            well.representative_letter_file.delete(save=False)
            well.representative_letter_file = None
    except Exception:
        pass
    well.save()
    # Auto fill geo ownership from current user profile if available
    current_profile = getattr(request.user, 'profile', None)
    if current_profile:
        if hasattr(well, 'affairs'):
            well.affairs = current_profile.affairs
        if hasattr(well, 'county'):
            well.county = current_profile.county
        if hasattr(well, 'broker'):
            well.broker = current_profile.broker
        well.save()

    # Create request instance
    instance = ProcessInstance.objects.create(
        process=process,
        description=description,
        well=well,
        representative=representative_user,
        requester=request.user,
        broker=request.user.profile.broker if request.user.profile else None,
        status='pending',
        priority='medium',
    )
    # ایجاد نمونه‌های مرحله بر اساس مراحل فرآیند و تنظیم مرحله فعلی
    for step in process.steps.all().order_by('order'):
        StepInstance.objects.create(
            process_instance=instance,
            step=step
        )
    first_step = process.steps.all().order_by('order').first()
    if first_step:
        instance.current_step = first_step
        instance.status = 'in_progress'
        instance.save()

    redirect_url = reverse('processes:instance_steps', args=[instance.id])
    return JsonResponse({'ok': True, 'instance_id': instance.id, 'redirect': redirect_url})


@require_POST
@login_required
def delete_request(request, instance_id):
    """حذف درخواست"""
    instance = get_object_or_404(ProcessInstance, id=instance_id)
    code = instance.code
    if instance.status == 'completed':
        return JsonResponse({
            'success': False,
            'message': 'درخواست تکمیل شده نمی‌تواند حذف شود'
        })
    instance.delete()
    return JsonResponse({
        'success': True,
        'message': f'درخواست {code} با موفقیت حذف شد'
    })


@login_required
def step_detail(request, instance_id, step_id):
    """نمایش جزئیات مرحله خاص"""
    instance = get_object_or_404(
        ProcessInstance.objects.select_related('process', 'well', 'requester', 'representative', 'representative__profile'),
        id=instance_id
    )
    step = get_object_or_404(instance.process.steps, id=step_id)
    # If the request is already completed, redirect to read-only summary page
    if instance.status == 'completed':
        return redirect('processes:instance_summary', instance_id=instance.id)
    
    # جلوگیری از پرش به مراحل آینده: فقط اجازه نمایش مرحله جاری یا مراحل تکمیل‌شده
    try:
        if instance.current_step and step.order > instance.current_step.order:
            messages.error(request, 'ابتدا مراحل قبلی را تکمیل کنید.')
            return redirect('processes:step_detail', instance_id=instance.id, step_id=instance.current_step.id)
    except Exception:
        pass

    # بررسی دسترسی به مرحله
    if not instance.can_access_step(step):
        messages.error(request, 'شما به این مرحله دسترسی ندارید. ابتدا مراحل قبلی را تکمیل کنید.')
        return redirect('processes:request_list')
    
    # هدایت به view مناسب بر اساس نوع مرحله
    if step.order == 1:  # مرحله اول - انتخاب اقلام
        return redirect('invoices:quote_step', instance_id=instance.id, step_id=step.id)
    elif step.order == 2:  # مرحله دوم - صدور پیش‌فاکتور
        return redirect('invoices:quote_preview_step', instance_id=instance.id, step_id=step.id)
    elif step.order == 3:  # مرحله سوم - ثبت فیش‌های واریزی
        return redirect('invoices:quote_payment_step', instance_id=instance.id, step_id=step.id)
    elif step.order == 4:  # مرحله چهارم - قرارداد
        return redirect('contracts:contract_step', instance_id=instance.id, step_id=step.id)
    elif step.order == 5:  # مرحله پنجم - انتخاب نصاب
        return redirect('installations:installation_assign_step', instance_id=instance.id, step_id=step.id)
    elif step.order == 6:  # مرحله ششم - گزارش نصب
        return redirect('installations:installation_report_step', instance_id=instance.id, step_id=step.id)
    elif step.order == 7:  # مرحله هفتم - فاکتور نهایی
        return redirect('invoices:final_invoice_step', instance_id=instance.id, step_id=step.id)
    elif step.order == 8:  # مرحله هشتم - تسویه حساب نهایی
        return redirect('invoices:final_settlement_step', instance_id=instance.id, step_id=step.id)
    elif step.order == 9:  # مرحله نهم - گواهی نهایی
        return redirect('certificates:certificate_step', instance_id=instance.id, step_id=step.id)
    
    # برای سایر مراحل، template عمومی نمایش داده می‌شود
    step_instance = instance.step_instances.filter(step=step).first()
    
    # Navigation logic
    previous_step = instance.process.steps.filter(order__lt=step.order).last()
    next_step = instance.process.steps.filter(order__gt=step.order).first()
    
    return render(request, 'processes/step_detail.html', {
        'instance': instance,
        'step': step,
        'step_instance': step_instance,
        'previous_step': previous_step,
        'next_step': next_step,
    })


@login_required 
def instance_steps(request, instance_id):
    """هدایت به مرحله فعلی instance"""
    instance = get_object_or_404(ProcessInstance, id=instance_id)
    
    if not instance.current_step:
        # اگر مرحله فعلی تعریف نشده، به اولین مرحله برو
        first_step = instance.process.steps.first()
        if first_step:
            instance.current_step = first_step
            instance.save()
            return redirect('processes:step_detail', instance_id=instance.id, step_id=first_step.id)
        else:
            messages.error(request, 'هیچ مرحله‌ای برای این فرآیند تعریف نشده است.')
            return redirect('processes:request_list')
    
    # If completed, go to summary instead of steps
    if instance.status == 'completed':
        return redirect('processes:instance_summary', instance_id=instance.id)
    return redirect('processes:step_detail', instance_id=instance.id, step_id=instance.current_step.id)


@login_required
def instance_summary(request, instance_id):
    """نمای خلاصهٔ فقط‌خواندنی برای درخواست‌های تکمیل‌شده."""
    instance = get_object_or_404(ProcessInstance.objects.select_related('well', 'representative'), id=instance_id)
    # Only show for completed requests; otherwise route to steps
    if instance.status != 'completed':
        return redirect('processes:instance_steps', instance_id=instance.id)

    # Collect final invoice, payments, and certificate if any
    from invoices.models import Invoice
    from installations.models import InstallationReport
    from certificates.models import CertificateInstance
    invoice = Invoice.objects.filter(process_instance=instance).first()
    payments = invoice.payments.filter(is_deleted=False).all() if invoice else []
    latest_report = InstallationReport.objects.filter(assignment__process_instance=instance).order_by('-created').first()
    certificate = CertificateInstance.objects.filter(process_instance=instance).order_by('-created').first()

    # Build rows like final invoice step
    rows = []
    if invoice:
        items_qs = invoice.items.select_related('item').filter(is_deleted=False).all()
        rows = list(items_qs)

    return render(request, 'processes/instance_summary.html', {
        'instance': instance,
        'invoice': invoice,
        'payments': payments,
        'rows': rows,
        'latest_report': latest_report,
        'certificate': certificate,
    })
    