# Add these imports at the top if not already present
import json
import re
import urllib.parse
import urllib.request
from django.shortcuts import render, get_object_or_404, redirect
from django.http import Http404
from django.http import JsonResponse
from django.contrib import messages
from django.conf import settings
from django.db.models import Q
from django.template.defaultfilters import truncatechars
from django.utils.html import strip_tags, escape
from django.core.cache import cache
from .models import *
from .forms import ContactForm
from .geo.services import HrefLangGenerator
from .geo.analytics import get_ga4_tracker
from .visitor_intel import (
    IPGeolocationService,
    get_client_ip as get_real_ip,
    is_bot as ua_is_bot,
    is_private_ip as ua_is_private_ip,
    is_valid_ip as ua_is_valid_ip,
)
from .visitor_services import AUTO_BLOCK, BLOCKLIST


def get_region_object(region_code):
    """Helper to get region object or None"""
    if not region_code:
        return None
    try:
        return Region.objects.get(code=region_code, is_active=True)
    except Region.DoesNotExist:
        # If an invalid region code is passed in the URL (e.g. /xyz/), we return None
        # The view or middleware might decide to 404, but for now fallback to global.
        # Alternatively, raise Http404 here if strict region checking is desired.
        return None

def filter_by_region(queryset, region):
    """Filter queryset by region. Includes items with no specific region (global)."""
    if not region:
        # If no region selected, show everything? Or only global items?
        # Let's show everything for now on the main site.
        return queryset
    
    # Show items explicitly tagged for this region OR items with NO region tags (global)
    return queryset.filter(Q(regions=region) | Q(regions__isnull=True)).distinct()

def get_common_context(context, region):
    """Add common context variables like current_region and hreflang_tags"""
    context['current_region'] = region
    try:
        context['company_settings'] = get_region_single_content(CompanySettings.objects.all(), region)
    except Exception:
        try:
            context['company_settings'] = CompanySettings.objects.first()
        except Exception:
            context['company_settings'] = None
    try:
        context['footer_settings'] = get_region_single_content(FooterSettings.objects.all(), region)
    except Exception:
        try:
            context['footer_settings'] = FooterSettings.objects.first()
        except Exception:
            context['footer_settings'] = None
    try:
        context['footer_link_groups_main'] = FooterLinkGroup.objects.filter(
            is_active=True, location='main'
        ).prefetch_related('links')
        context['footer_link_groups_bottom'] = FooterLinkGroup.objects.filter(
            is_active=True, location='bottom'
        ).prefetch_related('links')
    except Exception:
        context['footer_link_groups_main'] = []
        context['footer_link_groups_bottom'] = []
    return context


def get_region_single_content(queryset, region):
    """Return a single region-specific object, falling back to global.

    Priority order:
    1. Object explicitly tagged for this region
    2. Object with no region tags (global/default)
    3. Any active object (last resort)

    Uses at most one DB query by evaluating the queryset once.
    """
    items = list(queryset)
    if not items:
        return None
    if region:
        for item in items:
            if item.regions.filter(pk=region.pk).exists():
                return item
    for item in items:
        if not item.regions.exists():
            return item
    return items[0]


def get_region_prefix(region):
    """Return URL prefix for a region (default UK has no prefix)."""
    if not region:
        return ''
    code = getattr(region, 'code', '') or ''
    if code in {'ca', 'uae', 'ireland'}:
        return f'/{code}'
    return ''


def add_hreflang_tags(context, request):
    """Generate and add hreflang tags to context for SEO.
    
    This helper generates hreflang tags for all available regional versions
    of the current page and adds them to the template context.
    
    Args:
        context: The template context dictionary
        request: The HTTP request object
        
    Returns:
        The updated context with hreflang_tags
    """
    try:
        generator = HrefLangGenerator()
        hreflang_tags = generator.generate_tags(request)
        context['hreflang_tags'] = hreflang_tags
    except Exception as e:
        # Log error but don't fail the view if hreflang generation fails
        import logging
        logger = logging.getLogger(__name__)
        logger.error(f"Failed to generate hreflang tags: {str(e)}")
        context['hreflang_tags'] = []
    
    return context


def build_meta_description(primary_text, fallback_text, min_length=120, max_length=160):
    """Ensure meta description is present and within recommended length."""
    primary = strip_tags(primary_text or '').strip()
    fallback = strip_tags(fallback_text or '').strip()

    text = primary if len(primary) >= min_length else fallback or primary
    text = ' '.join(text.split())

    if len(text) < min_length:
        suffix = " Contact XinfinityGroup for tailored facilities, security, and cleaning support."
        text = f"{text} {suffix}".strip()
        text = ' '.join(text.split())

    if len(text) > max_length:
        text = truncatechars(text, max_length)

    return text


def build_meta_title(primary_text, fallback_text, min_length=50, max_length=60, short_suffix=" | XinfinityGroup", long_suffix=" | Facilities Management | XinfinityGroup"):
    """Ensure title tag is present and within recommended length."""
    base = (primary_text or fallback_text or "XinfinityGroup").strip()
    if len(base) < min_length:
        suffix = long_suffix if len(base) <= 28 else short_suffix
        base = f"{base}{suffix}"
    if len(base) > max_length:
        base = truncatechars(base, max_length)
    return base


def _plain_text_to_rich_html(text: str) -> str:
    if not text:
        return ""

    import re

    normalized = str(text).replace("\r\n", "\n").replace("\r", "\n").strip()
    if not normalized:
        return ""

    lines = normalized.split("\n")
    blocks = []
    current = []
    for line in lines:
        if line.strip() == "":
            if current:
                blocks.append(current)
                current = []
            continue
        current.append(line.rstrip())
    if current:
        blocks.append(current)

    def format_list_item(raw: str) -> str:
        escaped = escape(raw.strip())
        if ":" in escaped:
            left, right = escaped.split(":", 1)
            left = left.strip()
            right = right.strip()
            if left:
                return f"<strong>{left}:</strong> {right}" if right else f"<strong>{left}:</strong>"
        return escaped

    html_parts = []
    ordered_item_re = re.compile(r"^\s*(\d+)\.\s+(.*)$")
    unordered_item_re = re.compile(r"^\s*[-•]\s+(.*)$")

    for block in blocks:
        block_lines = block

        if block_lines and len(block_lines) > 1 and block_lines[0].strip().endswith(":"):
            heading = block_lines[0].strip()[:-1].strip()
            if 2 <= len(heading) <= 80:
                html_parts.append(f"<h2>{escape(heading)}</h2>")
                block_lines = block_lines[1:]
                if not block_lines:
                    continue

        ordered_matches = [ordered_item_re.match(line) for line in block_lines]
        unordered_matches = [unordered_item_re.match(line) for line in block_lines]

        if len(block_lines) == 1:
            line = block_lines[0].strip()
            title_split = re.match(r"^(.{2,80}?):\s+(.+)$", line)
            if title_split and not ordered_item_re.match(line) and not unordered_item_re.match(line):
                heading = title_split.group(1).strip()
                rest = title_split.group(2).strip()
                if heading and rest:
                    html_parts.append(f"<h2>{escape(heading)}</h2>")
                    html_parts.append(f"<p>{escape(rest)}</p>")
                    continue
            heading_line = line[:-1].strip() if line.endswith(":") else line
            if (
                2 <= len(heading_line) <= 80
                and not ordered_item_re.match(heading_line)
                and not unordered_item_re.match(heading_line)
                and not heading_line.endswith((".", "!", "?", ","))
            ):
                html_parts.append(f"<h2>{escape(heading_line)}</h2>")
                continue

        if all(m is not None for m in ordered_matches):
            items = []
            for m in ordered_matches:
                items.append(f"<li>{format_list_item(m.group(2))}</li>")
            html_parts.append("<ol>" + "".join(items) + "</ol>")
            continue

        if all(m is not None for m in unordered_matches):
            items = []
            for m in unordered_matches:
                items.append(f"<li>{format_list_item(m.group(1))}</li>")
            html_parts.append("<ul>" + "".join(items) + "</ul>")
            continue

        text_block = " ".join(line.strip() for line in block_lines)
        inline_steps = list(re.finditer(r"(?:^|\s)\d+\.\s+", text_block))
        if len(inline_steps) >= 2:
            pre = text_block[:inline_steps[0].start()].strip()
            if pre:
                html_parts.append(f"<p>{escape(pre)}</p>")

            step_parts = []
            for idx, match in enumerate(inline_steps):
                start = match.end()
                end = inline_steps[idx + 1].start() if (idx + 1) < len(inline_steps) else len(text_block)
                item_text = text_block[start:end].strip()
                if item_text:
                    step_parts.append(f"<p>{format_list_item(item_text)}</p>")
            if step_parts:
                html_parts.append('<div class="service-detail-steps">' + "".join(step_parts) + "</div>")
            continue

        paragraph = "<br>".join(escape(line.strip()) for line in block_lines)
        html_parts.append(f"<p>{paragraph}</p>")

    return "".join(html_parts)


def get_home_slider_cards():
    logistics_slider_cards = [
        {
            'title': '24/7 Command Center',
            'description': 'Real-time digital twin monitoring with verification, intervention, and controlled arrival release.',
            'url': '/logistics/details/command-center/',
            'image': 'images/logistics/247.jpg',
        },
        {
            'title': 'Uninterrupted Connectivity',
            'description': 'Dual-layer Iridium and Starlink resilience for remote routes, dead zones, and failover continuity.',
            'url': '/logistics/details/uninterrupted-connectivity/',
            'image': 'images/logistics/uninc.jpg',
        },
        {
            'title': 'Geofence Enforcement',
            'description': 'Green/Black corridor control with zero-tolerance breach alerts, unscheduled-stop flags, and lock actions.',
            'url': '/logistics/details/geofence-enforcement/',
            'image': 'images/logistics/Geof.png',
        },
        {
            'title': 'AI Fatigue Detection',
            'description': 'Biometric drowsiness and distraction detection with in-cab warning, video triage, and active intervention.',
            'url': '/logistics/details/ai-fatigue-detection/',
            'image': 'images/logistics/aifotage.png',
        },
        {
            'title': 'Precision Fuel Probes',
            'description': 'High-accuracy fuel measurement for anti-siphoning control and real-time theft detection.',
            'url': '/logistics/details/precision-fuel-probes/',
            'image': 'images/logistics/pfuel.jpg',
        },
        {
            'title': 'Digital Valve Seals',
            'description': 'Encrypted valve access control with tamper events, custody logs, and geofenced release.',
            'url': '/logistics/details/digital-valve-seals/',
            'image': 'images/logistics/digivalve.png',
        },
        {
            'title': 'Hatch Integrity',
            'description': 'Wireless hatch breach monitoring with instant alerts and contamination prevention controls.',
            'url': '/logistics/details/hatch-integrity/',
            'image': 'images/logistics/hintegrit.png',
        },
        {
            'title': 'Fuel Reconciliation',
            'description': 'Automated in-vs-out auditing with temperature correction and delta-loss reporting.',
            'url': '/logistics/details/fuel-reconciliation/',
            'image': 'images/logistics/FuelRec.webp',
        },
        {
            'title': 'Explosion-Proof Infrastructure',
            'description': 'ATEX-ready enclosures, IS barriers, and sealed installations for hazardous operations.',
            'url': '/logistics/details/explosion-proof-infrastructure/',
            'image': 'images/logistics/explosionproof.webp',
        },
        {
            'title': 'Security Response',
            'description': 'Highway-positioned rapid response units with command-center-linked dispatch and recovery support.',
            'url': '/logistics/details/security-response/',
            'image': 'images/logistics/Sresponse.webp',
        },
    ]

    risk_management_slider_cards = [
        {
            'title': 'Active Voltage Conditioner',
            'description': 'Voltage stability protection for critical operations and uptime-sensitive assets.',
            'url': '/risk-management/details/active-voltage-conditioner/',
            'image': 'images/risk-details/acvoltage.jpg',
        },
        {
            'title': 'Modular Power Distribution',
            'description': 'Deployable power infrastructure with controlled commissioning and relocation risk.',
            'url': '/risk-management/details/modular-power-distribution/',
            'image': 'images/risk-details/mpower.avif',
        },
        {
            'title': 'Vibrating Wire Crackmeter',
            'description': 'Structural displacement monitoring with threshold-based risk observations.',
            'url': '/risk-management/details/vibrating-wire-crackmeter/',
            'image': 'images/risk-details/ckmeter.jpg',
        },
        {
            'title': 'Wireless Tiltmeter',
            'description': 'Ground and structural tilt monitoring for early warning risk programs.',
            'url': '/risk-management/details/wireless-tiltmeter/',
            'image': 'images/risk-details/wtltmeter.jpg',
        },
        {
            'title': 'Underground Communications',
            'description': 'Underground communication resilience and emergency continuity controls for mining operations.',
            'url': '/risk-management/details/underground-communications/',
            'image': 'images/risk-details/uground.jpg',
        },
        {
            'title': 'Explosion Prevention',
            'description': 'Intrinsically safe networking and barrier protection for hazardous-area risk reduction.',
            'url': '/risk-management/details/explosion-prevention/',
            'image': 'images/risk-details/eprotection.webp',
        },
    ]
    return logistics_slider_cards, risk_management_slider_cards


