from decimal import Decimal
from django.utils import timezone
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db.models import Sum
from django.shortcuts import get_object_or_404, redirect, render
from expat_life.models import PlatformFeeSettings, Package, MarketingResource
from expat_life.forms import ContactMessageForm
from .models import (
    AffiliateProfile,
    AffiliateGuestReferral,
    AffiliateCommission,
    AffiliatePayoutRequest,
    AffiliateMarketingResource,
    AffiliateBusinessCard,
    AffiliateResourceRequest,
    AffiliateTrainingResource,
)
from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth import update_session_auth_hash
import random
import re
import string
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.contrib.auth import login
from django.contrib.auth.models import User
from django.db import transaction
from .forms import (
    AffiliateRegisterForm, AffiliatePasswordResetForm, AffiliateProfilePhotoForm, 
    AffiliateProfileEditForm, AffiliateUsernameChangeForm, AffiliateResourceRequestForm
)
from expat_life.email_services import send_affiliate_signup_welcome_email 
from django.contrib.auth import logout
from django.urls import reverse_lazy, reverse
from django.http import HttpResponseForbidden
# affiliates_app/views.py
from django.contrib.auth.views import (
    LoginView,
    PasswordResetView,
    PasswordResetDoneView,
    PasswordResetConfirmView,
    PasswordResetCompleteView,
)
from common.choices import NATIONALITY_CHOICES, COUNTRY_CHOICES, LANGUAGE_CHOICES
from django.conf import settings
from .utils import (
    PROMOTIONAL_LINKS,
    build_referral_url,
    generate_qr_code_image,
    generate_business_card_composite
)
from django.core.files.base import ContentFile
import os
from django.template.loader import render_to_string
from property_manager_app.models import PropertyManagerClientProfile
from rental_app.models import RentalOwner

def marketing_resources(request):
    selected_lang = request.GET.get('lang', 'all')
 
    resources = MarketingResource.objects.filter(is_active=True)
 
    if selected_lang and selected_lang != 'all':
        resources = resources.filter(language=selected_lang)
 
    return render(request, 'affiliates_app/marketing_resources.html', {
        'resources': resources,
        'selected_lang': selected_lang,
        'language_choices': LANGUAGE_CHOICES,
    })


def about_us_ff(request):
    return render(request, 'affiliates_app/about_aff.html')

def affiliate_terms(request):
    return render(request, 'affiliates_app/terms.html')

def affiliate_faq(request):
    return render(request, 'affiliates_app/faq.html')

def affiliate_privacy_policy(request):
    return render(request, 'affiliates_app/privacy_policy.html')

def affiliate_cookie_policy(request):
    return render(request, 'affiliates_app/cookie_policy.html')

def affiliate_refund_payment_policy(request):
    return render(request, 'affiliates_app/refund_payment_policy.html')

def affiliate_disclaimer(request):
    return render(request, 'affiliates_app/disclaimer.html')

def contact_page_aff(request):
    if request.method == 'POST':
        form = ContactMessageForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect(
                reverse('affiliates_app:success_page') +
                '?type=contact'
            )
    else:
        form = ContactMessageForm()
    return render(request, 'affiliates_app/contact_page_aff.html', {'form': form})

def success_page(request):
    success_type = request.GET.get('type', 'general')

    page_data = {
        'general': {
            'title': 'Thank You',
            'heading': 'Thank You for Reaching Out',
            'message': 'Your submission has been received successfully.',
            'button_1_text': 'Go to Home',
            'button_1_url': 'affiliates_app:home_affiliates',
            'button_2_text': 'About Ensolanka',
            'button_2_url': 'affiliates_app:about_us_aff',
        },
        'signup': {
            'title': 'Signup Submitted',
            'heading': 'Your Free Signup Has Been Submitted',
            'message': 'Thank you for sharing your details. We have received your information successfully and created your account.',
            'button_1_text': 'Go to Home',
            'button_1_url': 'affiliates_app:home_affiliates',
            'button_2_text': 'About Ensolanka',
            'button_2_url': 'affiliates_app:about_us_aff',
        },
        'consultation': {
            'title': 'Consultation Requested',
            'heading': 'Your Consultation Request Has Been Submitted',
            'message': 'Thank you. Your consultation request has been received. We can now review your request and discuss the most suitable next step.',
            'button_1_text': 'Go to Home',
            'button_1_url': 'affiliates_app:home_affiliates',
            'button_2_text': 'Contact Us',
            'button_2_url': 'affiliates_app:contact_page_aff',
        },
        'contact': {
            'title': 'Message Sent',
            'heading': 'Your Message Has Been Sent Successfully',
            'message': 'Thank you for contacting us. We have received your message and will review it as soon as possible.',
            'button_1_text': 'Go to Home',
            'button_1_url': 'affiliates_app:home_affiliates',
            'button_2_text': 'Contact Us',
            'button_2_url': 'affiliates_app:contact_page_aff',
        },
    }

    context = page_data.get(success_type, page_data['general']).copy()

    context['signup_type'] = success_type
    context['username'] = request.session.pop('new_account_username', None)
    context['password'] = request.session.pop('new_account_password', None)
    context['new_account_email'] = request.session.pop('new_account_email', None)
    context['account_role'] = request.session.pop('account_role', None)

    return render(request, 'affiliates_app/success_page.html', context)

@login_required
def affiliate_profile_page(request):
    try:
        profile = request.user.affiliate_profile
    except AttributeError:
        return HttpResponseForbidden("You do not have an affiliate profile.")

    return render(request, 'affiliates_app/affiliate_profile.html', {
        'profile': profile,
        'user': request.user,
    })

@login_required
def affiliate_edit_profile(request):
    try:
        profile = request.user.affiliate_profile
    except AttributeError:
        return HttpResponseForbidden("You do not have an affiliate profile.")

    if request.method == 'POST':
        form = AffiliateProfileEditForm(request.POST, instance=profile)
        if form.is_valid():
            form.save()
            messages.success(request, "Profile updated successfully.")
            return redirect('affiliates_app:affiliate_profile')
    else:
        form = AffiliateProfileEditForm(instance=profile)

    return render(request, 'affiliates_app/edit_affiliate_profile.html', {
        'form': form,
        'profile': profile,
    })

@login_required
def affiliate_change_username(request):
    try:
        profile = request.user.affiliate_profile
    except AttributeError:
        return HttpResponseForbidden("You do not have an affiliate profile.")

    if request.method == 'POST':
        form = AffiliateUsernameChangeForm(request.POST, user=request.user)
        if form.is_valid():
            form.save()
            messages.success(request, "Your username has been updated successfully.")
            return redirect('affiliates_app:affiliate_profile')
    else:
        form = AffiliateUsernameChangeForm(user=request.user)

    return render(request, 'affiliates_app/change_affiliate_username.html', {
        'form': form,
        'profile': profile,
    })

@login_required
def affiliate_change_password(request):
    try:
        profile = request.user.affiliate_profile
    except AttributeError:
        return HttpResponseForbidden("You do not have an affiliate profile.")

    if request.method == 'POST':
        form = PasswordChangeForm(request.user, request.POST)
        if form.is_valid():
            user = form.save()
            # Keep the user logged in after password change
            update_session_auth_hash(request, user)
            messages.success(request, "Your password has been changed successfully.")
            return redirect('affiliates_app:affiliate_profile')
    else:
        form = PasswordChangeForm(request.user)

    return render(request, 'affiliates_app/change_affiliate_password.html', {
        'form': form,
        'profile': profile,
    })

@login_required
@require_POST
def upload_affiliate_profile_image(request):
    profile = getattr(request.user, 'affiliate_profile', None)
    if not profile:
        return JsonResponse({
            'success': False,
            'error': 'Affiliate profile not found.'
        }, status=403)

    if 'profile_photo' not in request.FILES:
        return JsonResponse({
            'success': False,
            'error': 'No image was uploaded.'
        }, status=400)

    form = AffiliateProfilePhotoForm(request.POST, request.FILES, instance=profile)

    if form.is_valid():
        form.save()
        profile.refresh_from_db()

        image_url = profile.profile_photo.url if profile.profile_photo else ''
        return JsonResponse({
            'success': True,
            'image_url': image_url,
            'message': 'Profile image updated successfully.'
        })

    error_message = "Invalid image upload."
    if form.errors.get('profile_photo'):
        error_message = form.errors['profile_photo'][0]

    return JsonResponse({
        'success': False,
        'error': error_message
    }, status=400)