def home_view(request, region_code=None):
    """Home page view with featured content"""
    import json
    from .models import CompanySettings
    from django.core.cache import cache
    
    current_region = get_region_object(region_code)
    if not current_region:
        current_region = Region.objects.filter(is_default=True, is_active=True).first()
    
    region_id = getattr(current_region, 'id', None)
    
    # Full-page output caching. The home page is identical for every visitor
    # to a given region, so we render it once and reuse it for the cache window,
    # avoiding all DB queries + template rendering on every single request.
    cache_key = f'homepage:v1:region:{region_id or 0}'
    cached_html = cache.get(cache_key)
    if cached_html is not None:
        from django.http import HttpResponse
        response = HttpResponse(cached_html)
        response['X-Cache'] = 'HIT'
        return response
    
    # Get company settings
    try:
        company_settings = CompanySettings.objects.first()
    except:
        company_settings = None
    
    # Single query for all published services (prefetching region M2M once),
    # grouped by type in Python to avoid 6+ separate DB queries.
    services_qs = Service.objects.filter(is_published=True).order_by('order').prefetch_related('regions')
    services = list(filter_by_region(services_qs, current_region))
    
    def _by_type(limit, *service_types):
        results = [s for s in services if s.service_type in service_types]
        return results[:limit]

    security_services = _by_type(6, 'security')
    cleaning_services = _by_type(9, 'cleaning')
    sector_services = _by_type(7, 'sector')
    logistics_slider_cards = _by_type(6, 'logistics', 'logistic')
    risk_management_slider_cards = _by_type(6, 'risk-management', 'risk management', 'risk_management')
    staffing_solutions = _by_type(6, 'staffing')
    
    testimonials = list(filter_by_region(
        Testimonial.objects.filter(is_published=True).prefetch_related('regions'),
        current_region
    )[:6])
    
    # SEO Meta Tags for Homepage
    meta_title = "Security & Cleaning Services UK, Dubai & Canada | Xinfinity"
    meta_description = "Xinfinity Group provides professional security, CCTV monitoring, and commercial cleaning across the UK, Dubai, and Canada for businesses."
    meta_keywords = "security company, cleaning solutions, facility management, CCTV monitoring, commercial maintenance, property protection, global operations"
    
    # Organization Schema Markup
    organization_schema = {
        "@context": "https://schema.org",
        "@type": "Organization",
        "name": "Xinfinity Group",
        "url": "https://xinfinitygroup.com/",
        "logo": request.build_absolute_uri('/static/logo.png'),
        "description": "Professional provider delivering integrated facility management, protection, and maintenance solutions globally.",
        "areaServed": [
            "UK",
            "Dubai",
            "Canada"
        ],
        "knowsAbout": [
            "Security Services",
            "CCTV Monitoring",
            "Commercial Cleaning",
            "Facility Management"
        ],
        "sameAs": [
            "https://www.facebook.com/xinfinitygroup",
            "https://www.linkedin.com/company/xinfinitygroup",
            "https://www.twitter.com/xinfinitygroup"
        ],
        "contactPoint": {
            "@type": "ContactPoint",
            "contactType": "Customer Service",
            "telephone": company_settings.phone if company_settings else "01515 425 016",
            "email": company_settings.email if company_settings else "info@xinfinitygroup.com"
        },
        "address": {
            "@type": "PostalAddress",
            "streetAddress": company_settings.street_address if company_settings else "67-83 Norfolk Street",
            "addressLocality": company_settings.city if company_settings else "Liverpool",
            "addressRegion": company_settings.region if company_settings else "England",
            "postalCode": company_settings.postal_code if company_settings else "L1 0BG",
            "addressCountry": "GB"
        }
    }
    
    # LocalBusiness Schema Markup
    # Note: Do NOT add aggregateRating unless backed by real, verifiable reviews
    # Fake ratings (ratingValue, reviewCount) can trigger Google manual actions
    local_business_schema = {
        "@context": "https://schema.org",
        "@type": "LocalBusiness",
        "name": "Xinfinity Group",
        "image": request.build_absolute_uri('/static/logo.png'),
        "description": "Security and cleaning services with integrated facility management support for businesses.",
        "address": {
            "@type": "PostalAddress",
            "streetAddress": company_settings.street_address if company_settings else "67-83 Norfolk Street",
            "addressLocality": company_settings.city if company_settings else "Liverpool",
            "addressRegion": company_settings.region if company_settings else "England",
            "postalCode": company_settings.postal_code if company_settings else "L1 0BG",
            "addressCountry": "GB"
        },
        "telephone": company_settings.phone if company_settings else "01515 425 016",
        "url": "https://xinfinitygroup.com/",
        "areaServed": [
            "UK",
            "Dubai",
            "Canada"
        ],
        "serviceType": [
            "Security Services",
            "Cleaning Services",
            "Facility Management"
        ],
        "priceRange": "$$"
    }
    website_schema = {
        "@context": "https://schema.org",
        "@type": "WebSite",
        "name": "Xinfinity Group",
        "url": "https://xinfinitygroup.com/",
        "inLanguage": "en-GB",
        "publisher": {
            "@type": "Organization",
            "name": "Xinfinity Group",
            "url": "https://xinfinitygroup.com/"
        }
    }
    faq_schema = {
        "@context": "https://schema.org",
        "@type": "FAQPage",
        "mainEntity": [
            {
                "@type": "Question",
                "name": "What security services does Xinfinity Group provide?",
                "acceptedAnswer": {
                    "@type": "Answer",
                    "text": "Xinfinity Group provides manned guarding, CCTV monitoring, mobile patrols, key holding, and risk-focused site protection services."
                }
            },
            {
                "@type": "Question",
                "name": "Do you provide commercial cleaning in Dubai and Canada?",
                "acceptedAnswer": {
                    "@type": "Answer",
                    "text": "Yes. We deliver commercial cleaning services in the UK, Dubai, and Canada for offices, retail premises, and industrial facilities."
                }
            },
            {
                "@type": "Question",
                "name": "Can Xinfinity Group manage multiple sites?",
                "acceptedAnswer": {
                    "@type": "Answer",
                    "text": "Yes. Our integrated facility management model is designed for both single-site businesses and multi-location operations."
                }
            },
            {
                "@type": "Question",
                "name": "Where is Xinfinity Group based?",
                "acceptedAnswer": {
                    "@type": "Answer",
                    "text": "Our core office is based in Liverpool, and we support clients across the UK, Dubai, and Canada."
                }
            }
        ]
    }
    
    # BreadcrumbList Schema
    breadcrumb_schema = {
        "@context": "https://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement": [
            {
                "@type": "ListItem",
                "position": 1,
                "name": "Home",
                "item": request.build_absolute_uri('/')
            }
        ]
    }
    
    hero_section = get_region_single_content(
        HeroSection.objects.filter(is_active=True), current_region
    )
    certification_section = get_region_single_content(
        CertificationSection.objects.filter(is_active=True), current_region
    )
    certifications = filter_by_region(
        Certification.objects.filter(is_published=True).order_by('order'),
        current_region
    )[:10]
    why_choose_section = get_region_single_content(
        WhyChooseSection.objects.filter(is_active=True), current_region
    )
    feature_cards = FeatureCard.objects.select_related('section').filter(
        section=why_choose_section
    ).order_by('order')[:8] if why_choose_section else []
    key_differentiators = filter_by_region(
        KeyDifferentiator.objects.filter(is_published=True).order_by('order'),
        current_region
    )[:8]
    testimonial_section = get_region_single_content(
        TestimonialSection.objects.filter(is_active=True), current_region
    )
    
    context = {
        'services': services,
        'security_services': security_services,
        'cleaning_services': cleaning_services,
        'sector_services': sector_services,
        'logistics_slider_cards': logistics_slider_cards,
        'risk_management_slider_cards': risk_management_slider_cards,
        'staffing_solutions': staffing_solutions,
        'testimonials': testimonials,
        'meta_title': meta_title,
        'meta_description': meta_description,
        'meta_keywords': meta_keywords,
        'organization_schema': json.dumps(organization_schema),
        'local_business_schema': json.dumps(local_business_schema),
        'website_schema': json.dumps(website_schema),
        'faq_schema': json.dumps(faq_schema),
        'breadcrumb_schema': json.dumps(breadcrumb_schema),
        # Dynamic homepage content
        'hero_section': hero_section,
        'certification_section': certification_section,
        'certifications': certifications,
        'why_choose_section': why_choose_section,
        'feature_cards': feature_cards,
        'key_differentiators': key_differentiators,
        'testimonial_section': testimonial_section,
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    
    # Render the full page once and cache the HTML for the cache window.
    rendered = render(request, 'home.html', context)
    try:
        cache.set(cache_key, rendered.content, 600)
    except Exception:
        pass
    rendered['X-Cache'] = 'MISS'
    return rendered


def geo_debug_view(request):
    """Temporary debug view to inspect IP headers and geo detection."""
    geo_data = getattr(request, 'geo_data', None)
    data = {
        "remote_addr": request.META.get("REMOTE_ADDR", ""),
        "x_forwarded_for": request.META.get("HTTP_X_FORWARDED_FOR", ""),
        "x_real_ip": request.META.get("HTTP_X_REAL_IP", ""),
        "detected_country": getattr(geo_data, "country_code", None),
        "detected_country_name": getattr(geo_data, "country_name", None),
        "geo_provider": getattr(geo_data, "provider", None),
    }
    return JsonResponse(data)


def about_view(request, region_code=None):
    """About page view"""
    import json
    from .models import CompanySettings
    current_region = get_region_object(region_code)
    
    # Get company settings
    try:
        company_settings = CompanySettings.objects.first()
    except:
        company_settings = None
    
    try:
        about = About.objects.first()
    except About.DoesNotExist:
        raise Http404("About page not found")
    
    team_qs = TeamMember.objects.all()
    services_qs = Service.objects.filter(is_published=True)
    
    team_members = filter_by_region(team_qs, current_region)
    services = filter_by_region(services_qs, current_region)
    
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    
    # SEO Meta Tags - Use model fields if available
    meta_title = about.meta_title or f"About XinfinityGroup{region_suffix} - Professional Facilities Management"
    meta_description = about.meta_description or f"Learn about XinfinityGroup's mission, values, and team. Leading facilities management services provider{region_suffix} with 20+ years of experience."
    meta_keywords = about.meta_keywords or "about us, company information, facilities management, XinfinityGroup, professional services"
    
    # Organization Schema with extended information
    organization_schema = {
        "@context": "https://schema.org",
        "@type": "Organization",
        "name": "XinfinityGroup",
        "url": request.build_absolute_uri('/'),
        "logo": request.build_absolute_uri('/static/logo.png'),
        "description": "Leading facilities management services provider offering comprehensive security, cleaning, and facility management solutions.",
        "foundingDate": "2004",
        "sameAs": [
            "https://www.facebook.com/xinfinitygroup",
            "https://www.linkedin.com/company/xinfinitygroup",
            "https://www.twitter.com/xinfinitygroup"
        ],
        "contactPoint": {
            "@type": "ContactPoint",
            "contactType": "Customer Service",
            "telephone": company_settings.phone if company_settings else "01515 425 016",
            "email": company_settings.email if company_settings else "info@xinfinitygroup.com"
        },
        "address": {
            "@type": "PostalAddress",
            "streetAddress": company_settings.street_address if company_settings else "67-83 Norfolk Street",
            "addressLocality": company_settings.city if company_settings else "Liverpool",
            "addressRegion": company_settings.region if company_settings else "England",
            "postalCode": company_settings.postal_code if company_settings else "L1 0BG",
            "addressCountry": "GB"
        },
        "certifications": [
            "ISO 9001",
            "ISO 45001",
            "SafeContractor",
            "SSIP"
        ]
    }
    
    # Team Members Schema
    team_schema_list = []
    for member in team_members[:6]:
        team_schema_list.append({
            "@type": "Person",
            "name": member.name,
            "jobTitle": member.position,
            "image": member.photo.url if member.photo else None,
            "description": member.bio
        })
    
    # BreadcrumbList Schema
    breadcrumb_schema = {
        "@context": "https://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement": [
            {
                "@type": "ListItem",
                "position": 1,
                "name": "Home",
                "item": request.build_absolute_uri('/')
            },
            {
                "@type": "ListItem",
                "position": 2,
                "name": "About Us",
                "item": request.build_absolute_uri('/about/')
            }
        ]
    }
    
    context = {
        'about': about,
        'team_members': team_members,
        'services': services,
        'meta_title': meta_title,
        'meta_description': meta_description,
        'meta_keywords': meta_keywords,
        'organization_schema': json.dumps(organization_schema),
        'team_schema_list': json.dumps(team_schema_list),
        'breadcrumb_schema': json.dumps(breadcrumb_schema),
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    
    return render(request, 'pages/about.html', context)


def services_list_view(request, region_code=None):
    """Services listing page"""
    current_region = get_region_object(region_code)
    
    services_qs = Service.objects.filter(is_published=True)
    services = filter_by_region(services_qs, current_region)
    region_prefix = get_region_prefix(current_region)
    itemlist_schema = {
        "@context": "https://schema.org",
        "@type": "ItemList",
        "name": "Xinfinity Group Services",
        "itemListElement": [
            {
                "@type": "ListItem",
                "position": index + 1,
                "name": service.title,
                "url": request.build_absolute_uri(service.get_absolute_url())
            }
            for index, service in enumerate(services)
        ]
    }
    breadcrumb_schema = {
        "@context": "https://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement": [
            {
                "@type": "ListItem",
                "position": 1,
                "name": "Home",
                "item": request.build_absolute_uri(f'{region_prefix}/' if region_prefix else '/')
            },
            {
                "@type": "ListItem",
                "position": 2,
                "name": "Services",
                "item": request.build_absolute_uri(f'{region_prefix}/services/' if region_prefix else '/services/')
            }
        ]
    }
    
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    
    context = {
        'services': services,
        'meta_title': build_meta_title(
            '',
            f'Our Services{region_suffix}',
            short_suffix=" | XinfinityGroup",
            long_suffix=" | Facilities Management | XinfinityGroup"
        ),
        'meta_description': build_meta_description(
            '',
            f"Explore XinfinityGroup's full range of security, cleaning, and facilities management services{region_suffix}. "
            "ISO-certified teams, 24/7 support, and tailored plans for commercial and public-sector sites."
        ),
        'meta_keywords': 'security services UK, cleaning services UK, facility management UK, commercial cleaning Dubai, facility management Canada',
        'itemlist_schema': json.dumps(itemlist_schema),
        'breadcrumb_schema': json.dumps(breadcrumb_schema),
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    
    return render(request, 'pages/services.html', context)


def service_detail_view(request, slug, region_code=None):
    """Service detail view"""
    import json
    current_region = get_region_object(region_code)
    
    service = get_object_or_404(Service, slug=slug, is_published=True)
    
    # Ensure this service is actually available in this region?
    # Ideally yes, but filter_by_region handles list views.
    # For detail, we might want to check:
    if current_region and service.regions.exists() and current_region not in service.regions.all():
         # If service has specific regions and current is not one of them
         raise Http404("Service not available in this region")

    services_qs = Service.objects.filter(is_published=True)
    services = filter_by_region(services_qs, current_region)
    
    related_services = services.exclude(id=service.id)[:3]
    
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    
    # SEO Meta Tags - Use model fields if available, otherwise generate
    meta_title = build_meta_title(
        service.meta_title,
        f"{service.title} Services{region_suffix}",
        short_suffix=" | XinfinityGroup",
        long_suffix=" | Facilities Management | XinfinityGroup"
    )
    meta_description = build_meta_description(
        service.meta_description,
        service.description
        or f"Comprehensive {service.title.lower()} services{region_suffix} for commercial, industrial, and public-sector sites. "
           "ISO-certified teams, 24/7 support, and tailored plans to improve safety, compliance, and performance."
    )
    meta_keywords = service.meta_keywords or f"{service.title}, professional services, XinfinityGroup"
    
    # Service Schema Markup
    service_schema = {
        "@context": "https://schema.org",
        "@type": "Service",
        "name": service.title,
        "description": service.description[:500] if service.description else meta_description,
        "provider": {
            "@type": "Organization",
            "name": "XinfinityGroup",
            "url": request.build_absolute_uri('/')
        },
        "areaServed": ["GB", "CA", "AE", "IE"],
        "serviceType": service.title,
        "image": service.image.url if service.image else request.build_absolute_uri('/static/logo.png'),
        "url": request.build_absolute_uri(service.get_absolute_url()),
        "isRelatedTo": [
            request.build_absolute_uri(item.get_absolute_url())
            for item in list(related_services)
        ]
    }
    
    region_prefix = get_region_prefix(current_region)

    # BreadcrumbList Schema
    breadcrumb_schema = {
        "@context": "https://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement": [
            {
                "@type": "ListItem",
                "position": 1,
                "name": "Home",
                "item": request.build_absolute_uri(f'{region_prefix}/' if region_prefix else '/')
            },
            {
                "@type": "ListItem",
                "position": 2,
                "name": "Services",
                "item": request.build_absolute_uri(f'{region_prefix}/services/' if region_prefix else '/services/')
            },
            {
                "@type": "ListItem",
                "position": 3,
                "name": service.title,
                "item": request.build_absolute_uri(service.get_absolute_url())
            }
        ]
    }
    
    detail_body_html = getattr(service, 'detail_body_html', '') or ''
    detail_lede = getattr(service, 'detail_lede', '') or ''
    detail_lede_text = detail_lede or (service.description if detail_body_html else "")
    detail_body_html_rendered = detail_body_html or _plain_text_to_rich_html(service.description)

    context = {
        'service': service,
        'related_services': related_services,
        'services': services,
        'detail_lede_text': detail_lede_text,
        'detail_body_html_rendered': detail_body_html_rendered,
        'meta_title': meta_title,
        'meta_description': meta_description,
        'meta_keywords': meta_keywords,
        'meta_image': (
            request.build_absolute_uri(service.meta_image.url)
            if service.meta_image else (
                request.build_absolute_uri(service.image.url)
                if service.image else request.build_absolute_uri('/static/logo.png')
            )
        ),
        'canonical_url_override': service.meta_canonical_url or request.build_absolute_uri(service.get_absolute_url()),
        'og_type': 'website',
        'twitter_card': 'summary_large_image',
        'service_schema': json.dumps(service_schema),
        'breadcrumb_schema': json.dumps(breadcrumb_schema),
        'page_type': 'service',  # For breadcrumb generation
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    
    return render(request, 'pages/service_detail.html', context)


def team_view(request, region_code=None):
    """Team page view"""
    current_region = get_region_object(region_code)
    
    team_qs = TeamMember.objects.all()
    services_qs = Service.objects.filter(is_published=True)
    
    team_members = filter_by_region(team_qs, current_region)
    services = filter_by_region(services_qs, current_region)
    
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    
    context = {
        'team_members': team_members,
        'services': services,
        'meta_title': f'Our Team{region_suffix}',
        'meta_description': f'Meet our experienced team of security and facility management professionals{region_suffix}.',
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    
    return render(request, 'pages/team.html', context)


def _get_client_ip(request):
    forwarded = request.META.get('HTTP_X_FORWARDED_FOR', '')
    if forwarded:
        return forwarded.split(',')[0].strip()
    return request.META.get('REMOTE_ADDR', 'unknown')


def _is_contact_rate_limited(request):
    client_ip = _get_client_ip(request)
    key = f"contact_rate_limit:{client_ip}"
    attempts = cache.get(key, 0)
    return attempts >= settings.CONTACT_FORM_RATE_LIMIT


def _touch_contact_rate_limit(request):
    client_ip = _get_client_ip(request)
    key = f"contact_rate_limit:{client_ip}"
    attempts = cache.get(key, 0) + 1
    cache.set(key, attempts, timeout=settings.CONTACT_FORM_RATE_WINDOW_SECONDS)


def _verify_turnstile_token(token, request):
    """Verify Cloudflare Turnstile token server-side."""
    secret = settings.TURNSTILE_SECRET_KEY
    if not secret:
        # Allow operation when key is not configured; honeypot + rate-limit still apply.
        return True
    if not token:
        return False

    payload = {
        'secret': secret,
        'response': token,
        'remoteip': _get_client_ip(request),
    }
    data = urllib.parse.urlencode(payload).encode('utf-8')
    req = urllib.request.Request(
        'https://challenges.cloudflare.com/turnstile/v0/siteverify',
        data=data,
        method='POST',
        headers={'Content-Type': 'application/x-www-form-urlencoded'},
    )
    try:
        with urllib.request.urlopen(req, timeout=5) as response:
            result = json.loads(response.read().decode('utf-8'))
            return bool(result.get('success'))
    except Exception:
        return False


SPAM_KEYWORDS = (
    'viagra', 'casino', 'bitcoin', 'crypto', 'whatsapp', 'seo specialist',
    'backlink', 'guest post', 'buy', 'sell', 'porn', 'escort', 'loan',
    'invest', 'bank transfer', 'western union', 'herbal', 'click here',
    'earn money', 'make money online', 'forex', 'jackpot', 'prize',
)

# Known spam bot name (Robertnox group sends the same translated
# "I wanted to know your price" message in dozens of languages).
SPAM_BOT_NAMES = ('robertnox',)

# "price" words in the ~30 languages the bot uses. Only matched against very
# short messages (see _contact_spam_reason), so genuine inquiries stay unflagged.
_SPAM_PRICE_WORDS = (
    'precio', 'prezzo', 'prezo', 'preu', 'prys', 'präis', 'pris', 'price',
    'precio', 'harga', 'praghas', 'prezioa', 'pretium', 'verð', 'kainą',
    'cijenu', 'árát', 'çmimin tuaj', 'qiymətinizi', 'giá', 'prajs', 'цена',
    'прайс', 'ფასი', 'գինը', 'মূল্য', 'τιμή',
)


def _contact_spam_reason(form_data: dict) -> str:
    """Heuristic spam filter for contact submissions. Returns '' if genuine."""
    name = str(form_data.get('name') or '').lower()
    for bot_name in SPAM_BOT_NAMES:
        if bot_name in name:
            return f'known spam bot name "{bot_name}"'

    haystack = ' '.join(
        str(value or '').lower()
        for value in form_data.values()
    )
    for keyword in SPAM_KEYWORDS:
        if keyword in haystack:
            return f'contains spam keyword "{keyword}"'

    url_count = len(re.findall(r'https?://', haystack))
    if url_count >= 3:
        return 'too many URLs'

    message = str(form_data.get('message') or '')
    if message != message.strip() or '\n\n\n' in message:
        return 'suspicious formatting'

    # Robertnox-style mass bot: a very short "know your price" message in any
    # language. Real inquiries are longer than this bot's one-liner.
    msg = message.lower()
    if len(message) <= 140 and any(word in msg for word in _SPAM_PRICE_WORDS):
        return 'translated price-inquiry spam'

    return ''


def contact_view(request, region_code=None):
    """Contact page view with form handling"""
    current_region = get_region_object(region_code)
    
    if request.method == 'POST':
        form = ContactForm(request.POST)
        honeypot_value = request.POST.get('website', '').strip()
        turnstile_token = request.POST.get('cf-turnstile-response', '')
        client_ip = get_real_ip(request)

        _touch_contact_rate_limit(request)

        # A previously-blocked IP is rejected outright and never stored.
        if BLOCKLIST.is_blocked(client_ip):
            messages.error(request, 'Unable to submit your request. Please try again.')
            return redirect(request.path)

        if honeypot_value:
            AUTO_BLOCK.register_violation(request, 'honeypot field filled', source='contact_form')
            messages.error(request, 'Unable to submit your request. Please try again.')
        elif _is_contact_rate_limited(request):
            AUTO_BLOCK.register_violation(request, 'rate limit exceeded', source='rate_limit')
            messages.error(request, 'Too many requests. Please wait a few minutes before trying again.')
        elif not _verify_turnstile_token(turnstile_token, request):
            AUTO_BLOCK.register_violation(request, 'captcha verification failed', source='contact_form')
            messages.error(request, 'Captcha verification failed. Please try again.')
        elif form.is_valid():
            cleaned = form.cleaned_data
            name = cleaned['name']
            email = cleaned['email']
            phone = cleaned['phone']
            subject = cleaned['subject']
            message = cleaned['message']

            # Collect request-level intelligence for this submission.
            user_agent = request.META.get('HTTP_USER_AGENT', '') or ''
            profile = None
            if client_ip and ua_is_valid_ip(client_ip) and not ua_is_private_ip(client_ip):
                try:
                    profile = IPGeolocationService().lookup(client_ip)
                except Exception:
                    profile = None

            raw = {
                'name': name,
                'email': email,
                'phone': phone,
                'subject': subject,
                'message': message,
            }
            spam_reason = _contact_spam_reason(raw)

            Contact.objects.create(
                name=name,
                email=email,
                phone=phone or '',
                subject=subject or '',
                message=message,
                ip_address=client_ip if ua_is_valid_ip(client_ip) else None,
                country_code=(profile.country_code if profile else '') or '',
                country_name=(profile.country_name if profile else '') or '',
                city=(profile.city if profile else '') or '',
                user_agent=user_agent[:2000],
                is_spam=bool(spam_reason),
                spam_reason=spam_reason,
            )

            if spam_reason:
                AUTO_BLOCK.register_violation(request, f'spam content: {spam_reason}', source='contact_form')

            # Track contact form submission in GA4
            _track_contact_form_submission(request, name, email, subject)
            
            messages.success(request, 'Thank you for your message. We will get back to you soon!')
            
            return redirect(request.path)
        else:
            messages.error(request, 'There was an error with your submission. Please check the form and try again.')
    else:
        form = ContactForm()
    
    services_qs = Service.objects.filter(is_published=True)
    services = filter_by_region(services_qs, current_region)
    
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    
    context = {
        'services': services,
        'form': form,
        'turnstile_site_key': settings.TURNSTILE_SITE_KEY,
        'meta_title': f'Contact Xinfinity Group{region_suffix} | Security Company',
        'meta_description': f'Contact Xinfinity Group for security services, CCTV monitoring, and cleaning services{region_suffix}.',
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    
    return render(request, 'pages/contact.html', context)


def privacy_policy_view(request, region_code=None):
    """Privacy Policy page view"""
    current_region = get_region_object(region_code)
    services = filter_by_region(Service.objects.filter(is_published=True), current_region)
    
    context = {
        'services': services,
        'meta_title': 'Privacy Policy - XinfinityGroup',
        'meta_description': 'Learn how XinfinityGroup protects your privacy and handles your personal information in our security, cleaning, and facility management services.',
        'meta_keywords': 'privacy policy, data protection, XinfinityGroup, security services',
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/privacy-policy.html', context)


def terms_of_service_view(request, region_code=None):
    """Terms of Service page view"""
    current_region = get_region_object(region_code)
    services = filter_by_region(Service.objects.filter(is_published=True), current_region)
    
    context = {
        'services': services,
        'meta_title': 'Terms of Service - XinfinityGroup',
        'meta_description': 'Read the XinfinityGroup terms of service covering service scope, responsibilities, compliance requirements, and contractual conditions.',
        'meta_keywords': 'terms of service, conditions, XinfinityGroup, security services, cleaning services',
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/terms-of-service.html', context)


def cookie_policy_view(request, region_code=None):
    """Cookie Policy page view"""
    current_region = get_region_object(region_code)
    services = filter_by_region(Service.objects.filter(is_published=True), current_region)
    
    context = {
        'services': services,
        'meta_title': 'Cookie Policy - XinfinityGroup',
        'meta_description': 'Learn about how XinfinityGroup uses cookies on our website to improve your browsing experience.',
        'meta_keywords': 'cookie policy, website cookies, XinfinityGroup, privacy',
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/cookie-policy.html', context)


def accessibility_view(request, region_code=None):
    """Accessibility Statement page view"""
    current_region = get_region_object(region_code)
    services = filter_by_region(Service.objects.filter(is_published=True), current_region)
    
    context = {
        'services': services,
        'meta_title': 'Accessibility Statement - XinfinityGroup',
        'meta_description': 'XinfinityGroup is committed to ensuring digital accessibility for people with disabilities.',
        'meta_keywords': 'accessibility, disability access, XinfinityGroup, inclusive design',
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/accessibility.html', context)


def sitemap_view(request, region_code=None):
    """Sitemap page view"""
    current_region = get_region_object(region_code)
    
    services = filter_by_region(Service.objects.filter(is_published=True), current_region)
    
    
    context = {
        'services': services,
        'meta_title': 'Sitemap - XinfinityGroup',
        'meta_description': 'Find all pages and content on the XinfinityGroup website with our comprehensive sitemap.',
        'meta_keywords': 'sitemap, website navigation, XinfinityGroup, site structure',
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/sitemap.html', context)


def security_view(request, region_code=None):
    current_region = get_region_object(region_code)
    # Fetch security services from database
    qs = Service.objects.filter(is_published=True).order_by('order')
    qs = filter_by_region(qs, current_region)
    
    security_services = qs[:6] # Or filter by type? Original was just first 6.
    
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    
    context = {
        'security_services': security_services,
        'meta_title': f'Security Services{region_suffix} | Xinfinity Group',
        'meta_description': f'Professional security services including manned guarding, CCTV monitoring, mobile patrols, and key holding{region_suffix}.',
        'meta_keywords': 'security services UK, security company Liverpool, CCTV monitoring UK, security guard services Dubai, security services Canada',
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/security.html', context)


def cleaning_view(request, region_code=None):
    current_region = get_region_object(region_code)
    
    # Fetch cleaning services from database
    qs = Service.objects.filter(is_published=True, title__icontains='cleaning').order_by('order')
    qs = filter_by_region(qs, current_region)
    
    cleaning_services = qs[:6]
    
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    
    context = {
        'cleaning_services': cleaning_services,
        'meta_title': f'Commercial Cleaning Services{region_suffix} | Xinfinity',
        'meta_description': f'Trusted commercial cleaning services for offices, retail, and industrial sites{region_suffix} with reliable quality control.',
        'meta_keywords': 'cleaning services UK, commercial cleaning Dubai, office cleaning Liverpool, industrial cleaning Canada, contract cleaning services',
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/cleaning.html', context)


def properties_view(request, region_code=None):
    current_region = get_region_object(region_code)
    
    # Fetch properties services from database
    qs = Service.objects.filter(is_published=True, title__icontains='properties').order_by('order')
    qs = filter_by_region(qs, current_region)
    
    properties_services = qs[:6]
    
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    
    context = {
        'properties_services': properties_services,
        'meta_title': f'Property & Facility Management Services{region_suffix} | Xinfinity Group',
        'meta_description': f'Integrated property and facility management services{region_suffix} that improve site standards, compliance, and operational performance.',
        'meta_keywords': 'facility management UK, property management services, building maintenance, facilities support, commercial property services',
    }
    context = get_common_context(context, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/properties.html', context)


def staffing_view(request, region_code=None):
    current_region = get_region_object(region_code)

    qs = Service.objects.filter(is_published=True).order_by('order').prefetch_related('regions')
    qs = filter_by_region(qs, current_region)
    staffing_services = qs.filter(service_type='staffing')

    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    is_uk = current_region is None or (current_region and current_region.code == 'uk')

    uk_stat_pills = [
        {'label': 'Workers Supplied', 'value': '1,200+', 'icon': 'users',
         'tile_bg': 'bg-blue-100 border-blue-100', 'icon_bg': 'bg-gradient-to-br from-blue-100 to-indigo-50', 'icon_fg': 'text-blue-600', 'value_fg': 'text-blue-700'},
        {'label': 'Temp & Contract', 'value': '100%', 'icon': 'briefcase',
         'tile_bg': 'bg-indigo-100 border-indigo-100', 'icon_bg': 'bg-gradient-to-br from-indigo-100 to-purple-50', 'icon_fg': 'text-indigo-600', 'value_fg': 'text-indigo-700'},
        {'label': 'Compliance Audits Passed', 'value': '100%', 'icon': 'shield-check',
         'tile_bg': 'bg-sky-100 border-sky-100', 'icon_bg': 'bg-gradient-to-br from-sky-100 to-cyan-50', 'icon_fg': 'text-sky-600', 'value_fg': 'text-sky-700'},
        {'label': 'Client Retention', 'value': '96%', 'icon': 'heart-handshake',
         'tile_bg': 'bg-emerald-100 border-emerald-100', 'icon_bg': 'bg-gradient-to-br from-emerald-100 to-green-50', 'icon_fg': 'text-emerald-600', 'value_fg': 'text-emerald-700'},
    ]

    uk_portfolio_metrics = [
        {'label': 'Staff Deployment Time', 'value': '3.2 days', 'accent': 'from-sky-400 to-cyan-300', 'pct': 92},
        {'label': 'Right-to-Work Compliance', 'value': '100%', 'accent': 'from-emerald-400 to-teal-300', 'pct': 100},
        {'label': 'Time-sheet Accuracy', 'value': '99.2%', 'accent': 'from-amber-400 to-orange-300', 'pct': 99},
        {'label': 'Worker Retention (90d)', 'value': '94%', 'accent': 'from-indigo-400 to-purple-300', 'pct': 94},
    ]

    staffing_sections = [
        {
            'title': 'Temporary & Contract Staff',
            'icon': 'clock-3',
            'summary': 'Rapid deployment of vetted temporary, fixed-term, and contract workers across cleaning, security, construction, facilities, and front-of-house roles — cover peaks, sickness, planned leave, and project surges with UK-compliant payroll and insurances in place from day one.',
            'card_bg': 'bg-gradient-to-br from-blue-50 to-indigo-100',
            'card_border': 'border-blue-200',
            'card_icon_bg': 'bg-gradient-to-br from-blue-500 to-indigo-700',
            'section_header_bg': 'bg-gradient-to-br from-blue-500 to-indigo-700',
            'section_border': 'border-blue-100',
            'card_icon': 'user-plus',
            'services': [
                {'title': 'Temporary Cleaning Operatives', 'desc': 'Daily/weekly/monthly cover for commercial, education, healthcare, and public-sector cleaning contracts with DBS, uniform, and training provided.'},
                {'title': 'Security Officers (SIA Licenced)', 'desc': 'Short-notice SIA front-line, CCTV, key holding, and events cover including mobile patrols for vacant sites and retail operations.'},
                {'title': 'Construction Site Staff', 'desc': 'CSCS carded labourers, groundworkers, site marshals, banksmen, and trade support for building, civil engineering, and infrastructure projects.'},
                {'title': 'Warehouse & Industrial Staff', 'desc': 'Pickers, packers, FLT, yard marshals, and goods-in staff for 3PL, FMCG, and last-mile depots with RTW and induction checks.'},
            ],
        },
        {
            'title': 'Construction Workforce Supply',
            'icon': 'hammer',
            'summary': 'Dedicated construction staffing from site labour to skilled trade support — CSCS-qualified personnel, site safety compliant, ready for long-term projects or short-term mobilisations across the UK.',
            'card_bg': 'bg-gradient-to-br from-orange-50 to-amber-100',
            'card_border': 'border-orange-200',
            'card_icon_bg': 'bg-gradient-to-br from-orange-500 to-amber-700',
            'section_header_bg': 'bg-gradient-to-br from-orange-500 to-amber-700',
            'section_border': 'border-orange-100',
            'card_icon': 'wrench',
            'services': [
                {'title': 'General Labourers (CSCS)', 'desc': 'Site prep, clear-up, material handling, and general site support with valid CSCS cards and site-specific PPE provided.'},
                {'title': 'Groundworkers & Banksmen', 'desc': 'Groundworks support, excavation banksman duties, vehicle marshalling, and plant-safety trained personnel.'},
                {'title': 'Trade Support & Mates', 'desc': 'Skilled mates for carpentry, bricklaying, plastering, plumbing, and electrical teams across residential and commercial builds.'},
                {'title': 'Site Marshals & Access Control', 'desc': 'Visitor sign-in, delivery coordination, access control, and fire-warden trained marshals for live construction sites.'},
            ],
        },
        {
            'title': 'Managed Workforce Solutions',
            'icon': 'layout-grid',
            'summary': 'Full outsourcing of temporary labour supply, multi-site master vendor, and on-site managed service teams — combining Xinfinity cleaning, security, and construction delivery with workforce planning, payroll, compliance, and MI reporting.',
            'card_bg': 'bg-gradient-to-br from-emerald-50 to-green-100',
            'card_border': 'border-emerald-200',
            'card_icon_bg': 'bg-gradient-to-br from-emerald-500 to-green-700',
            'section_header_bg': 'bg-gradient-to-br from-emerald-500 to-green-700',
            'section_border': 'border-emerald-100',
            'card_icon': 'network',
            'services': [
                {'title': 'On-site Managed Teams', 'desc': 'Embedded team leaders, payroll, inductions, HR, and quality controls for large cleaning, security, and construction contracts across the UK.'},
                {'title': 'Master Vendor Supply', 'desc': 'Single-supplier orchestration of preferred labour providers with rate cards, SLAs, consolidated invoicing, and compliance screening.'},
                {'title': 'Bulk Mobilisation Projects', 'desc': 'Scaled workforce roll-outs for new contract starts, project phases, seasonal peaks, and rapid-response deployments with named PM lead.'},
                {'title': 'Bespoke Outsource Projects', 'desc': 'Custom build of workforce resilience programmes, TUPE-style transfers, restructure support, and weekly MI reporting dashboards.'},
            ],
        },
        {
            'title': 'Compliance, Payroll & Support',
            'icon': 'shield-check',
            'summary': 'UK employment-law and tax-compliant back-office for all supplied workers — Right to Work, DBS, pre-employment screening, PAYE/CIS payroll, pensions auto-enrolment, and on-site HR support.',
            'card_bg': 'bg-gradient-to-br from-sky-50 to-cyan-100',
            'card_border': 'border-sky-200',
            'card_icon_bg': 'bg-gradient-to-br from-sky-500 to-cyan-700',
            'section_header_bg': 'bg-gradient-to-br from-sky-500 to-cyan-700',
            'section_border': 'border-sky-100',
            'card_icon': 'clipboard-check',
            'services': [
                {'title': 'Right-to-Work & DBS Screening', 'desc': 'Home-office compliant ID and RTW verification, Basic, Standard, and Enhanced DBS, barred list, and online update service checks.'},
                {'title': 'PAYE & CIS Payroll', 'desc': 'Weekly / monthly CIS, PAYE, and AWR-compliant payroll with auto-enrolment, holiday pay, and HMRC RTI submissions handled end-to-end.'},
                {'title': 'On-site HR & Support', 'desc': 'Worker contracts, handbooks, disciplinaries, grievance support, and day-to-day HR advisory backed by qualified employment-law partners.'},
                {'title': 'Qualifications & Training', 'desc': 'CSCS, SIA top-ups, IOSH, manual handling, infection control, food safety, fire marshal, and safeguarding training programmes.'},
            ],
        },
    ]

    staffing_industries = [
        {'title': 'Construction & Engineering', 'icon': 'hammer',
         'card_bg': 'bg-gradient-to-br from-orange-50 to-amber-100', 'card_border': 'border-orange-200', 'icon_bg': 'bg-gradient-to-br from-orange-500 to-amber-700'},
        {'title': 'Cleaning & FM Contractors', 'icon': 'sparkles',
         'card_bg': 'bg-gradient-to-br from-emerald-50 to-green-100', 'card_border': 'border-emerald-200', 'icon_bg': 'bg-gradient-to-br from-emerald-500 to-green-700'},
        {'title': 'Security & Events Companies', 'icon': 'shield-alert',
         'card_bg': 'bg-gradient-to-br from-blue-50 to-indigo-100', 'card_border': 'border-blue-200', 'icon_bg': 'bg-gradient-to-br from-blue-500 to-indigo-700'},
        {'title': 'Warehousing, Logistics & 3PL', 'icon': 'truck',
         'card_bg': 'bg-gradient-to-br from-amber-50 to-orange-100', 'card_border': 'border-amber-200', 'icon_bg': 'bg-gradient-to-br from-amber-500 to-orange-700'},
        {'title': 'Education, NHS & Public Sector', 'icon': 'building-2',
         'card_bg': 'bg-gradient-to-br from-sky-50 to-cyan-100', 'card_border': 'border-sky-200', 'icon_bg': 'bg-gradient-to-br from-sky-500 to-cyan-700'},
        {'title': 'Retail, Hospitality & Leisure', 'icon': 'shopping-bag',
         'card_bg': 'bg-gradient-to-br from-indigo-50 to-purple-100', 'card_border': 'border-indigo-200', 'icon_bg': 'bg-gradient-to-br from-indigo-500 to-purple-700'},
        {'title': 'Offices, Co-working & B2B', 'icon': 'briefcase',
         'card_bg': 'bg-gradient-to-br from-cyan-50 to-sky-100', 'card_border': 'border-cyan-200', 'icon_bg': 'bg-gradient-to-br from-cyan-500 to-sky-700'},
        {'title': 'Care, SEN & Residential', 'icon': 'heart-handshake',
         'card_bg': 'bg-gradient-to-br from-emerald-50 to-teal-100', 'card_border': 'border-emerald-200', 'icon_bg': 'bg-gradient-to-br from-emerald-500 to-teal-700'},
    ]

    overview_pill_classes = [
        ('24/7', 'Desk & Out-of-Hours', 'bg-blue-50 border-blue-100', 'text-blue-700'),
        ('Same-Day', 'Emergency Cover', 'bg-indigo-50 border-indigo-100', 'text-indigo-700'),
        ('HMRC & RTW', 'Audit-Ready Payroll', 'bg-emerald-50 border-emerald-100', 'text-emerald-700'),
        ('AWR Compliant', 'Agency Worker Regs', 'bg-sky-50 border-sky-100', 'text-sky-700'),
    ]

    context = get_common_context({
        'meta_title': f'Staffing Solutions & Workforce Supply{region_suffix} | Xinfinity Group',
        'meta_description': f'UK workforce supply delivering temporary, contract, and managed staffing solutions{region_suffix} for cleaning, security, construction, facilities, and industrial roles. Compliance-led, rapid-deployment staff provision with payroll and HR services included.',
        'meta_keywords': 'staffing agency UK, temporary staff supply, contract staffing Liverpool, construction staff agency, cleaning staff supply, security staffing, CSCS labourers, facilities management staff, payroll services, SIA licensed staff supply',
        'staffing_services': staffing_services,
        'is_uk': is_uk,
        'uk_stat_pills': uk_stat_pills,
        'uk_portfolio_metrics': uk_portfolio_metrics,
        'staffing_sections': staffing_sections,
        'staffing_industries': staffing_industries,
        'overview_pill_classes': overview_pill_classes,
        'brand_hero_badge_bg': 'bg-blue-100 text-blue-800',
        'brand_underline': 'bg-gradient-to-r from-blue-500 to-indigo-600',
        'brand_underline_2': 'bg-gradient-to-r from-orange-500 to-amber-600',
        'brand_cta_gradient': 'bg-gradient-to-br from-blue-600 via-indigo-600 to-orange-700',
        'brand_cta_primary': 'text-indigo-700 hover:bg-indigo-50',
        'brand_cta_hover': 'hover:text-indigo-700',
        'brand_hero_badge_icon': 'users',
    }, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/staffing.html', context)

# Placeholder views should also accept region_code to avoid crashing
def retail_view(request, region_code=None):
    current_region = get_region_object(region_code)
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    context = get_common_context({
        'meta_title': f'Retail Security & Cleaning Services{region_suffix} | Xinfinity Group',
        'meta_description': f'Retail-focused security, cleaning, and facility management services{region_suffix} designed for high-footfall environments and trading-hour resilience.',
        'meta_keywords': 'retail security services, retail cleaning services, shopping centre security, retail facility management',
    }, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/retail.html', context)

def construction_view(request, region_code=None):
    current_region = get_region_object(region_code)
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    context = get_common_context({
        'meta_title': f'Construction Site Security & Support Services{region_suffix} | Xinfinity',
        'meta_description': f'Construction support services{region_suffix} including site security, access control, cleaning, and facilities support for active projects.',
        'meta_keywords': 'construction site security, construction cleaning, site access control, construction support services',
    }, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/construction.html', context)

def transport_view(request, region_code=None):
    current_region = get_region_object(region_code)
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    context = get_common_context({
        'meta_title': f'Transport Sector Security & Cleaning Services{region_suffix} | Xinfinity',
        'meta_description': f'Transport-sector security, cleaning, and operational support services{region_suffix} for stations, depots, and logistics routes.',
        'meta_keywords': 'transport security services, station cleaning services, depot facility management, transit security',
    }, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/transport.html', context)

def education_view(request, region_code=None):
    current_region = get_region_object(region_code)
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    context = get_common_context({
        'meta_title': f'Education Sector Facilities Services{region_suffix} | Xinfinity Group',
        'meta_description': f'Security, cleaning, and facilities management services{region_suffix} for schools, colleges, and universities with safeguarding-focused delivery.',
        'meta_keywords': 'school security services, education cleaning services, campus facility management, university cleaning',
    }, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/education.html', context)

def industries_view(request, region_code=None):
    current_region = get_region_object(region_code)
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    context = get_common_context({
        'meta_title': f'Industrial Security & Facility Services{region_suffix} | Xinfinity Group',
        'meta_description': f'Industrial site security, cleaning, and facility management solutions{region_suffix} that improve safety, compliance, and operational uptime.',
        'meta_keywords': 'industrial security services, industrial cleaning services, facility management industrial sites',
    }, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/industries.html', context)

def hospitality_view(request, region_code=None):
    current_region = get_region_object(region_code)
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    context = get_common_context({
        'meta_title': f'Hospitality Security & Cleaning Services{region_suffix} | Xinfinity',
        'meta_description': f'Hospitality-focused security, cleaning, and facilities services{region_suffix} for hotels, venues, and guest-facing businesses.',
        'meta_keywords': 'hospitality security services, hotel cleaning services, venue facility management',
    }, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/hospitality.html', context)

def healthcare_view(request, region_code=None):
    current_region = get_region_object(region_code)
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    context = get_common_context({
        'meta_title': f'Healthcare Cleaning & Security Services{region_suffix} | Xinfinity Group',
        'meta_description': f'Healthcare environment services{region_suffix} including specialist cleaning, compliance-led security, and facility support for clinics and care sites.',
        'meta_keywords': 'healthcare cleaning services, healthcare security services, clinic facility management, medical cleaning',
    }, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/healthcare.html', context)

def logistics_view(request, region_code=None):
    current_region = get_region_object(region_code)
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    services_qs = Service.objects.filter(is_published=True).order_by('order').prefetch_related('regions')
    services = filter_by_region(services_qs, current_region)
    logistics_services = services.filter(service_type__in=['logistics', 'logistic'])

    logistics_image_map = {
        'command-center': 'images/logistics/247.jpeg',
        'uninterrupted-connectivity': 'images/logistics/uninc.jpg',
        'geofence-enforcement': 'images/logistics/Geof.png',
        'ai-fatigue-detection': 'images/logistics/aifotage.png',
        'precision-fuel-probes': 'images/logistics/pfuel.jpg',
        'digital-valve-seals': 'images/logistics/dgvol.webp',
        'hatch-integrity': 'images/logistics/hintegrit.png',
        'fuel-reconciliation': 'images/logistics/FuelRec.webp',
        'explosion-proof-infrastructure': 'images/logistics/explosionproof.webp',
        'security-response': 'images/logistics/Sresponse.webp',
    }

    logistics_section_defs = [
        {
            'title': 'Tactical Monitoring',
            'icon': 'monitor',
            'slugs': ['command-center', 'uninterrupted-connectivity', 'geofence-enforcement', 'ai-fatigue-detection'],
        },
        {
            'title': 'Anti-Theft Tech',
            'icon': 'shield',
            'slugs': ['precision-fuel-probes', 'digital-valve-seals', 'hatch-integrity', 'fuel-reconciliation'],
        },
        {
            'title': 'Safety & Security Response',
            'icon': 'shield-alert',
            'slugs': ['explosion-proof-infrastructure', 'security-response'],
        },
    ]

    fallback_cards = []
    if not logistics_services.exists():
        cards, _ = get_home_slider_cards()
        for item in cards:
            slug = item.get('url', '').rstrip('/').split('/')[-1]
            fallback_cards.append({
                'slug': slug,
                'title': item.get('title', slug),
                'description': item.get('description', ''),
                'url': item.get('url', '#'),
            })

    service_by_slug = {service.slug: service for service in logistics_services}
    fallback_by_slug = {card['slug']: card for card in fallback_cards}
    logistics_sections = []
    used_slugs = set()
    for section_def in logistics_section_defs:
        cards = []
        for slug in section_def['slugs']:
            service = service_by_slug.get(slug)
            fallback = fallback_by_slug.get(slug) if not service else None
            if not service and not fallback:
                continue
            used_slugs.add(slug)
            cards.append({
                'title': service.title if service else fallback['title'],
                'description': service.description if service else fallback['description'],
                'url': (service.primary_cta_url or service.get_absolute_url()) if service else fallback['url'],
                'image': logistics_image_map.get(slug),
            })
        logistics_sections.append({
            'title': section_def['title'],
            'icon': section_def['icon'],
            'cards': cards,
        })

    remaining_cards = []
    if logistics_services.exists():
        for service in logistics_services:
            if service.slug in used_slugs:
                continue
            remaining_cards.append({
                'title': service.title,
                'description': service.description,
                'url': service.primary_cta_url or service.get_absolute_url(),
                'image': logistics_image_map.get(service.slug),
            })
    if remaining_cards:
        logistics_sections.append({
            'title': 'Additional Capabilities',
            'icon': 'layers',
            'cards': remaining_cards,
        })

    context = get_common_context({
        'meta_title': f'Logistics Security & Facility Management{region_suffix} | Xinfinity Group',
        'meta_description': f'Security, cleaning, and facility management solutions{region_suffix} for warehouses, depots, and logistics operations across key markets.',
        'meta_keywords': 'logistics security services, warehouse cleaning services, depot facility management',
        'logistics_sections': logistics_sections,
    }, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/logistics.html', context)

def logistics_detail_page_view(request, detail_slug, region_code=None):
    current_region = get_region_object(region_code)
    service = Service.objects.filter(
        slug=detail_slug,
        is_published=True,
        service_type__in=['logistics', 'logistic'],
    ).first()

    if not service:
        raise Http404('Detail page not found')

    if current_region and service.regions.exists() and current_region not in service.regions.all():
        raise Http404("Service not available in this region")

    tactical = {'command-center', 'uninterrupted-connectivity', 'geofence-enforcement', 'ai-fatigue-detection'}
    anti_theft = {'precision-fuel-probes', 'digital-valve-seals', 'hatch-integrity', 'fuel-reconciliation'}
    response = {'explosion-proof-infrastructure', 'security-response'}

    if detail_slug in tactical:
        section = 'Tactical Monitoring'
    elif detail_slug in anti_theft:
        section = 'Anti-Theft Tech'
    elif detail_slug in response:
        section = 'Safety & Security Response'
    else:
        section = 'Logistics'

    logistics_detail_image_map = {
        'command-center': 'images/logistics/247.jpeg',
        'uninterrupted-connectivity': 'images/logistics/uninc.jpg',
        'geofence-enforcement': 'images/logistics/Geof.png',
        'ai-fatigue-detection': 'images/logistics/aifotage.png',
        'precision-fuel-probes': 'images/logistics/pfuel.jpg',
        'digital-valve-seals': 'images/logistics/dgvol.webp',
        'hatch-integrity': 'images/logistics/hintegrit.png',
        'fuel-reconciliation': 'images/logistics/FuelRec.webp',
        'explosion-proof-infrastructure': 'images/logistics/explosionproof.webp',
        'security-response': 'images/logistics/Sresponse.webp',
    }

    description_text = strip_tags(service.description).strip()
    words = description_text.split()
    lede_text = " ".join(words[:22])
    summary_text = " ".join(words[:28])

    service.detail_section = section
    service.detail_lede = lede_text
    service.detail_summary = summary_text
    service.detail_body_html = _plain_text_to_rich_html(service.description)
    service.detail_date = ''
    service.detail_read_time = ''

    context = get_common_context({
        'detail_service': service,
        'detail_image_static': logistics_detail_image_map.get(detail_slug, ''),
    }, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/logistics-details/dynamic.html', context)


def _risk_detail_catalog():
    """Static enterprise-ready risk datasets for risk detail pages."""
    return {
        'active-voltage-conditioner': {
            'title': 'Active Voltage Conditioner',
            'section': 'Power Management',
            'source_url': 'https://www.eaton.com/us/en-us/catalog/power-conditioners/sag-ride-through-power-conditioner.html',
            'summary': 'Voltage conditioning controls and continuity safeguards for mission-critical power loads.',
            'kpis': {
                'total_risks': 14,
                'critical_risks': 3,
                'mitigated_risks': 8,
                'avg_score': 68,
            },
            'risks': [
                {'id': 'AVC-01', 'title': 'Deep Voltage Sag Event', 'domain': 'Electrical', 'severity': 'Critical', 'likelihood': 4, 'impact': 5, 'owner': 'Power Ops', 'status': 'Open', 'trend': 'Rising', 'score': 90},
                {'id': 'AVC-02', 'title': 'Transformer Harmonic Distortion', 'domain': 'Electrical', 'severity': 'High', 'likelihood': 3, 'impact': 4, 'owner': 'Maintenance', 'status': 'Monitoring', 'trend': 'Stable', 'score': 72},
                {'id': 'AVC-03', 'title': 'Controller Firmware Drift', 'domain': 'Technology', 'severity': 'Medium', 'likelihood': 3, 'impact': 3, 'owner': 'Automation Team', 'status': 'Mitigated', 'trend': 'Falling', 'score': 48},
                {'id': 'AVC-04', 'title': 'Cooling System Degradation', 'domain': 'Operations', 'severity': 'High', 'likelihood': 2, 'impact': 4, 'owner': 'Site Engineering', 'status': 'Open', 'trend': 'Rising', 'score': 66},
                {'id': 'AVC-05', 'title': 'Comms Link Failure (Modbus)', 'domain': 'Technology', 'severity': 'Medium', 'likelihood': 2, 'impact': 3, 'owner': 'Controls Team', 'status': 'Mitigated', 'trend': 'Falling', 'score': 36},
            ],
            'timeline': [
                {'date': '2026-01-12', 'event': 'Baseline risk assessment approved', 'type': 'Assessment'},
                {'date': '2026-02-03', 'event': 'Sag event simulation exceeded threshold', 'type': 'Incident'},
                {'date': '2026-03-18', 'event': 'Protection logic retuned and validated', 'type': 'Mitigation'},
                {'date': '2026-04-21', 'event': 'Quarterly executive review completed', 'type': 'Governance'},
            ],
        },
        'modular-power-distribution': {
            'title': 'Modular Power Distribution',
            'section': 'Power Management',
            'source_url': 'https://www.eaton.com/us/en-us/catalog/medium-voltage-power-distribution-control-systems/modular-integrated-transportable-substation.html',
            'summary': 'Mobile modular substations with deployment, commissioning, and reliability risk controls.',
            'kpis': {'total_risks': 12, 'critical_risks': 2, 'mitigated_risks': 7, 'avg_score': 61},
            'risks': [
                {'id': 'MPD-01', 'title': 'Substation Relocation Delay', 'domain': 'Logistics', 'severity': 'High', 'likelihood': 4, 'impact': 4, 'owner': 'Program Delivery', 'status': 'Open', 'trend': 'Rising', 'score': 82},
                {'id': 'MPD-02', 'title': 'Protection Relay Misconfiguration', 'domain': 'Technology', 'severity': 'Critical', 'likelihood': 3, 'impact': 5, 'owner': 'Commissioning', 'status': 'Monitoring', 'trend': 'Stable', 'score': 84},
                {'id': 'MPD-03', 'title': 'Skid Structural Fatigue', 'domain': 'Operations', 'severity': 'Medium', 'likelihood': 2, 'impact': 3, 'owner': 'Mechanical Team', 'status': 'Mitigated', 'trend': 'Falling', 'score': 34},
                {'id': 'MPD-04', 'title': 'Cable Termination Nonconformance', 'domain': 'Quality', 'severity': 'High', 'likelihood': 2, 'impact': 4, 'owner': 'QA/QC', 'status': 'Open', 'trend': 'Stable', 'score': 58},
            ],
            'timeline': [
                {'date': '2025-12-06', 'event': 'Factory acceptance criteria defined', 'type': 'Governance'},
                {'date': '2026-01-30', 'event': 'Transport route risk review completed', 'type': 'Assessment'},
                {'date': '2026-03-07', 'event': 'Relay test campaign started', 'type': 'Mitigation'},
                {'date': '2026-04-26', 'event': 'Site energization go/no-go checkpoint', 'type': 'Governance'},
            ],
        },
        'vibrating-wire-crackmeter': {
            'title': 'Vibrating Wire Crackmeter / Jointmeter',
            'section': 'Road Safety',
            'source_url': 'https://www.soilinstruments.com/products/joints-crackmeters/vibrating-wire-crackmeter/',
            'summary': 'Structural displacement monitoring for infrastructure cracks with threshold-driven alerts.',
            'kpis': {'total_risks': 10, 'critical_risks': 1, 'mitigated_risks': 6, 'avg_score': 52},
            'risks': [
                {'id': 'VWC-01', 'title': 'Sensor Drift Beyond Calibration Window', 'domain': 'Instrumentation', 'severity': 'High', 'likelihood': 3, 'impact': 4, 'owner': 'Monitoring Lead', 'status': 'Monitoring', 'trend': 'Stable', 'score': 70},
                {'id': 'VWC-02', 'title': 'Anchor Slippage on Concrete Joint', 'domain': 'Structural', 'severity': 'Critical', 'likelihood': 2, 'impact': 5, 'owner': 'Civil Team', 'status': 'Open', 'trend': 'Rising', 'score': 76},
                {'id': 'VWC-03', 'title': 'Telemetry Packet Loss', 'domain': 'Technology', 'severity': 'Medium', 'likelihood': 3, 'impact': 2, 'owner': 'Comms Team', 'status': 'Mitigated', 'trend': 'Falling', 'score': 30},
            ],
            'timeline': [
                {'date': '2026-01-09', 'event': 'Threshold library published', 'type': 'Governance'},
                {'date': '2026-02-15', 'event': 'Bridge segment alert triggered', 'type': 'Incident'},
                {'date': '2026-03-02', 'event': 'Anchor reinforcement completed', 'type': 'Mitigation'},
                {'date': '2026-04-12', 'event': 'Monitoring stability confirmed', 'type': 'Assessment'},
            ],
        },
        'wireless-tiltmeter': {
            'title': 'Wireless Tiltmeter (MEMS)',
            'section': 'Road Safety',
            'source_url': 'https://www.worldsensing.com/product/tiltmeter/',
            'summary': 'Wireless tilt intelligence for slope, rail, and infrastructure movement risk management.',
            'kpis': {'total_risks': 11, 'critical_risks': 2, 'mitigated_risks': 5, 'avg_score': 57},
            'risks': [
                {'id': 'WTM-01', 'title': 'Rapid Inclination Change Event', 'domain': 'Geotechnical', 'severity': 'Critical', 'likelihood': 3, 'impact': 5, 'owner': 'Geotech Analyst', 'status': 'Open', 'trend': 'Rising', 'score': 88},
                {'id': 'WTM-02', 'title': 'Battery Depletion in Remote Node', 'domain': 'Operations', 'severity': 'Medium', 'likelihood': 4, 'impact': 2, 'owner': 'Field Ops', 'status': 'Monitoring', 'trend': 'Stable', 'score': 44},
                {'id': 'WTM-03', 'title': 'Gateway Uplink Congestion', 'domain': 'Technology', 'severity': 'High', 'likelihood': 2, 'impact': 4, 'owner': 'Network Engineering', 'status': 'Mitigated', 'trend': 'Falling', 'score': 46},
            ],
            'timeline': [
                {'date': '2025-11-22', 'event': 'Regional baseline tilt profile established', 'type': 'Assessment'},
                {'date': '2026-01-17', 'event': 'Slope movement spike recorded', 'type': 'Incident'},
                {'date': '2026-02-21', 'event': 'Alert rules tuned for false-positive reduction', 'type': 'Mitigation'},
                {'date': '2026-04-29', 'event': 'Executive risk posture briefing delivered', 'type': 'Governance'},
            ],
        },
        'underground-communications': {
            'title': 'Underground Communications',
            'section': 'Mining Safety',
            'source_url': 'https://www.eaton.com/gb/en-gb/products/safety-security-emergency-communications/mining-communications--monitoring-and-automation-systems/wireless-mining-communications-systems.html',
            'summary': 'Underground wireless communication resilience and emergency continuity risk controls.',
            'kpis': {'total_risks': 13, 'critical_risks': 3, 'mitigated_risks': 6, 'avg_score': 65},
            'risks': [
                {'id': 'UGC-01', 'title': 'Shaft Repeater Cascade Failure', 'domain': 'Technology', 'severity': 'Critical', 'likelihood': 3, 'impact': 5, 'owner': 'Network Reliability', 'status': 'Open', 'trend': 'Rising', 'score': 87},
                {'id': 'UGC-02', 'title': 'Dead-Zone Expansion in New Drift', 'domain': 'Coverage', 'severity': 'High', 'likelihood': 4, 'impact': 4, 'owner': 'Mine Ops', 'status': 'Monitoring', 'trend': 'Rising', 'score': 81},
                {'id': 'UGC-03', 'title': 'Radio Interference from Equipment', 'domain': 'Operations', 'severity': 'Medium', 'likelihood': 2, 'impact': 3, 'owner': 'Maintenance', 'status': 'Mitigated', 'trend': 'Falling', 'score': 33},
            ],
            'timeline': [
                {'date': '2026-01-03', 'event': 'Coverage audit completed', 'type': 'Assessment'},
                {'date': '2026-02-11', 'event': 'Intermittent packet loss incident', 'type': 'Incident'},
                {'date': '2026-03-23', 'event': 'Redundant repeater ring deployed', 'type': 'Mitigation'},
                {'date': '2026-04-16', 'event': 'Emergency drill communication SLA met', 'type': 'Governance'},
            ],
        },
        'explosion-prevention': {
            'title': 'Explosion Prevention',
            'section': 'Mining Safety',
            'source_url': 'https://www.eaton.com/gb/en-gb/catalog/intrinsic-safety/mtl-9470-et-g-mtl-gigabit-intrinsically-safe-ethernet-range.html',
            'summary': 'Intrinsically safe networking risk controls for hazardous environments and explosion prevention.',
            'kpis': {'total_risks': 15, 'critical_risks': 4, 'mitigated_risks': 9, 'avg_score': 71},
            'risks': [
                {'id': 'EXP-01', 'title': 'Hazard Zone Segregation Breach', 'domain': 'Compliance', 'severity': 'Critical', 'likelihood': 3, 'impact': 5, 'owner': 'HSE Lead', 'status': 'Open', 'trend': 'Rising', 'score': 89},
                {'id': 'EXP-02', 'title': 'IS Barrier Degradation', 'domain': 'Electrical', 'severity': 'High', 'likelihood': 3, 'impact': 4, 'owner': 'Reliability', 'status': 'Monitoring', 'trend': 'Stable', 'score': 69},
                {'id': 'EXP-03', 'title': 'Certification Expiry Exposure', 'domain': 'Compliance', 'severity': 'High', 'likelihood': 2, 'impact': 4, 'owner': 'Regulatory Affairs', 'status': 'Mitigated', 'trend': 'Falling', 'score': 52},
                {'id': 'EXP-04', 'title': 'PoEx Link Overload', 'domain': 'Technology', 'severity': 'Medium', 'likelihood': 2, 'impact': 3, 'owner': 'OT Engineering', 'status': 'Mitigated', 'trend': 'Stable', 'score': 37},
            ],
            'timeline': [
                {'date': '2025-12-14', 'event': 'Hazard classification map approved', 'type': 'Governance'},
                {'date': '2026-02-08', 'event': 'Barrier fault alarm escalation', 'type': 'Incident'},
                {'date': '2026-03-12', 'event': 'Barrier replacement and retesting complete', 'type': 'Mitigation'},
                {'date': '2026-04-30', 'event': 'External compliance audit passed', 'type': 'Assessment'},
            ],
        },
    }


def _risk_detail_payload(detail_slug):
    catalog = _risk_detail_catalog()
    detail = catalog.get(detail_slug)
    if not detail:
        return None

    severity_order = {'Critical': 4, 'High': 3, 'Medium': 2, 'Low': 1}
    sorted_risks = sorted(
        detail['risks'],
        key=lambda risk: (risk['score'], severity_order.get(risk['severity'], 0)),
        reverse=True,
    )
    detail['risks'] = sorted_risks
    detail['updated_at'] = '2026-05-02T12:00:00Z'
    return detail


def risk_management_detail_data_view(request, detail_slug, region_code=None):
    service = Service.objects.filter(
        slug=detail_slug,
        is_published=True,
        service_type__in=['risk-management', 'risk management', 'risk_management'],
    ).first()

    if not service:
        detail = _risk_detail_catalog().get(detail_slug)
        if not detail:
            return JsonResponse({'error': 'Detail page not found'}, status=404)
        Service.objects.update_or_create(
            slug=detail_slug,
            defaults={
                'title': detail.get('title', detail_slug),
                'description': detail.get('summary', ''),
                'service_type': 'risk-management',
                'is_published': True,
                'primary_cta_url': f'/risk-management/details/{detail_slug}/',
            },
        )
        service = Service.objects.filter(slug=detail_slug, is_published=True).first()

    if not service:
        return JsonResponse({'error': 'Detail page not found'}, status=404)

    detail_body_html = getattr(service, 'detail_body_html', '') or ''
    detail_lede = getattr(service, 'detail_lede', '') or ''
    detail_section = getattr(service, 'detail_section', '') or ''
    detail_summary = getattr(service, 'detail_summary', '') or ''

    return JsonResponse({
        'slug': service.slug,
        'title': service.title,
        'section': detail_section,
        'lede': detail_lede,
        'summary': detail_summary,
        'description': service.description,
        'body_html': detail_body_html or _plain_text_to_rich_html(service.description),
        'updated_at': service.updated_at.isoformat() if getattr(service, 'updated_at', None) else None,
    })


def risk_management_detail_page_view(request, detail_slug, region_code=None):
    current_region = get_region_object(region_code)

    service = Service.objects.filter(
        slug=detail_slug,
        is_published=True,
        service_type__in=['risk-management', 'risk management', 'risk_management'],
    ).first()

    if not service:
        detail = _risk_detail_catalog().get(detail_slug)
        if not detail:
            raise Http404('Detail page not found')
        Service.objects.update_or_create(
            slug=detail_slug,
            defaults={
                'title': detail.get('title', detail_slug),
                'description': detail.get('summary', ''),
                'service_type': 'risk-management',
                'is_published': True,
                'primary_cta_url': f'/risk-management/details/{detail_slug}/',
            },
        )
        service = get_object_or_404(Service, slug=detail_slug, is_published=True)

    if current_region and service.regions.exists() and current_region not in service.regions.all():
        raise Http404("Service not available in this region")

    detail = _risk_detail_catalog().get(detail_slug, {})
    detail_body_html = getattr(service, 'detail_body_html', '') or ''
    detail_lede = getattr(service, 'detail_lede', '') or ''
    detail_section = getattr(service, 'detail_section', '') or ''
    detail_summary = getattr(service, 'detail_summary', '') or ''
    detail_date = getattr(service, 'detail_date', '') or ''
    detail_read_time = getattr(service, 'detail_read_time', '') or ''

    service.detail_section = detail_section or detail.get('section', 'Risk Management')
    service.detail_lede = detail_lede or service.description
    service.detail_summary = detail_summary or service.description
    service.detail_body_html = detail_body_html or _plain_text_to_rich_html(service.description)
    service.detail_date = detail_date
    service.detail_read_time = detail_read_time

    context = get_common_context({'detail_service': service}, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/risk-details/dynamic.html', context)

def risk_management_view(request, region_code=None):
    current_region = get_region_object(region_code)
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""

    services_qs = Service.objects.filter(is_published=True).order_by('order').prefetch_related('regions')
    services = filter_by_region(services_qs, current_region)
    risk_services = services.filter(service_type__in=['risk-management', 'risk management', 'risk_management'])

    risk_catalog = _risk_detail_catalog()
    risk_section_icon_map = {
        'Power Management': 'zap',
        'Road Safety': 'traffic-cone',
        'Mining Safety': 'mountain',
    }

    sections_by_title = {}
    if risk_services.exists():
        for service in risk_services:
            detail = risk_catalog.get(service.slug)
            section_title = (detail or {}).get('section') or 'Risk Management'
            section_icon = risk_section_icon_map.get(section_title, 'shield-check')
            card = {
                'title': service.title,
                'description': service.description,
                'url': service.primary_cta_url or service.get_absolute_url(),
            }
            if section_title not in sections_by_title:
                sections_by_title[section_title] = {
                    'title': section_title,
                    'icon': section_icon,
                    'cards': [],
                }
            sections_by_title[section_title]['cards'].append(card)
    else:
        for slug, detail in risk_catalog.items():
            section_title = detail.get('section') or 'Risk Management'
            section_icon = risk_section_icon_map.get(section_title, 'shield-check')
            card = {
                'title': detail.get('title', slug),
                'description': detail.get('summary', ''),
                'url': f'/risk-management/details/{slug}/',
            }
            if section_title not in sections_by_title:
                sections_by_title[section_title] = {
                    'title': section_title,
                    'icon': section_icon,
                    'cards': [],
                }
            sections_by_title[section_title]['cards'].append(card)

    risk_section_order = ['Power Management', 'Road Safety', 'Mining Safety', 'Risk Management']
    risk_sections = sorted(
        sections_by_title.values(),
        key=lambda section: risk_section_order.index(section['title']) if section['title'] in risk_section_order else len(risk_section_order),
    )

    context = get_common_context({
        'meta_title': f'Risk Management Services{region_suffix} | Xinfinity Group',
        'meta_description': f'Risk management services{region_suffix} supporting safer operations through practical controls, monitoring, compliance support, and incident response planning.',
        'meta_keywords': 'risk management services, compliance support, incident response planning, operational risk',
        'risk_sections': risk_sections,
    }, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/risk-management.html', context)

def oil_refinery_view(request, region_code=None):
    current_region = get_region_object(region_code)
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    context = get_common_context({
        'meta_title': f'Oil & Gas Security & Facility Services{region_suffix} | Xinfinity Group',
        'meta_description': f'Security, cleaning, and facility support services{region_suffix} for oil and gas environments with an emphasis on safety, compliance, and operational continuity.',
        'meta_keywords': 'oil and gas security, oil and gas cleaning, industrial facilities services, site compliance',
    }, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/oil-refinery.html', context)

def environment_view(request, region_code=None):
    current_region = get_region_object(region_code)
    region_suffix = f" in {current_region.name}" if current_region and current_region.name else ""
    context = get_common_context({
        'meta_title': f'Environmental Services & Site Support{region_suffix} | Xinfinity Group',
        'meta_description': f'Environmental and site support services{region_suffix} delivered with practical risk controls, compliance standards, and operational reliability.',
        'meta_keywords': 'environmental support services, site compliance services, facilities support',
    }, current_region)
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/environment.html', context)

def code_of_conduct_view(request, region_code=None):
    context = get_common_context({
        'meta_title': 'Code of Conduct - XinfinityGroup',
        'meta_description': 'Read the XinfinityGroup Code of Conduct covering ethics, professionalism, safety, inclusion, confidentiality, and responsible business practices.',
        'meta_keywords': 'code of conduct, business ethics, compliance, xinfinitygroup standards',
    }, get_region_object(region_code))
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/code-of-conduct.html', context)

def modern_slavery_statement_view(request, region_code=None):
    context = get_common_context({
        'meta_title': 'Modern Slavery Statement - XinfinityGroup',
        'meta_description': 'View the XinfinityGroup Modern Slavery Statement outlining due diligence, fair employment standards, and anti-slavery safeguards.',
        'meta_keywords': 'modern slavery statement, anti slavery policy, ethical supply chain, xinfinitygroup',
    }, get_region_object(region_code))
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/modern-slavery-statement.html', context)

def inclusion_diversity_view(request, region_code=None):
    context = get_common_context({
        'meta_title': 'Inclusion & Diversity - XinfinityGroup',
        'meta_description': 'Explore XinfinityGroup inclusion and diversity commitments, equal opportunities, and actions that support an inclusive workplace culture.',
        'meta_keywords': 'inclusion and diversity, equal opportunities, workplace culture, xinfinitygroup',
    }, get_region_object(region_code))
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/inclusion-diversity.html', context)

def infinitygroup_charity_view(request, region_code=None):
    context = get_common_context({
        'meta_title': 'XinfinityGroup Charity - Community Impact',
        'meta_description': 'Discover XinfinityGroup charity initiatives focused on education, healthcare, environment, and community development.',
        'meta_keywords': 'xinfinitygroup charity, community impact, education programs, healthcare support',
    }, get_region_object(region_code))
    context = add_hreflang_tags(context, request)
    return render(request, 'pages/infinitygroup-charity.html', context)


def _track_contact_form_submission(request, name: str, email: str, subject: str) -> None:
    """
    Track contact form submission in Google Analytics 4.
    
    Extracts traffic source information from request and sends conversion event to GA4.
    
    Args:
        request: HTTP request object
        name: Contact form submitter name
        email: Contact form submitter email
        subject: Contact form subject
    """
    try:
        tracker = get_ga4_tracker()
        if not tracker:
            return
        
        # Extract GA4 client ID from cookies
        client_id = request.COOKIES.get('_ga', '')
        if not client_id:
            # Generate a fallback client ID if not available
            import uuid
            client_id = str(uuid.uuid4())
        
        # Extract traffic source information from request
        source = request.GET.get('utm_source', 'direct')
        medium = request.GET.get('utm_medium', 'direct')
        campaign = request.GET.get('utm_campaign', '')
        
        # Track the conversion event
        tracker.track_contact_form_submission(
            client_id=client_id,
            name=name,
            email=email,
            subject=subject,
            source=source,
            medium=medium,
            campaign=campaign,
        )
        
    except Exception as e:
        # Log error but don't fail the view if GA4 tracking fails
        import logging
        logger = logging.getLogger(__name__)
        logger.error(f"Failed to track contact form submission in GA4: {str(e)}")


# ============================================================================
# Location-Specific Views for UK, Canada, and UAE
# ============================================================================

def uk_main_view(request):
    """UK main location page view"""
    import json
    
    # Get UK region
    try:
        uk_region = Region.objects.get(code='uk', is_active=True)
    except Region.DoesNotExist:
        uk_region = None
    
    # Get region-specific content
    services_qs = Service.objects.filter(is_published=True)
    testimonials_qs = Testimonial.objects.filter(is_published=True)
    
    services = filter_by_region(services_qs, uk_region)[:6]
    testimonials = filter_by_region(testimonials_qs, uk_region)[:6]
    
    # SEO Meta Tags for UK
    meta_title = "Facilities Management Services UK | XinfinityGroup"
    meta_description = "Professional facilities management, security, and cleaning services across the UK. London, Manchester, Birmingham and more. ISO certified, 24/7 support."
    meta_keywords = "facilities management UK, security services UK, cleaning services UK, facility management company, professional services"
    
    # LocalBusiness Schema for UK
    # Note: Do NOT add aggregateRating unless backed by real, verifiable reviews
    # Fake ratings (ratingValue, reviewCount) can trigger Google manual actions
    # Note: Do NOT add aggregateRating unless backed by real, verifiable reviews
    # Fake ratings (ratingValue, reviewCount) can trigger Google manual actions
    localbusiness_schema = {
        "@context": "https://schema.org",
        "@type": "LocalBusiness",
        "name": "XinfinityGroup UK",
        "image": request.build_absolute_uri('/static/logo.png'),
        "description": "Professional facilities management services across the United Kingdom",
        "address": {
            "@type": "PostalAddress",
            "addressCountry": "GB"
        },
        "areaServed": ["GB"],
        "url": request.build_absolute_uri('/'),
        "priceRange": "£"
    }
    
    context = {
        'services': services,
        'testimonials': testimonials,
        'meta_title': meta_title,
        'meta_description': meta_description,
        'meta_keywords': meta_keywords,
        'localbusiness_schema': json.dumps(localbusiness_schema),
        'current_region': uk_region,
    }
    context = add_hreflang_tags(context, request)
    
    return render(request, 'pages/uk.html', context)


def uk_city_view(request, city_slug):
    """UK city-specific location page view"""
    import json
    
    # City mapping
    uk_cities = {
        'london': {
            'name': 'London',
            'title': 'Facilities Management Services in London | XinfinityGroup',
            'description': 'Professional facilities management, security, and cleaning services in London. Serving central London, Greater London, and surrounding areas.',
            'keywords': 'facilities management London, security services London, cleaning services London, facility management company London',
        },
        'manchester': {
            'name': 'Manchester',
            'title': 'Facilities Management Services in Manchester | XinfinityGroup',
            'description': 'Professional facilities management, security, and cleaning services in Manchester. Serving Manchester city centre and Greater Manchester.',
            'keywords': 'facilities management Manchester, security services Manchester, cleaning services Manchester, facility management company Manchester',
        },
        'birmingham': {
            'name': 'Birmingham',
            'title': 'Facilities Management Services in Birmingham | XinfinityGroup',
            'description': 'Professional facilities management, security, and cleaning services in Birmingham. Serving Birmingham city centre and surrounding areas.',
            'keywords': 'facilities management Birmingham, security services Birmingham, cleaning services Birmingham, facility management company Birmingham',
        },
    }
    
    if city_slug not in uk_cities:
        raise Http404("City not found")
    
    city_info = uk_cities[city_slug]
    
    # Get UK region
    try:
        uk_region = Region.objects.get(code='uk', is_active=True)
    except Region.DoesNotExist:
        uk_region = None
    
    # Get region-specific content
    services_qs = Service.objects.filter(is_published=True)
    testimonials_qs = Testimonial.objects.filter(is_published=True)
    
    services = filter_by_region(services_qs, uk_region)[:6]
    testimonials = filter_by_region(testimonials_qs, uk_region)[:6]
    
    # LocalBusiness Schema for UK City
    # Note: Do NOT add aggregateRating unless backed by real, verifiable reviews
    # Fake ratings (ratingValue, reviewCount) can trigger Google manual actions
    # Note: Do NOT add aggregateRating unless backed by real, verifiable reviews
    # Fake ratings (ratingValue, reviewCount) can trigger Google manual actions
    localbusiness_schema = {
        "@context": "https://schema.org",
        "@type": "LocalBusiness",
        "name": f"XinfinityGroup {city_info['name']}",
        "image": request.build_absolute_uri('/static/logo.png'),
        "description": f"Professional facilities management services in {city_info['name']}",
        "address": {
            "@type": "PostalAddress",
            "addressLocality": city_info['name'],
            "addressRegion": "England",
            "addressCountry": "GB"
        },
        "areaServed": [city_info['name'], "Greater " + city_info['name']],
        "url": request.build_absolute_uri(f'/city/{city_slug}/'),
        "priceRange": "£"
    }
    
    context = {
        'city_name': city_info['name'],
        'city_slug': city_slug,
        'services': services,
        'testimonials': testimonials,
        'meta_title': city_info['title'],
        'meta_description': city_info['description'],
        'meta_keywords': city_info['keywords'],
        'localbusiness_schema': json.dumps(localbusiness_schema),
        'current_region': uk_region,
    }
    context = add_hreflang_tags(context, request)
    
    return render(request, 'pages/uk_city.html', context)


def canada_main_view(request):
    """Canada main location page view"""
    import json
    
    # Get Canada region
    try:
        ca_region = Region.objects.get(code='ca', is_active=True)
    except Region.DoesNotExist:
        ca_region = None
    
    # Get region-specific content
    services_qs = Service.objects.filter(is_published=True).order_by('order').prefetch_related('regions')
    testimonials_qs = Testimonial.objects.filter(is_published=True).prefetch_related('regions')
    team_qs = TeamMember.objects.all().prefetch_related('regions')
    
    services = filter_by_region(services_qs, ca_region)
    if not services.exists():
        services = Service.objects.filter(is_published=True).order_by('order')
    testimonials = filter_by_region(testimonials_qs, ca_region)[:6]
    team_members = filter_by_region(team_qs, ca_region)[:6]
    
    security_services = services.filter(service_type='security')[:6]
    cleaning_services = services.filter(service_type='cleaning')[:9]
    sector_services = services.filter(service_type='sector')[:7]
    logistics_slider_cards = services.filter(service_type__in=['logistics', 'logistic'])[:6]
    risk_management_slider_cards = services.filter(service_type__in=['risk-management', 'risk management', 'risk_management'])[:6]
    staffing_solutions = services.filter(service_type='staffing')[:6]
    
    # SEO Meta Tags for Canada
    meta_title = "Facilities Management Services Canada | XinfinityGroup"
    meta_description = "Professional facilities management, security, and cleaning services across Canada. Toronto, Vancouver, and more. ISO certified, 24/7 support."
    meta_keywords = "facilities management Canada, security services Canada, cleaning services Canada, facility management company, professional services"
    
    # LocalBusiness Schema for Canada
    # Note: Do NOT add aggregateRating unless backed by real, verifiable reviews
    # Fake ratings (ratingValue, reviewCount) can trigger Google manual actions
    localbusiness_schema = {
        "@context": "https://schema.org",
        "@type": "LocalBusiness",
        "name": "XinfinityGroup Canada",
        "image": request.build_absolute_uri('/static/logo.png'),
        "description": "Professional facilities management services across Canada",
        "address": {
            "@type": "PostalAddress",
            "addressCountry": "CA"
        },
        "areaServed": ["CA"],
        "url": request.build_absolute_uri('/ca/'),
        "priceRange": "$"
    }
    
    try:
        about = About.objects.first()
    except About.DoesNotExist:
        about = None
    
    current_region = ca_region
    hero_section = get_region_single_content(
        HeroSection.objects.filter(is_active=True), current_region
    )
    certification_section = get_region_single_content(
        CertificationSection.objects.filter(is_active=True), current_region
    )
    certifications = filter_by_region(
        Certification.objects.filter(is_published=True).order_by('order'),
        current_region
    )
    why_choose_section = get_region_single_content(
        WhyChooseSection.objects.filter(is_active=True), current_region
    )
    feature_cards = FeatureCard.objects.select_related('section').filter(
        section=why_choose_section
    ).order_by('order') if why_choose_section else []
    key_differentiators = filter_by_region(
        KeyDifferentiator.objects.filter(is_published=True).order_by('order'),
        current_region
    )
    testimonial_section = get_region_single_content(
        TestimonialSection.objects.filter(is_active=True), current_region
    )
    
    context = {
        'services': services,
        'security_services': security_services,
        'cleaning_services': cleaning_services,
        'sector_services': sector_services,
        'logistics_slider_cards': logistics_slider_cards,
        'risk_management_slider_cards': risk_management_slider_cards,
        'staffing_solutions': staffing_solutions,
        'about': about,
        'team_members': team_members,
        'testimonials': testimonials,
        'meta_title': meta_title,
        'meta_description': meta_description,
        'meta_keywords': meta_keywords,
        'localbusiness_schema': json.dumps(localbusiness_schema),
        'current_region': ca_region,
        # Dynamic homepage content
        'hero_section': hero_section,
        'certification_section': certification_section,
        'certifications': certifications,
        'why_choose_section': why_choose_section,
        'feature_cards': feature_cards,
        'key_differentiators': key_differentiators,
        'testimonial_section': testimonial_section,
    }
    context = get_common_context(context, ca_region)
    context = add_hreflang_tags(context, request)
    
    return render(request, 'pages/canada.html', context)


def canada_city_view(request, city_slug):
    """Canada city-specific location page view"""
    import json
    
    # City mapping
    canada_cities = {
        'toronto': {
            'name': 'Toronto',
            'province': 'Ontario',
            'title': 'Facilities Management Services in Toronto | XinfinityGroup',
            'description': 'Professional facilities management, security, and cleaning services in Toronto. Serving Greater Toronto Area and surrounding regions.',
            'keywords': 'facilities management Toronto, security services Toronto, cleaning services Toronto, facility management company Toronto',
        },
        'vancouver': {
            'name': 'Vancouver',
            'province': 'British Columbia',
            'title': 'Facilities Management Services in Vancouver | XinfinityGroup',
            'description': 'Professional facilities management, security, and cleaning services in Vancouver. Serving Metro Vancouver and surrounding areas.',
            'keywords': 'facilities management Vancouver, security services Vancouver, cleaning services Vancouver, facility management company Vancouver',
        },
    }
    
    if city_slug not in canada_cities:
        raise Http404("City not found")
    
    city_info = canada_cities[city_slug]
    
    # Get Canada region
    try:
        ca_region = Region.objects.get(code='ca', is_active=True)
    except Region.DoesNotExist:
        ca_region = None
    
    # Get region-specific content
    services_qs = Service.objects.filter(is_published=True)
    testimonials_qs = Testimonial.objects.filter(is_published=True)
    
    services = filter_by_region(services_qs, ca_region)[:6]
    testimonials = filter_by_region(testimonials_qs, ca_region)[:6]
    
    # LocalBusiness Schema for Canada City
    # Note: Do NOT add aggregateRating unless backed by real, verifiable reviews
    # Fake ratings (ratingValue, reviewCount) can trigger Google manual actions
    localbusiness_schema = {
        "@context": "https://schema.org",
        "@type": "LocalBusiness",
        "name": f"XinfinityGroup {city_info['name']}",
        "image": request.build_absolute_uri('/static/logo.png'),
        "description": f"Professional facilities management services in {city_info['name']}",
        "address": {
            "@type": "PostalAddress",
            "addressLocality": city_info['name'],
            "addressRegion": city_info['province'],
            "addressCountry": "CA"
        },
        "areaServed": [city_info['name'], f"Greater {city_info['name']}"],
        "url": request.build_absolute_uri(f'/ca/{city_slug}/'),
        "priceRange": "$"
    }
    
    context = {
        'city_name': city_info['name'],
        'city_slug': city_slug,
        'services': services,
        'testimonials': testimonials,
        'meta_title': city_info['title'],
        'meta_description': city_info['description'],
        'meta_keywords': city_info['keywords'],
        'localbusiness_schema': json.dumps(localbusiness_schema),
        'current_region': ca_region,
    }
    context = add_hreflang_tags(context, request)
    
    return render(request, 'pages/canada_city.html', context)


def uae_main_view(request):
    """UAE main location page view"""
    import json
    
    # Get UAE region
    try:
        uae_region = Region.objects.get(code='uae', is_active=True)
    except Region.DoesNotExist:
        uae_region = None
    
    # Get region-specific content
    services_qs = Service.objects.filter(is_published=True).order_by('order').prefetch_related('regions')
    testimonials_qs = Testimonial.objects.filter(is_published=True).prefetch_related('regions')
    team_qs = TeamMember.objects.all().prefetch_related('regions')
    
    services = filter_by_region(services_qs, uae_region)
    if not services.exists():
        services = Service.objects.filter(is_published=True).order_by('order')
    testimonials = filter_by_region(testimonials_qs, uae_region)[:6]
    team_members = filter_by_region(team_qs, uae_region)[:6]
    
    security_services = services.filter(service_type='security')[:6]
    cleaning_services = services.filter(service_type='cleaning')[:9]
    sector_services = services.filter(service_type='sector')[:7]
    logistics_slider_cards = services.filter(service_type__in=['logistics', 'logistic'])[:6]
    risk_management_slider_cards = services.filter(service_type__in=['risk-management', 'risk management', 'risk_management'])[:6]
    staffing_solutions = services.filter(service_type='staffing')[:6]
    
    # SEO Meta Tags for UAE
    meta_title = "Facilities Management Services UAE | XinfinityGroup"
    meta_description = "Professional facilities management, security, and cleaning services across UAE. Dubai, Abu Dhabi, and more. ISO certified, 24/7 support."
    meta_keywords = "facilities management UAE, security services UAE, cleaning services UAE, facility management company, professional services"
    
    # LocalBusiness Schema for UAE
    # Note: Do NOT add aggregateRating unless backed by real, verifiable reviews
    # Fake ratings (ratingValue, reviewCount) can trigger Google manual actions
    localbusiness_schema = {
        "@context": "https://schema.org",
        "@type": "LocalBusiness",
        "name": "XinfinityGroup UAE",
        "image": request.build_absolute_uri('/static/logo.png'),
        "description": "Professional facilities management services across UAE",
        "address": {
            "@type": "PostalAddress",
            "addressCountry": "AE"
        },
        "areaServed": ["AE"],
        "url": request.build_absolute_uri('/uae/'),
        "priceRange": "د.إ"
    }
    
    try:
        about = About.objects.first()
    except About.DoesNotExist:
        about = None
    
    current_region = uae_region
    hero_section = get_region_single_content(
        HeroSection.objects.filter(is_active=True), current_region
    )
    certification_section = get_region_single_content(
        CertificationSection.objects.filter(is_active=True), current_region
    )
    certifications = filter_by_region(
        Certification.objects.filter(is_published=True).order_by('order'),
        current_region
    )
    why_choose_section = get_region_single_content(
        WhyChooseSection.objects.filter(is_active=True), current_region
    )
    feature_cards = FeatureCard.objects.select_related('section').filter(
        section=why_choose_section
    ).order_by('order') if why_choose_section else []
    key_differentiators = filter_by_region(
        KeyDifferentiator.objects.filter(is_published=True).order_by('order'),
        current_region
    )
    testimonial_section = get_region_single_content(
        TestimonialSection.objects.filter(is_active=True), current_region
    )
    
    context = {
        'services': services,
        'security_services': security_services,
        'cleaning_services': cleaning_services,
        'sector_services': sector_services,
        'logistics_slider_cards': logistics_slider_cards,
        'risk_management_slider_cards': risk_management_slider_cards,
        'staffing_solutions': staffing_solutions,
        'about': about,
        'team_members': team_members,
        'testimonials': testimonials,
        'meta_title': meta_title,
        'meta_description': meta_description,
        'meta_keywords': meta_keywords,
        'localbusiness_schema': json.dumps(localbusiness_schema),
        'current_region': uae_region,
        # Dynamic homepage content
        'hero_section': hero_section,
        'certification_section': certification_section,
        'certifications': certifications,
        'why_choose_section': why_choose_section,
        'feature_cards': feature_cards,
        'key_differentiators': key_differentiators,
        'testimonial_section': testimonial_section,
    }
    context = get_common_context(context, uae_region)
    context = add_hreflang_tags(context, request)
    
    return render(request, 'pages/uae.html', context)


def uae_city_view(request, city_slug):
    """UAE city-specific location page view"""
    import json
    
    # City mapping
    uae_cities = {
        'dubai': {
            'name': 'Dubai',
            'emirate': 'Dubai',
            'title': 'Facilities Management Services in Dubai | XinfinityGroup',
            'description': 'Professional facilities management, security, and cleaning services in Dubai. Serving Dubai Marina, Downtown Dubai, and all areas.',
            'keywords': 'facilities management Dubai, security services Dubai, cleaning services Dubai, facility management company Dubai',
        },
        'abu-dhabi': {
            'name': 'Abu Dhabi',
            'emirate': 'Abu Dhabi',
            'title': 'Facilities Management Services in Abu Dhabi | XinfinityGroup',
            'description': 'Professional facilities management, security, and cleaning services in Abu Dhabi. Serving all areas of Abu Dhabi.',
            'keywords': 'facilities management Abu Dhabi, security services Abu Dhabi, cleaning services Abu Dhabi, facility management company Abu Dhabi',
        },
    }
    
    if city_slug not in uae_cities:
        raise Http404("City not found")
    
    city_info = uae_cities[city_slug]
    
    # Get UAE region
    try:
        uae_region = Region.objects.get(code='uae', is_active=True)
    except Region.DoesNotExist:
        uae_region = None
    
    # Get region-specific content
    services_qs = Service.objects.filter(is_published=True)
    testimonials_qs = Testimonial.objects.filter(is_published=True)
    
    services = filter_by_region(services_qs, uae_region)[:6]
    testimonials = filter_by_region(testimonials_qs, uae_region)[:6]
    
    # LocalBusiness Schema for UAE City
    # Note: Do NOT add aggregateRating unless backed by real, verifiable reviews
    # Fake ratings (ratingValue, reviewCount) can trigger Google manual actions
    localbusiness_schema = {
        "@context": "https://schema.org",
        "@type": "LocalBusiness",
        "name": f"XinfinityGroup {city_info['name']}",
        "image": request.build_absolute_uri('/static/logo.png'),
        "description": f"Professional facilities management services in {city_info['name']}",
        "address": {
            "@type": "PostalAddress",
            "addressLocality": city_info['name'],
            "addressRegion": city_info['emirate'],
            "addressCountry": "AE"
        },
        "areaServed": [city_info['name']],
        "url": request.build_absolute_uri(f'/uae/{city_slug}/'),
        "priceRange": "د.إ"
    }
    
    context = {
        'city_name': city_info['name'],
        'city_slug': city_slug,
        'services': services,
        'testimonials': testimonials,
        'meta_title': city_info['title'],
        'meta_description': city_info['description'],
        'meta_keywords': city_info['keywords'],
        'localbusiness_schema': json.dumps(localbusiness_schema),
        'current_region': uae_region,
    }
    context = add_hreflang_tags(context, request)
    
    return render(request, 'pages/uae_city.html', context)


# ============================================================================
# IRELAND LOCATION VIEWS
# ============================================================================

def ireland_main_view(request):
    """Ireland main location page view"""
    import json
    
    # Get Ireland region
    try:
        ireland_region = Region.objects.get(code='ireland', is_active=True)
    except Region.DoesNotExist:
        ireland_region = None
    
    # Get region-specific content
    services_qs = Service.objects.filter(is_published=True).order_by('order').prefetch_related('regions')
    testimonials_qs = Testimonial.objects.filter(is_published=True).prefetch_related('regions')
    team_qs = TeamMember.objects.all().prefetch_related('regions')
    
    services = filter_by_region(services_qs, ireland_region)
    if not services.exists():
        services = Service.objects.filter(is_published=True).order_by('order')
    testimonials = filter_by_region(testimonials_qs, ireland_region)[:6]
    team_members = filter_by_region(team_qs, ireland_region)[:6]
    
    security_services = services.filter(service_type='security')[:6]
    cleaning_services = services.filter(service_type='cleaning')[:9]
    sector_services = services.filter(service_type='sector')[:7]
    logistics_slider_cards = services.filter(service_type__in=['logistics', 'logistic'])[:6]
    risk_management_slider_cards = services.filter(service_type__in=['risk-management', 'risk management', 'risk_management'])[:6]
    staffing_solutions = services.filter(service_type='staffing')[:6]
    
    # SEO Meta Tags for Ireland
    meta_title = "Facilities Management Services Ireland | XinfinityGroup"
    meta_description = "Professional facilities management, security, and cleaning services across Ireland. Dublin, Cork, Galway, and more. ISO certified, 24/7 support."
    meta_keywords = "facilities management Ireland, security services Ireland, cleaning services Ireland, facility management company, professional services"
    
    # LocalBusiness Schema for Ireland
    # Note: Do NOT add aggregateRating unless backed by real, verifiable reviews
    # Fake ratings (ratingValue, reviewCount) can trigger Google manual actions
    localbusiness_schema = {
        "@context": "https://schema.org",
        "@type": "LocalBusiness",
        "name": "XinfinityGroup Ireland",
        "image": request.build_absolute_uri('/static/logo.png'),
        "description": "Professional facilities management services across Ireland",
        "address": {
            "@type": "PostalAddress",
            "addressCountry": "IE"
        },
        "areaServed": ["IE"],
        "url": request.build_absolute_uri('/ireland/'),
        "priceRange": "€"
    }
    
    try:
        about = About.objects.first()
    except About.DoesNotExist:
        about = None
    
    current_region = ireland_region
    hero_section = get_region_single_content(
        HeroSection.objects.filter(is_active=True), current_region
    )
    certification_section = get_region_single_content(
        CertificationSection.objects.filter(is_active=True), current_region
    )
    certifications = filter_by_region(
        Certification.objects.filter(is_published=True).order_by('order'),
        current_region
    )
    why_choose_section = get_region_single_content(
        WhyChooseSection.objects.filter(is_active=True), current_region
    )
    feature_cards = FeatureCard.objects.select_related('section').filter(
        section=why_choose_section
    ).order_by('order') if why_choose_section else []
    key_differentiators = filter_by_region(
        KeyDifferentiator.objects.filter(is_published=True).order_by('order'),
        current_region
    )
    testimonial_section = get_region_single_content(
        TestimonialSection.objects.filter(is_active=True), current_region
    )
    
    context = {
        'services': services,
        'security_services': security_services,
        'cleaning_services': cleaning_services,
        'sector_services': sector_services,
        'logistics_slider_cards': logistics_slider_cards,
        'risk_management_slider_cards': risk_management_slider_cards,
        'staffing_solutions': staffing_solutions,
        'about': about,
        'team_members': team_members,
        'testimonials': testimonials,
        'meta_title': meta_title,
        'meta_description': meta_description,
        'meta_keywords': meta_keywords,
        'localbusiness_schema': json.dumps(localbusiness_schema),
        'current_region': ireland_region,
        # Dynamic homepage content
        'hero_section': hero_section,
        'certification_section': certification_section,
        'certifications': certifications,
        'why_choose_section': why_choose_section,
        'feature_cards': feature_cards,
        'key_differentiators': key_differentiators,
        'testimonial_section': testimonial_section,
    }
    context = get_common_context(context, ireland_region)
    context = add_hreflang_tags(context, request)
    
    return render(request, 'pages/ireland.html', context)


def ireland_city_view(request, city_slug):
    """Ireland city-specific location page view"""
    import json
    
    # City mapping
    ireland_cities = {
        'dublin': {
            'name': 'Dublin',
            'county': 'Dublin',
            'title': 'Facilities Management Services in Dublin | XinfinityGroup',
            'description': 'Professional facilities management, security, and cleaning services in Dublin. Serving Dublin City, Dun Laoghaire, and surrounding areas.',
            'keywords': 'facilities management Dublin, security services Dublin, cleaning services Dublin, facility management company Dublin',
        },
        'cork': {
            'name': 'Cork',
            'county': 'Cork',
            'title': 'Facilities Management Services in Cork | XinfinityGroup',
            'description': 'Professional facilities management, security, and cleaning services in Cork. Serving Cork City and surrounding areas.',
            'keywords': 'facilities management Cork, security services Cork, cleaning services Cork, facility management company Cork',
        },
        'galway': {
            'name': 'Galway',
            'county': 'Galway',
            'title': 'Facilities Management Services in Galway | XinfinityGroup',
            'description': 'Professional facilities management, security, and cleaning services in Galway. Serving Galway City and surrounding areas.',
            'keywords': 'facilities management Galway, security services Galway, cleaning services Galway, facility management company Galway',
        },
        'limerick': {
            'name': 'Limerick',
            'county': 'Limerick',
            'title': 'Facilities Management Services in Limerick | XinfinityGroup',
            'description': 'Professional facilities management, security, and cleaning services in Limerick. Serving Limerick City and surrounding areas.',
            'keywords': 'facilities management Limerick, security services Limerick, cleaning services Limerick, facility management company Limerick',
        },
    }
    
    if city_slug not in ireland_cities:
        raise Http404("City not found")
    
    city_info = ireland_cities[city_slug]
    
    # Get Ireland region
    try:
        ireland_region = Region.objects.get(code='ireland', is_active=True)
    except Region.DoesNotExist:
        ireland_region = None
    
    # Get region-specific content
    services_qs = Service.objects.filter(is_published=True)
    testimonials_qs = Testimonial.objects.filter(is_published=True)
    
    services = filter_by_region(services_qs, ireland_region)[:6]
    testimonials = filter_by_region(testimonials_qs, ireland_region)[:6]
    
    # LocalBusiness Schema for Ireland City
    # Note: Do NOT add aggregateRating unless backed by real, verifiable reviews
    # Fake ratings (ratingValue, reviewCount) can trigger Google manual actions
    localbusiness_schema = {
        "@context": "https://schema.org",
        "@type": "LocalBusiness",
        "name": f"XinfinityGroup {city_info['name']}",
        "image": request.build_absolute_uri('/static/logo.png'),
        "description": f"Professional facilities management services in {city_info['name']}",
        "address": {
            "@type": "PostalAddress",
            "addressLocality": city_info['name'],
            "addressRegion": city_info['county'],
            "addressCountry": "IE"
        },
        "areaServed": [city_info['name']],
        "url": request.build_absolute_uri(f'/ireland/{city_slug}/'),
        "priceRange": "€"
    }
    
    context = {
        'city_name': city_info['name'],
        'city_slug': city_slug,
        'services': services,
        'testimonials': testimonials,
        'meta_title': city_info['title'],
        'meta_description': city_info['description'],
        'meta_keywords': city_info['keywords'],
        'localbusiness_schema': json.dumps(localbusiness_schema),
        'current_region': ireland_region,
    }
    context = add_hreflang_tags(context, request)
    
    return render(request, 'pages/ireland_city.html', context)