class AffiliatePasswordResetView(PasswordResetView):
    template_name = 'registration/affiliate_password_reset.html'
    form_class = AffiliatePasswordResetForm
    email_template_name = 'emails/affiliates_app/password_reset_email.txt'
    html_email_template_name = 'emails/affiliates_app/password_reset_email.html'
    subject_template_name = 'emails/affiliates_app/password_reset_subject.txt'
    success_url = reverse_lazy('affiliates_app:affiliate_password_reset_done')
    from_email = "Partner with Ensolanka <dsjayathunge@gmail.com>" 

    def get_extra_email_context(self):
        return {
            "site_url": self.request.build_absolute_uri("/"),
            "dashboard_url": self.request.build_absolute_uri(
                reverse_lazy('affiliates_app:affiliate_dashboard')
            ),
        }

    def form_valid(self, form):
        self.extra_email_context = self.get_extra_email_context()
        email = form.cleaned_data.get('email')

        user_exists_as_affiliate = User.objects.filter(
            email__iexact=email,
            affiliate_profile__isnull=False,
            affiliate_profile__is_active=True
        ).exists()

        if not user_exists_as_affiliate:
            messages.warning(
                self.request,
                "If this email belongs to a registered Affiliate Partner account, "
                "password reset instructions will be sent."
            )

        return super().form_valid(form)


class AffiliatePasswordResetDoneView(PasswordResetDoneView):
    template_name = 'registration/affiliate_password_reset_done.html'


class AffiliatePasswordResetConfirmView(PasswordResetConfirmView):
    template_name = 'registration/affiliate_password_reset_confirm.html'
    success_url = reverse_lazy('affiliates_app:affiliate_password_reset_complete')


class AffiliatePasswordResetCompleteView(PasswordResetCompleteView):
    template_name = 'registration/affiliate_password_reset_complete.html'


class AffiliateLoginView(LoginView):
    template_name = 'registration/affiliate_login.html'

    def form_valid(self, form):
        response = super().form_valid(form)
        user = self.request.user

        # Check if the user has an affiliate profile
        if hasattr(user, 'affiliate_profile') and user.affiliate_profile.is_active:
            return response

        # Not an affiliate → logout and show error
        messages.error(
            self.request,
            "This login is only for Affiliate Partners. Please use the correct login page."
        )
        logout(self.request)
        return redirect('affiliates_app:affiliate_login')

    def get_success_url(self):
        return self.get_redirect_url() or reverse_lazy('affiliates_app:affiliate_dashboard')

def generate_affiliate_username_from_name(full_name):
    base_name = re.sub(r'[^a-zA-Z0-9]', '', full_name.lower())

    if not base_name:
        base_name = 'affiliate'

    base = f"aff_{base_name}"
    username = base
    counter = 1

    while User.objects.filter(username=username).exists():
        username = f"{base}{counter}"
        counter += 1

    return username


def generate_random_password(length=10):
    chars = string.ascii_letters + string.digits
    return ''.join(random.choice(chars) for _ in range(length))

@transaction.atomic
def affiliate_register(request):
    if request.user.is_authenticated and hasattr(request.user, 'affiliate_profile'):
        messages.info(request, "You are already registered as an affiliate partner.")
        return redirect('affiliates_app:affiliate_dashboard')

    if request.method == 'POST':
        form = AffiliateRegisterForm(request.POST)

        if form.is_valid():
            email = form.cleaned_data['email'].strip().lower()
            full_name = form.cleaned_data['full_name'].strip()

            existing_user = User.objects.filter(email__iexact=email).first()

            if existing_user:
                form.add_error('email', 'An account with this email already exists.')
            else:
                username = generate_affiliate_username_from_name(full_name)
                password = generate_random_password()

                name_parts = full_name.split()
                first_name = name_parts[0] if name_parts else ''
                last_name = ' '.join(name_parts[1:]) if len(name_parts) > 1 else ''

                user = User.objects.create_user(
                    username=username,
                    email=email,
                    password=password,
                    first_name=first_name,
                    last_name=last_name
                )

                affiliate = form.save(commit=False)
                affiliate.user = user
                affiliate.status = 'approved'
                affiliate.is_active = True
                affiliate.save()

                # --- Send welcome email --- #
                try:
                    send_affiliate_signup_welcome_email(
                        user=user,
                        full_name=full_name,
                        email=email,
                        username=username,
                        temporary_password=password,
                        request=request,
                    )
                except Exception as e:
                    # Log error but don't break registration
                    import logging
                    logger = logging.getLogger(__name__)
                    logger.error(f"Failed to send affiliate welcome email to {email}: {e}")

                login(request, user)

                request.session['new_account_username'] = username
                request.session['new_account_password'] = password
                request.session['new_account_email'] = email
                request.session['account_role'] = 'Affiliate Partner'
                request.session['just_signed_up'] = True

                messages.success(
                    request,
                    "Your affiliate partner account has been created successfully. "
                    "We have sent your login details to your email address."
                )

                return redirect('affiliates_app:affiliate_dashboard')
        else:
            messages.error(request, "Please correct the errors below and try again.")
    else:
        form = AffiliateRegisterForm()

    return render(request, 'affiliates_app/affiliate_register.html', {
        'form': form
    })

@login_required
def affiliate_dashboard(request):
    affiliate = getattr(request.user, 'affiliate_profile', None)

    if not affiliate:
        messages.warning(request, "Affiliate profile not found.")
        return redirect('affiliates_app:home_affiliates')

    default_profile_image = 'expat_life/images/default-profile-neutral.png'

    referrals = AffiliateGuestReferral.objects.filter(
        affiliate=affiliate
    ).select_related(
        'guest_user',
        'foreigner_lead',
        'foreigner_profile'
    )

    commissions = AffiliateCommission.objects.filter(
        affiliate=affiliate
    )

    pending_commission_total = commissions.filter(
        status='pending'
    ).aggregate(total=Sum('commission_amount_usd'))['total'] or Decimal('0.00')

    earned_commission_total = commissions.filter(
        status='earned'
    ).aggregate(total=Sum('commission_amount_usd'))['total'] or Decimal('0.00')

    paid_commission_total = commissions.filter(
        status='paid'
    ).aggregate(total=Sum('commission_amount_usd'))['total'] or Decimal('0.00')

    possible_future_earnings = referrals.aggregate(
        total=Sum('total_possible_commission_usd')
    )['total'] or Decimal('0.00')

    pending_clients_count = referrals.filter(status='signed_up').count()
    completed_clients_count = referrals.filter(status='completed').count()

    #resources = AffiliateMarketingResource.objects.filter(is_active=True)
    # Get affiliate‑specific marketing resources
    resources = AffiliateMarketingResource.objects.filter(
        affiliate_profile=affiliate,
        is_active=True
    ).order_by('-created_at')

    payout_requests = AffiliatePayoutRequest.objects.filter(
        affiliate=affiliate
    )[:5]

    confirmed_count = referrals.filter(status='confirmed').count()
    service_paid_count = referrals.filter(status__in=['service_fee_paid', 'completed']).count()

    # Build list of promotional links with full referral URLs for display
    promo_links_with_urls = []
    for url_name, display_name in PROMOTIONAL_LINKS:
        full_url = build_referral_url(request, url_name, affiliate.affiliate_code)
        promo_links_with_urls.append({
            'url_name': url_name,
            'display_name': display_name,
            'full_url': full_url,
        })

    # Get existing business cards for this affiliate
    existing_cards = AffiliateBusinessCard.objects.filter(
        affiliate_profile=affiliate
    ).order_by('-created_at')


    # Handle resource request submission
    if request.method == 'POST' and 'request_resources' in request.POST:
        form = AffiliateResourceRequestForm(request.POST)
        if form.is_valid():
            languages = form.cleaned_data['requested_languages']  # list of strings
            resource_request = AffiliateResourceRequest.objects.create(
                affiliate_profile=affiliate,
                requested_languages=languages,
                status='pending'
            )
            messages.success(request, "Your request has been submitted. We'll notify you when materials are ready.")
            return redirect('affiliates_app:affiliate_dashboard')
    else:
        form = AffiliateResourceRequestForm()
    
    
    # Fetch pending requests (status not 'completed' or 'rejected')
    pending_requests = affiliate.resource_requests.exclude(status__in=['completed', 'rejected']).order_by('-request_date')
    
    training_resources = AffiliateTrainingResource.objects.filter(
        is_active=True
    ).order_by('language')
                
    has_property_manager_profile = hasattr(
        request.user,
        'property_manager_client_profile'
    )

    has_rental_owner_profile = hasattr(
        request.user,
        'rental_owner_profile'
    )

    context = {
        'affiliate': affiliate,
        'promotional_links': promo_links_with_urls,
        'existing_cards': existing_cards,
        'referrals': referrals,
        'confirmed_count': confirmed_count,
        'service_paid_count': service_paid_count,
        'default_profile_image': default_profile_image,
        'commissions': commissions[:10],
        'pending_commission_total': pending_commission_total,
        'earned_commission_total': earned_commission_total,
        'paid_commission_total': paid_commission_total,
        'possible_future_earnings': possible_future_earnings,
        'pending_clients_count': pending_clients_count,
        'completed_clients_count': completed_clients_count,
        'resources': resources,
        'training_resources': training_resources,
        'payout_requests': payout_requests,
        'has_property_manager_profile': has_property_manager_profile,
        'has_rental_owner_profile': has_rental_owner_profile,
        # Just signed up account details
        'just_signed_up': request.session.pop('just_signed_up', False),
        'username': request.session.pop('new_account_username', None),
        'password': request.session.pop('new_account_password', None),
        'new_account_email': request.session.pop('new_account_email', None),
        'account_role': request.session.pop('account_role', None),
        'now': timezone.now(),
        'resource_request_form': form,
        'pending_requests': pending_requests,
    }

    return render(request, 'affiliates_app/affiliate_dashboard.html', context)

@login_required
def generate_business_card(request):
    affiliate = getattr(request.user, 'affiliate_profile', None)
    if not affiliate:
        messages.warning(request, "Affiliate profile not found.")
        return redirect('expat_life:home')

    if request.method != 'POST':
        messages.error(request, "Invalid request method.")
        return redirect('affiliate_dashboard')

    url_name = request.POST.get('promo_link')
    valid_names = [name for name, _ in PROMOTIONAL_LINKS]
    if url_name not in valid_names:
        messages.error(request, "Please select a valid promotional link.")
        return redirect('affiliate_dashboard')

    # Build full referral link
    referral_url = build_referral_url(request, url_name, affiliate.affiliate_code)

    # Generate QR code
    qr_buffer = generate_qr_code_image(referral_url, size=300)

    # Generate business card composite (adjust paths as needed)
    background_path = os.path.join(settings.BASE_DIR, 'static', 'expat_life', 'images', 'bc_background_with_logo.png')
    # Optionally use a default fallback if file missing
    if not os.path.exists(background_path):
        messages.error(request, "Background image missing. Contact administrator.")
        return redirect('affiliate_dashboard')

    name_font = os.path.join(settings.BASE_DIR, 'static', 'fonts', 'Poppins-Medium.ttf')
    contact_font = os.path.join(settings.BASE_DIR, 'static', 'fonts', 'Poppins-Regular.ttf')
    code_font = os.path.join(settings.BASE_DIR, 'static', 'fonts', 'Poppins-Medium.ttf')

    composite_buffer = generate_business_card_composite(
        affiliate_profile=affiliate,
        qr_image_buffer=qr_buffer,
        background_image_path=background_path,
        card_size=(1050, 600),
        name_font_path=name_font,
        contact_font_path=contact_font,
        code_font_path=code_font
    )

    # Use update_or_create to avoid duplicate (affiliate_profile, referral_link)
    card, created = AffiliateBusinessCard.objects.update_or_create(
        affiliate_profile=affiliate,
        referral_link=referral_url,
        defaults={
            'design_version': 'default',
            'is_active': True,
        }
    )

    # Generate filenames
    qr_filename = f"qr_{affiliate.affiliate_code}_{url_name}.png"
    card_filename = f"card_{affiliate.affiliate_code}_{url_name}.png"

    # Delete old image files if they exist (to avoid orphan files)
    if not created:
        # Remove old QR and card images from filesystem
        card.delete_qr_and_card_files()   # you must have this method defined (see previous answer)

    # Save new images (overwrites the ImageField references)
    card.qr_code_image.save(qr_filename, ContentFile(qr_buffer.getvalue()), save=False)
    card.business_card_image.save(card_filename, ContentFile(composite_buffer.getvalue()), save=False)
    card.save()

    if created:
        messages.success(request, f"New business card for '{dict(PROMOTIONAL_LINKS).get(url_name)}' created successfully!")
    else:
        messages.success(request, f"Business card for '{dict(PROMOTIONAL_LINKS).get(url_name)}' updated with fresh QR and image.")


    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        return JsonResponse({'success': True})
    else:
        return redirect('affiliates_app:affiliate_dashboard')


@login_required
def get_affiliate_cards(request):
    """Return HTML snippet of existing business cards for the current affiliate."""
    affiliate = getattr(request.user, 'affiliate_profile', None)
    if not affiliate:
        return JsonResponse({'error': 'No affiliate profile'}, status=400)
    
    existing_cards = AffiliateBusinessCard.objects.filter(
        affiliate_profile=affiliate
    ).order_by('-created_at')
    
    html = render_to_string('affiliate/_cards_section.html', {
        'existing_cards': existing_cards
    }, request=request)
    return JsonResponse({'html': html})

@login_required
def request_affiliate_payout(request):
    affiliate = getattr(request.user, 'affiliate_profile', None)

    if not affiliate:
        messages.warning(request, "Affiliate profile not found.")
        return redirect('affiliates_app:home_affiliates')

    if request.method == 'POST':
        amount = request.POST.get('amount_usd', '0').strip()

        try:
            amount = Decimal(amount)
        except Exception:
            amount = Decimal('0.00')

        if amount <= 0:
            messages.error(request, "Please enter a valid payout amount.")
            return redirect('affiliates_app:affiliate_dashboard')

        if amount > affiliate.available_balance_usd:
            messages.error(request, "Requested payout amount is higher than your available balance.")
            return redirect('affiliates_app:affiliate_dashboard')

        bank_snapshot = f"""
Bank Name: {affiliate.bank_name}
Account Name: {affiliate.bank_account_name}
Account Number: {affiliate.bank_account_number}
Branch: {affiliate.bank_branch}
Notes: {affiliate.payout_notes}
"""

        AffiliatePayoutRequest.objects.create(
            affiliate=affiliate,
            amount_usd=amount,
            bank_snapshot=bank_snapshot
        )

        messages.success(request, "Your payout request has been submitted.")
        return redirect('affiliates_app:affiliate_dashboard')

    return redirect('affiliates_app:affiliate_dashboard')

def get_platform_fee_settings():
    settings_obj = PlatformFeeSettings.objects.filter(is_active=True).first()
    if settings_obj:
        return settings_obj

    return PlatformFeeSettings.objects.first()


def home_affiliates(request):
    affiliate_profile = None

    if request.user.is_authenticated:
        affiliate_profile = getattr(request.user, 'affiliate_profile', None)

    settings_obj = get_platform_fee_settings()

    default_affiliate_percentage = Decimal('20.00')
    if settings_obj and hasattr(settings_obj, 'affiliate_commission_percentage'):
        default_affiliate_percentage = settings_obj.affiliate_commission_percentage or Decimal('20.00')

    packages = Package.objects.filter(is_active=True).order_by('order', 'monthly_price_usd')

    earning_rows = []

    for package in packages:
        confirmation_fee = package.confirmation_fee_usd or Decimal('0.00')
        service_fee_amount = package.service_fee_amount

        # Use PlatformFeeSettings affiliate percentage as the global rule.
        # If you later want package-specific percentage, replace this with package.affiliate_fee_percentage.
        affiliate_percentage = default_affiliate_percentage

        confirmation_affiliate_fee = (
            confirmation_fee * affiliate_percentage / Decimal('100')
        ).quantize(Decimal('0.01'))

        service_affiliate_fee = (
            service_fee_amount * affiliate_percentage / Decimal('100')
        ).quantize(Decimal('0.01'))

        total_affiliate_fee_per_guest = (
            confirmation_affiliate_fee + service_affiliate_fee
        ).quantize(Decimal('0.01'))

        estimated_5_guests_income = (
            total_affiliate_fee_per_guest * Decimal('5')
        ).quantize(Decimal('0.01'))

        estimated_10_guests_income = (
            total_affiliate_fee_per_guest * Decimal('10')
        ).quantize(Decimal('0.01'))

        earning_rows.append({
            'package': package,
            'confirmation_fee': confirmation_fee,
            'service_fee_percentage': package.service_fee_percentage,
            'service_fee_amount': service_fee_amount,
            'affiliate_percentage': affiliate_percentage,
            'confirmation_affiliate_fee': confirmation_affiliate_fee,
            'service_affiliate_fee': service_affiliate_fee,
            'total_affiliate_fee_per_guest': total_affiliate_fee_per_guest,
            'estimated_5_guests_income': estimated_5_guests_income,
            'estimated_10_guests_income': estimated_10_guests_income,
        })

    total_affiliates = AffiliateProfile.objects.filter(
        status='approved',
        is_active=True
    ).count()

    total_referrals = AffiliateGuestReferral.objects.count()

    total_payouts = AffiliatePayoutRequest.objects.filter(
        status='paid'
    ).aggregate(total=Sum('amount_usd'))['total'] or Decimal('0.00')

    context = {
        'affiliate_profile': affiliate_profile,
        'settings_obj': settings_obj,
        'default_affiliate_percentage': default_affiliate_percentage,
        'earning_rows': earning_rows,
        'total_affiliates': total_affiliates,
        'total_referrals': total_referrals,
        'total_payouts': total_payouts,
    }

    return render(request, 'affiliates_app/home_affiliates.html', context)

@login_required
def affiliate_referral_list(request):
    affiliate = getattr(request.user, 'affiliate_profile', None)

    if not affiliate:
        messages.warning(request, "Affiliate profile not found.")
        return redirect('affiliates_app:home_affiliates')

    status_filter = request.GET.get('status', 'signed_up')

    STATUS_META = {
        'signed_up': {
            'label': 'Pending Referrals',
            'description': 'Referrals who have signed up but are not yet confirmed.',
            'badge_class': 'text-bg-secondary',
            'icon': 'bi-hourglass-split',
            'icon_color': 'text-secondary',
        },
        'confirmed': {
            'label': 'Confirmed Referrals',
            'description': 'Referrals who paid the confirmation fee — commission earned.',
            'badge_class': 'text-bg-success',
            'icon': 'bi-patch-check-fill',
            'icon_color': 'text-success',
        },
        'service_fee_paid': {
            'label': 'Service Fee Paid',
            'description': 'Referrals who paid the one-time service fee.',
            'badge_class': 'text-bg-info',
            'icon': 'bi-credit-card-fill',
            'icon_color': 'text-info',
        },
        'completed': {
            'label': 'Completed Referrals',
            'description': 'Referrals who have completed the full journey.',
            'badge_class': 'text-bg-primary',
            'icon': 'bi-trophy-fill',
            'icon_color': 'text-primary',
        },
    }

    # 'paid_completed' is a combined filter for the dashboard card
    if status_filter == 'paid_completed':
        referrals = AffiliateGuestReferral.objects.filter(
            affiliate=affiliate,
            status__in=['service_fee_paid', 'completed']
        ).select_related('guest_user', 'foreigner_profile', 'foreigner_lead')
        meta = {
            'label': 'Paid / Completed Referrals',
            'description': 'Referrals who paid the service fee or completed the full journey.',
            'badge_class': 'text-bg-info',
            'icon': 'bi-credit-card-fill',
            'icon_color': 'text-info',
        }
    else:
        if status_filter not in STATUS_META:
            status_filter = 'signed_up'
        referrals = AffiliateGuestReferral.objects.filter(
            affiliate=affiliate,
            status=status_filter
        ).select_related('guest_user', 'foreigner_profile', 'foreigner_lead')
        meta = STATUS_META[status_filter]

    context = {
        'affiliate': affiliate,
        'referrals': referrals,
        'status_filter': status_filter,
        'meta': meta,
    }

    return render(request, 'affiliates_app/affiliate_referral_list.html', context)

@login_required
@require_POST
@transaction.atomic
def activate_property_manager_from_affiliate(request):
    """
    Creates a Property Care client profile for the currently logged-in
    Affiliate Partner using available affiliate profile details,
    then redirects to the Property Care Dashboard.

    If the Property Care profile already exists,
    simply redirect to that dashboard.
    """

    user = request.user

    # ---------------------------------------------------------
    # 1. Confirm this user has an Affiliate Profile
    # ---------------------------------------------------------
    affiliate_profile = getattr(
        user,
        'affiliate_profile',
        None
    )

    if affiliate_profile is None:
        messages.warning(
            request,
            "Please activate Affiliate access first before creating a Property Care profile."
        )
        return redirect(
            'affiliates_app:affiliate_dashboard'
        )

    # ---------------------------------------------------------
    # 2. If Property Care profile already exists, just redirect
    # ---------------------------------------------------------
    existing_property_manager_profile = getattr(
        user,
        'property_manager_client_profile',
        None
    )

    if existing_property_manager_profile is not None:
        messages.info(
            request,
            "Your Property Care access is already active."
        )
        return redirect(
            'property_manager_app:property_manager_dashboard'
        )

    # ---------------------------------------------------------
    # 3. Create Property Care profile from Affiliate details
    # ---------------------------------------------------------
    PropertyManagerClientProfile.objects.create(
        user=user,

        client_type='individual',
        residency_status='other',

        full_name=affiliate_profile.full_name,
        email=user.email,
        whatsapp_number=affiliate_profile.whatsapp,
        phone_number=affiliate_profile.phone,

        current_country=affiliate_profile.country,
        current_city='',

        emergency_contact_name='',
        emergency_contact_phone='',

        short_note=(
            "Property Care access was activated from the existing Affiliate Partner account."
        ),

        is_identity_verified=False,
        is_approved=True,
        can_submit_properties=True,
    )

    # ---------------------------------------------------------
    # 4. Success and redirect
    # ---------------------------------------------------------
    messages.success(
        request,
        "Property Care access has been activated successfully. You can now register properties for maintenance, review, and care planning."
    )

    return redirect(
        'property_manager_app:property_manager_dashboard'
    )

@login_required
@require_POST
@transaction.atomic
def activate_rental_owner_from_affiliate(request):
    """
    Creates a Rental Owner profile for the currently logged-in
    Affiliate Partner using available affiliate profile details,
    then redirects to the Rental Owner Dashboard.

    If the Rental Owner profile already exists,
    simply redirect to that dashboard.
    """

    user = request.user

    # ---------------------------------------------------------
    # 1. Confirm this user has an Affiliate Profile
    # ---------------------------------------------------------
    affiliate_profile = getattr(
        user,
        'affiliate_profile',
        None
    )

    if affiliate_profile is None:
        messages.warning(
            request,
            "Please activate Affiliate access first before creating a Rental Owner profile."
        )
        return redirect(
            'affiliates_app:affiliate_dashboard'
        )

    # ---------------------------------------------------------
    # 2. If Rental Owner profile already exists, just redirect
    # ---------------------------------------------------------
    existing_rental_owner_profile = getattr(
        user,
        'rental_owner_profile',
        None
    )

    if existing_rental_owner_profile is not None:
        messages.info(
            request,
            "Your Rental Owner access is already active."
        )
        return redirect(
            'rental_app:rental_owner_dashboard'
        )

    # ---------------------------------------------------------
    # 3. Create Rental Owner profile from Affiliate details
    # ---------------------------------------------------------
    RentalOwner.objects.create(
        user=user,
        owner_type='individual',

        full_name=affiliate_profile.full_name,
        email=user.email,
        whatsapp_number=affiliate_profile.whatsapp,
        phone_number=affiliate_profile.phone,

        city='',
        address='',
        business_name='',

        is_identity_verified=False,
        is_approved=True,
        is_featured=False,
        can_submit_listings=True,
    )

    # ---------------------------------------------------------
    # 4. Success and redirect
    # ---------------------------------------------------------
    messages.success(
        request,
        "Rental Owner access has been activated successfully. You can now create and manage rental property listings."
    )

    return redirect(
        'rental_app:rental_owner_dashboard'
    )

def affiliate_information_center(request):
    selected_language = request.GET.get('lang', 'en')

    allowed_languages = ['en', 'si', 'ta']
    if selected_language not in allowed_languages:
        selected_language = 'en'

    training_resources = AffiliateTrainingResource.objects.filter(
        is_active=True
    ).order_by('language')

    selected_resource = training_resources.filter(
        language=selected_language
    ).first()

    # Fallback: if selected language resource is not created yet,
    # show English if available.
    if selected_resource is None:
        selected_resource = training_resources.filter(language='en').first()
        selected_language = 'en'

    context = {
        'training_resources': training_resources,
        'selected_resource': selected_resource,
        'selected_language': selected_language,
    }

    return render(
        request,
        'affiliates_app/affiliate_information_center.html',
        context
    )