from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.http import JsonResponse
from django.core.exceptions import PermissionDenied

from .models import Branch, PromoCode, AIChatLog, AIPrompt
from .forms import BranchForm
from .utils import is_feature_enabled, filter_orders_by_user_branch
from accounts.decorators import role_required
from companies.permissions import company_feature_required

# core/views.py (Dashboard with real data)
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.utils import timezone
from django.db.models import Sum, Count, Q
from datetime import datetime, timedelta
from inventory.models import Product
from accounts.models import CustomUser
from sales.models import POSOrder, POSOrderItem, DailySalesSummary

def home(request):
    if not request.user.is_authenticated:
        return redirect('register')
    if request.user.is_superuser:
        return redirect('superadmin_company_list')
    company = getattr(request.user, 'company', None)
    if company:
        if request.user.role == 'cashier':
            company_settings = getattr(company, 'settings', None)
            pos_mode = getattr(company_settings, 'pos_interface_mode', 'classic') if company_settings else 'classic'
            if pos_mode == 'grid':
                return redirect(f'/{company.slug}/sales/pos/grid/')
            return redirect(f'/{company.slug}/sales/pos/')
        return redirect(f'/{company.slug}/dashboard/')
    return redirect('company_inactive')

@login_required
@role_required(['admin', 'manager'])
def dashboard(request):
    """Main dashboard — scoped to request.company."""
    from django.db.models import Avg
    today = timezone.now().date()
    company = getattr(request, 'company', None)

    base_orders = POSOrder.objects.filter(company=company) if company else POSOrder.objects.none()

    # Get today's summary
    today_summary = DailySalesSummary.objects.filter(company=company, date=today).first()

    # If no summary exists, calculate fresh
    if not today_summary:
        today_orders = base_orders.filter(created_at__date=today)
        today_orders = filter_orders_by_user_branch(request, today_orders)
        today_sales = today_orders.aggregate(total=Sum('final_amount'))['total'] or 0
        today_transactions = today_orders.count()
        today_customers = today_orders.values('customer_name', 'customer_phone').distinct().count()
        avg_order_value = today_orders.aggregate(avg=Avg('final_amount'))['avg'] or 0
    else:
        today_sales = today_summary.total_revenue
        today_transactions = today_summary.total_transactions
        today_customers = getattr(today_summary, 'total_customers', 0)
        avg_order_value = float(today_sales) / max(today_transactions, 1)

    # Inventory data
    total_inventory = Product.objects.filter(company=company).count() if company else 0
    low_stock_products = Product.objects.filter(
        company=company, stock_status__in=['low_stock', 'out_of_stock']
    ).count() if company else 0

    # User data
    total_users = CustomUser.objects.filter(company=company).count() if company else 0
    active_users = CustomUser.objects.filter(company=company, is_active=True).count() if company else 0

    # Timeline activities
    recent_orders = base_orders.filter(
        created_at__date=today,
        status='completed'
    ).order_by('-created_at')[:3]

    from inventory.models import InventoryTransaction
    recent_inventory_updates = InventoryTransaction.objects.filter(
        company=company,
        created_at__date=today
    ).order_by('-created_at')[:3] if company else InventoryTransaction.objects.none()

    recent_users = CustomUser.objects.filter(
        company=company,
        date_joined__date=today
    ).order_by('-date_joined')[:3] if company else CustomUser.objects.none()

    activities = []

    # Orders
    for order in recent_orders:
        activities.append({
            'type': 'sale',
            'title': f'POS Sale #{order.order_number}',
            'amount': order.final_amount,
            'time': order.created_at.strftime('%H:%M'),
            'icon': 'fas fa-cash-register',
            'color': 'primary'
        })

    # Inventory
    for update in recent_inventory_updates:
        activities.append({
            'type': 'inventory',
            'title': f'{update.transaction_type.title()} Stock',
            'product': update.product.name,
            'quantity': update.quantity,
            'time': update.created_at.strftime('%H:%M'),
            'icon': 'fas fa-box',
            'color': 'success'
        })

    # New users
    for user in recent_users:
        activities.append({
            'type': 'user',
            'title': f'New User: {user.username}',
            'time': user.date_joined.strftime('%H:%M'),
            'icon': 'fas fa-user-plus',
            'color': 'info'
        })

    activities.sort(key=lambda x: x['time'], reverse=True)

    # Top selling items (last 24 hours)
    last_24h_start = timezone.now() - timedelta(hours=24)

    top_selling_items = (
        POSOrderItem.objects.filter(
            order__company=company,
            order__created_at__gte=last_24h_start,
            order__status='completed'
        )
        .values('product__name', 'product__sku')
        .annotate(
            total_quantity=Sum('quantity'),
            total_revenue=Sum('total_price')
        )
        .order_by('-total_quantity')[:5]
    )

    # ── Weekly chart data (last 7 days) ──
    import json
    weekly_labels = []
    weekly_revenue_data = []
    weekly_orders_data = []
    for i in range(6, -1, -1):
        day = today - timedelta(days=i)
        day_orders = base_orders.filter(created_at__date=day, status='completed')
        rev = day_orders.aggregate(total=Sum('final_amount'))['total'] or 0
        cnt = day_orders.count()
        weekly_labels.append(day.strftime('%a'))
        weekly_revenue_data.append(float(rev))
        weekly_orders_data.append(cnt)

    # ── Yesterday stats ──
    yesterday = today - timedelta(days=1)
    yesterday_qs = base_orders.filter(created_at__date=yesterday, status='completed')
    yesterday_sales = yesterday_qs.aggregate(total=Sum('final_amount'))['total'] or 0
    yesterday_transactions = yesterday_qs.count()

    # Growth
    if yesterday_sales > 0:
        sales_growth_percentage = ((float(today_sales) - float(yesterday_sales)) / float(yesterday_sales)) * 100
    else:
        sales_growth_percentage = 0

    # ── Weekly / Monthly totals ──
    week_start = today - timedelta(days=today.weekday())
    month_start = today.replace(day=1)
    weekly_qs = base_orders.filter(created_at__date__gte=week_start, status='completed')
    monthly_qs = base_orders.filter(created_at__date__gte=month_start, status='completed')
    weekly_sales = weekly_qs.aggregate(total=Sum('final_amount'))['total'] or 0
    weekly_transactions = weekly_qs.count()
    monthly_sales = monthly_qs.aggregate(total=Sum('final_amount'))['total'] or 0
    monthly_transactions = monthly_qs.count()

    # ── Inventory detail ──
    in_stock_products = Product.objects.filter(company=company, stock_status='in_stock').count() if company else 0
    out_of_stock_products = Product.objects.filter(company=company, stock_status='out_of_stock').count() if company else 0

    # ── Recent orders (queryset for template) ──
    recent_orders_qs = base_orders.filter(
        created_at__date=today, status='completed'
    ).select_related('customer').order_by('-created_at')[:6]

    # ── Payment breakdown ──
    payment_breakdown = []
    total_today = float(today_sales) or 1
    for method_code, method_label in [('cash','Cash'),('transfer','Bank Transfer'),('pos','POS/Card'),('mobile_money','Mobile Money')]:
        method_total = base_orders.filter(
            created_at__date=today, status='completed', payment_method=method_code
        ).aggregate(total=Sum('final_amount'))['total'] or 0
        if method_total:
            payment_breakdown.append({
                'label': method_label,
                'total': float(method_total),
                'percentage': round(float(method_total) / total_today * 100, 1),
            })

    # ── Cashier performance ──
    from django.db.models import Count
    cashier_performance = (
        base_orders.filter(created_at__date=today, status='completed')
        .values('cashier')
        .annotate(total_orders=Count('id'), total_sales=Sum('final_amount'))
        .order_by('-total_sales')[:8]
    )

    # ── Subscription / Plan data ──
    plan = getattr(company, 'plan', None)
    today_orders_count = base_orders.filter(created_at__date=today).count()
    
    sub_data          = None
    days_until_expiry = None
    license_expired   = False
    whatsapp_number   = None
    license_obj       = None

    if plan and company:
        from accounts.models import CustomUser as _CU
        from inventory.models import ProductCategory

        def _pct(current, maximum):
            if maximum and maximum > 0:
                return min(round(current / maximum * 100), 100)
            return None

        products_count    = Product.objects.filter(company=company).count()
        categories_count  = ProductCategory.objects.filter(company=company).count()
        users_count       = _CU.objects.filter(company=company).count()

        # Feature flags to display (label, plan attr)
        feature_flags = [
            ('POS Terminal V1',      plan.feature_pos_terminal_v1),
            ('Smart Grid POS V2',    plan.feature_pos_terminal_v2_grid),
            ('Barcode POS',          plan.feature_barcode_pos),
            ('Bulk Import',          plan.feature_bulk_import),
            ('Data Export',          plan.feature_export),
            ('P&L Reports',          plan.feature_profit_loss),
            ('Audit Logs',           plan.feature_audit_logs),
            ('Multi-Branch',         plan.feature_multi_branch),
            ('Wholesale Pricing',    plan.feature_wholesale_price),
            ('Discounts',            plan.feature_discount),
            ('Promo Codes',          plan.feature_promo),
            ('Credit Sales',         plan.feature_credit_sales),
            ('Advanced Reports',     plan.feature_advanced_reports),
        ]

        # Expiry data
        today_date = timezone.now().date()
        days_until_expiry = None
        license_expired = company.is_expired
        if company.expiry_date:
            days_until_expiry = (company.expiry_date - today_date).days
            if days_until_expiry < 0:
                days_until_expiry = 0
                license_expired = True

        sub_data = {
            'plan_name':          plan.name,
            'plan_price':         plan.price_monthly,
            'is_active':          company.is_active,
            'is_expired':         license_expired,
            'is_accessible':      company.is_accessible,
            'expiry_date':        company.expiry_date,
            'days_until_expiry':  days_until_expiry,
            # Usage
            'products_count':     products_count,
            'max_products':       plan.max_products,
            'products_pct':       _pct(products_count, plan.max_products),
            'categories_count':   categories_count,
            'max_categories':     plan.max_categories,
            'categories_pct':     _pct(categories_count, plan.max_categories),
            'orders_today':       today_orders_count,
            'max_orders_per_day': plan.max_orders_per_day,
            'orders_pct':         _pct(today_orders_count, plan.max_orders_per_day),
            'users_count':        users_count,
            'max_staff':          plan.max_staff,
            'users_pct':          _pct(users_count, plan.max_staff),
            'max_branches':       plan.max_branches,
            # Features
            'features':           feature_flags,
        }
        
        # Pull extra context for the banner
        whatsapp_number = company.whatsapp_number
        license_obj = company # For backward compatibility in template

    context = {
        'today_sales': today_sales,
        'today_transactions': today_transactions,
        'today_customers': today_customers,
        'avg_order_value': avg_order_value,
        'yesterday_sales': yesterday_sales,
        'yesterday_transactions': yesterday_transactions,
        'weekly_sales': weekly_sales,
        'weekly_transactions': weekly_transactions,
        'monthly_sales': monthly_sales,
        'monthly_transactions': monthly_transactions,
        'sales_growth_percentage': sales_growth_percentage,
        'total_inventory': total_inventory,
        'in_stock_products': in_stock_products,
        'low_stock_products': low_stock_products,
        'out_of_stock_products': out_of_stock_products,
        'total_users': total_users,
        'active_users': active_users,
        'top_selling_items': top_selling_items,
        'recent_orders': recent_orders_qs,
        'payment_breakdown': payment_breakdown,
        'cashier_performance': cashier_performance,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
        # Chart.js data (JSON-safe)
        'weekly_labels': json.dumps(weekly_labels),
        'weekly_revenue_data': json.dumps(weekly_revenue_data),
        'weekly_orders_data': json.dumps(weekly_orders_data),
        # Subscription
        'sub_data': sub_data,
    }
    return render(request, 'accounts/dashboard.html', context)

    

@login_required
@role_required('admin')
def company_settings(request):
    """Edit CompanySettings for request.company. Replaces old system_settings."""
    from companies.models import CompanySettings
    company = request.company
    cs, created = CompanySettings.objects.get_or_create(company=company)
    
    # Pre-populate settings from company model if it's new OR if it still has generic names
    generic_names = ["My Business", "Modern POS Business", "MODERN POS BUSINESS", "MODERN POS business"]
    if created or cs.business_name in generic_names:
        if company.name:
             cs.business_name = company.name
        if company.address:
             cs.business_address = company.address
        if company.phone:
             cs.business_phone = company.phone
        if company.email:
             cs.business_email = company.email
        if company.logo:
             cs.logo = company.logo
        cs.save()

    if request.method == 'POST':
        cs.business_name    = request.POST.get('business_name',    cs.business_name)
        cs.business_address = request.POST.get('business_address', cs.business_address)
        cs.business_phone   = request.POST.get('business_phone',   cs.business_phone)
        cs.business_email   = request.POST.get('business_email',   cs.business_email)
        cs.currency_symbol  = request.POST.get('currency_symbol',  cs.currency_symbol)
        cs.vat_rate         = request.POST.get('vat_rate',         cs.vat_rate) or 0
        cs.pos_interface_mode = request.POST.get('pos_interface_mode', cs.pos_interface_mode)
        cs.receipt_header   = request.POST.get('receipt_header',   cs.receipt_header)
        cs.receipt_footer   = request.POST.get('receipt_footer',   cs.receipt_footer)
        # Checkboxes: present in POST = True, absent = False
        cs.enable_camera_scanner = 'enable_camera_scanner' in request.POST
        cs.show_receipt_logo     = 'show_receipt_logo'     in request.POST
        # Optional fields (safe to set if the model has them)
        if hasattr(cs, 'decimal_places'):
            try:
                cs.decimal_places = int(request.POST.get('decimal_places', cs.decimal_places or 2))
            except (ValueError, TypeError):
                pass
        if hasattr(cs, 'use_comma_separator'):
            cs.use_comma_separator = 'use_comma_separator' in request.POST
        if hasattr(cs, 'enable_unlimited_stock'):
            cs.enable_unlimited_stock = 'enable_unlimited_stock' in request.POST

        # ── WhatsApp / SMS ──────────────────────────────────────────────
        if hasattr(cs, 'whatsapp_api_url'):
            cs.whatsapp_api_url = request.POST.get('whatsapp_api_url', cs.whatsapp_api_url or '').strip()
        if hasattr(cs, 'whatsapp_api_key'):
            val = request.POST.get('whatsapp_api_key', '').strip()
            if val:  # only overwrite if user actually typed something (password fields send blank when unchanged)
                cs.whatsapp_api_key = val
        if hasattr(cs, 'sms_api_key'):
            val = request.POST.get('sms_api_key', '').strip()
            if val:
                cs.sms_api_key = val
        if hasattr(cs, 'sms_sender_id'):
            cs.sms_sender_id = request.POST.get('sms_sender_id', cs.sms_sender_id or '').strip()
        if hasattr(cs, 'send_receipt_via_whatsapp'):
            cs.send_receipt_via_whatsapp = 'send_receipt_via_whatsapp' in request.POST
        if hasattr(cs, 'send_credit_via_whatsapp'):
            cs.send_credit_via_whatsapp = 'send_credit_via_whatsapp' in request.POST
        if hasattr(cs, 'send_lowstock_via_whatsapp'):
            cs.send_lowstock_via_whatsapp = 'send_lowstock_via_whatsapp' in request.POST

        # ── Thermal Printing ────────────────────────────────────────────
        if hasattr(cs, 'thermal_printer_name'):
            cs.thermal_printer_name = request.POST.get('thermal_printer_name', cs.thermal_printer_name or '').strip()
        if hasattr(cs, 'thermal_paper_width'):
            try:
                cs.thermal_paper_width = int(request.POST.get('thermal_paper_width', 80))
            except (ValueError, TypeError):
                pass
        if hasattr(cs, 'auto_print_receipt'):
            cs.auto_print_receipt = 'auto_print_receipt' in request.POST

        # ── Security / 2FA ──────────────────────────────────────────────
        if hasattr(cs, 'require_2fa_for_admin'):
            cs.require_2fa_for_admin = 'require_2fa_for_admin' in request.POST
        if hasattr(cs, 'require_2fa_for_manager'):
            cs.require_2fa_for_manager = 'require_2fa_for_manager' in request.POST
        if hasattr(cs, 'require_2fa_for_cashier'):
            cs.require_2fa_for_cashier = 'require_2fa_for_cashier' in request.POST

        if request.FILES.get('logo'):
            cs.logo = request.FILES['logo']
        cs.save()
        messages.success(request, 'Settings saved successfully!')
        return redirect('company_settings')


    # Build the live webhook URL dynamically from the current request
    webhook_url = request.build_absolute_uri('/webhooks/monnify/')

    import sys, os
    python_path = sys.executable
    manage_py   = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'manage.py')
    cron_command = f'"{python_path}" "{manage_py}" process_subscriptions'
    # cPanel "Command" field format (no quotes needed on Linux)
    cpanel_cron_command = f'{python_path} {manage_py} process_subscriptions'

    context = {
        'cs': cs,
        'company': company,
        'user_role':  request.user.role,
        'user_name':  request.user.get_full_name() or request.user.username,
        'webhook_url': webhook_url,
        'cron_command': cron_command,
        'cpanel_cron_command': cpanel_cron_command,
        'cpanel_cron_schedule': '0 1 * * *',
    }
    return render(request, 'core/system_settings.html', context)


# Legacy alias — keeps any old template {% url 'system_settings' %} working
system_settings = company_settings



@login_required
@role_required('admin')
@company_feature_required('feature_promo')
def promo_list(request):
    promos = PromoCode.objects.filter(company=request.company)
    return render(request, 'core/promo_list.html', {
        'promos': promos,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    })


@login_required
@role_required('admin')
@company_feature_required('feature_promo')
def promo_create(request):
    if request.method == 'POST':
        code = request.POST.get('code', '').strip().upper()
        description = request.POST.get('description', '').strip()
        discount_type = request.POST.get('discount_type', 'percentage')
        discount_value = request.POST.get('discount_value', '0')
        max_uses = request.POST.get('max_uses', '0')
        minimum_order_amount = request.POST.get('minimum_order_amount', '0')
        expires_at_raw = request.POST.get('expires_at', '').strip() or None

        if not code:
            messages.error(request, 'Code is required.')
            return redirect('promo_create')

        if PromoCode.objects.filter(company=request.company, code__iexact=code).exists():
            messages.error(request, f'Code "{code}" already exists.')
            return redirect('promo_create')

        PromoCode.objects.create(
            company=request.company,
            code=code, description=description, discount_type=discount_type,
            discount_value=discount_value, max_uses=max_uses,
            minimum_order_amount=minimum_order_amount, expires_at=expires_at_raw,
        )
        messages.success(request, f'Promo code "{code}" created!')
        return redirect('promo_list')

    return render(request, 'core/promo_form.html', {
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    })


@login_required
@role_required('admin')
@company_feature_required('feature_promo')
def promo_toggle(request, pk):
    promo = get_object_or_404(PromoCode, pk=pk, company=request.company)
    promo.is_active = not promo.is_active
    promo.save()
    status = 'activated' if promo.is_active else 'deactivated'
    messages.success(request, f'Promo "{promo.code}" {status}.')
    return redirect('promo_list')


@login_required
@role_required('admin')
@company_feature_required('feature_promo')
def promo_delete(request, pk):
    promo = get_object_or_404(PromoCode, pk=pk, company=request.company)
    if request.method == 'POST':
        code = promo.code
        promo.delete()
        messages.success(request, f'Promo "{code}" deleted.')
        return redirect('promo_list')
    return render(request, 'core/promo_confirm_delete.html', {
        'promo': promo,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    })




    # ==========================
# Branch Management Views
# ==========================

@login_required
@role_required('admin')
@company_feature_required('feature_multi_branch')
def branch_list(request):
    """
    List all branches. If no branches exist, create a default MAIN branch.
    """
    # Ensure at least one branch exists
    if not Branch.objects.filter(company=request.company).exists():
        default_name = request.company.settings.business_name if getattr(request.company, 'settings', None) else "Main Branch"
        Branch.objects.create(
            company=request.company,
            name=default_name,
            code="MAIN",
            is_active=True,
        )

    allow_multi_branch = getattr(request.company.plan, 'feature_multi_branch', False) if request.company.plan else False

    branches = Branch.objects.filter(company=request.company).order_by('name')

    context = {
        "branches": branches,
        "allow_multi_branch": allow_multi_branch,
    }
    return render(request, "core/branch_list.html", context)


@login_required
@role_required('admin')
@company_feature_required('feature_multi_branch')
def branch_create(request):
    """
    Create a new branch – only allowed if plan.allow_multi_branch is True.
    """

    if request.method == "POST":
        form = BranchForm(request.POST)
        if form.is_valid():
            branch = form.save(commit=False)
            branch.company = request.company
            branch.save()
            messages.success(request, "Branch created successfully.")
            return redirect('branch_list')
    else:
        form = BranchForm()

    return render(request, "core/branch_form.html", {"form": form, "mode": "create"})


@login_required
@role_required('admin')
def branch_update(request, pk):
    """
    Edit an existing branch. Even on single-branch plans, editing the MAIN branch should be allowed.
    """
    branch = get_object_or_404(Branch, pk=pk, company=request.company)

    if request.method == "POST":
        form = BranchForm(request.POST, instance=branch)
        if form.is_valid():
            form.save()
            messages.success(request, "Branch updated successfully.")
            return redirect('branch_list')
    else:
        form = BranchForm(instance=branch)

    return render(request, "core/branch_form.html", {"form": form, "mode": "edit", "branch": branch})


@login_required
@role_required('admin')
def branch_delete(request, pk):
    """
    Delete a branch. Prevent deletion if it's the only branch.
    """
    branch = get_object_or_404(Branch, pk=pk, company=request.company)

    if Branch.objects.filter(company=request.company).count() <= 1:
        messages.error(request, "You must have at least one branch.")
        return redirect('branch_list')

    if request.method == "POST":
        branch.delete()
        messages.success(request, "Branch deleted successfully.")
        return redirect('branch_list')

    return render(request, "core/branch_confirm_delete.html", {"branch": branch})

# core/views.py

from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseForbidden
from django.utils import timezone
from django.db.models import Sum, Count
from sales.models import POSOrder
from accounts.models import CustomUser
from .models import Branch

@login_required
@role_required('admin')
def branch_detail(request, pk):
    """
    Branch detail page – shows sales and users for this branch.
    Respects roles:
      - superadmin/admin → can view any branch
      - manager/cashier → only their own branch
    """
    branch = get_object_or_404(Branch, pk=pk, company=request.company)
    user = request.user

    if user.role in ("manager", "cashier") and user.branch_id != branch.id:
        return HttpResponseForbidden("You are not allowed to view other branches.")

    today = timezone.now().date()
    month_start = today.replace(day=1)

    orders_today = POSOrder.objects.filter(
        branch=branch,
        status="completed",
        created_at__date=today,
    )

    orders_month = POSOrder.objects.filter(
        branch=branch,
        status="completed",
        created_at__date__gte=month_start,
        created_at__date__lte=today,
    )

    today_sales = orders_today.aggregate(total=Sum("final_amount"))["total"] or 0
    month_sales = orders_month.aggregate(total=Sum("final_amount"))["total"] or 0
    total_orders_today = orders_today.count()
    total_orders_month = orders_month.count()

    branch_users = CustomUser.objects.filter(branch=branch).order_by("role", "username")
    from inventory.models import BranchStock
    branch_stocks = BranchStock.objects.filter(branch=branch).select_related("product").order_by("-quantity")

    context = {
        "branch": branch,
        "users": branch_users,
        "branch_stocks": branch_stocks,
        "today_sales": today_sales,
        "month_sales": month_sales,
        "total_orders_today": total_orders_today,
        "total_orders_month": total_orders_month,
        "orders_today": orders_today.order_by("-created_at")[:20],
        "user_role": user.role,
        "user_name": user.get_full_name() or user.username,
    }
    return render(request, "core/branch_detail.html", context)


def offline(request):
    """
    Shown when the service worker can't reach network and no cached page is available.
    """
    return render(request, 'core/offline.html')


def upgrade_required(request):
    """Feature lock page - shown when a plan-gated feature is accessed."""
    feature_name = request.GET.get('feature', 'This Feature')
    required_plan = request.GET.get('required_plan', 'Standard')
    return render(request, 'core/upgrade_required.html', {
        'feature_name': feature_name,
        'required_plan': required_plan,
    })


def permission_denied(request):
    """Role permission denied — shown when a user's role doesn't have access to a feature."""
    return render(request, 'core/permission_denied.html', {
        'user_role': getattr(request.user, 'role', ''),
        'user_name': request.user.get_full_name() or request.user.username if request.user.is_authenticated else '',
    })


# ─────────────────────────────────────────────────────────────────
# CUSTOM ERROR HANDLERS
# ─────────────────────────────────────────────────────────────────

def error_400(request, exception=None):
    """400 Bad Request"""
    return render(request, 'errors/400.html', status=400)


def error_403(request, exception=None):
    """403 Forbidden / Permission Denied"""
    return render(request, 'errors/403.html', status=403)


def error_404(request, exception=None):
    """404 Page Not Found"""
    return render(request, 'errors/404.html', status=404)


def error_500(request):
    """500 Internal Server Error"""
    return render(request, 'errors/500.html', status=500)


def error_503(request, exception=None):
    """503 Service Unavailable"""
    return render(request, 'errors/503.html', status=503)

# ─────────────────────────────────────────────────────────────────
# AI ASSISTANT VIEWS
# ─────────────────────────────────────────────────────────────────
from django.conf import settings
from .models import AIPrompt, AIChatLog
from .ai_service import call_llm
import json

@login_required
def web_ai_chat(request):
    """Handles chat messages from the web UI widget."""
    if request.method == 'GET':
        chat_history = AIChatLog.objects.filter(company=request.company).select_related('user').order_by('-created_at')[:30]
        return render(request, 'core/ai_chat_page.html', {
            'chat_history': chat_history,
            'user_role': request.user.role,
            'user_name': request.user.get_full_name() or request.user.username,
        })
    elif request.method != 'POST':
        return JsonResponse({'error': 'Method not allowed'}, status=405)

    company = getattr(request, 'company', None)
    if not company:
        return JsonResponse({'error': 'No company logic context.'}, status=400)

    try:
        data = json.loads(request.body)
        prompt_text = data.get('prompt', '').strip()
    except Exception:
        return JsonResponse({'error': 'Invalid JSON data'}, status=400)

    if not prompt_text:
        return JsonResponse({'error': 'Prompt cannot be empty.'}, status=400)

    # 1. Check Rate Limit
    today = timezone.now().date()
    daily_limit = getattr(settings, 'AI_DAILY_LIMIT', 50)
    
    current_usage = AIChatLog.objects.filter(
        company=company,
        created_at__date=today
    ).count()

    if current_usage >= daily_limit:
        return JsonResponse({
            'error': f'You have reached your company\'s AI limit of {daily_limit} chats per day.'
        }, status=429)

    # 2. Call AI Service
    # This might block for a few seconds, so frontend needs a typing indicator
    response_text = call_llm(prompt_text, company)

    # 3. Log the interaction
    AIChatLog.objects.create(
        company=company,
        user=request.user,
        prompt=prompt_text,
        response=response_text,
        tokens_used=0  # Calculate if desired later
    )

    return JsonResponse({
        'response': response_text,
        'usage_remaining': daily_limit - current_usage - 1
    })

@login_required
def web_ai_prompts(request):
    """Returns global and company-specific ready-made questions."""
    company = getattr(request, 'company', None)
    
    if request.method == 'GET':
        if not AIPrompt.objects.exists():
            AIPrompt.objects.bulk_create([
                AIPrompt(text="How much have we sold today?", is_global=True),
                AIPrompt(text="What is our outstanding credit?", is_global=True),
                AIPrompt(text="List the items that are low in stock.", is_global=True),
                AIPrompt(text="What was our revenue yesterday?", is_global=True),
                AIPrompt(text="Who owes us money right now?", is_global=True),
                AIPrompt(text="What is our total revenue for this month?", is_global=True),
                AIPrompt(text="Do we have any out of stock items?", is_global=True),
                AIPrompt(text="Compare today's sales to yesterday's.", is_global=True)
            ])

        qs = AIPrompt.objects.filter(
            Q(is_global=True) | Q(company=company)
        ).values('id', 'text', 'is_global')
        return JsonResponse(list(qs), safe=False)
        
    elif request.method == 'POST':
        try:
            data = json.loads(request.body)
            text = data.get('text', '').strip()
            if text and company:
                AIPrompt.objects.create(company=company, text=text, is_global=False)
                return JsonResponse({'status': 'ok'})
        except Exception:
            pass
        return JsonResponse({'error': 'Failed to add prompt'}, status=400)
@login_required
def sales_hub(request):
    return render(request, 'core/hubs/sales_hub.html')

@login_required
def inventory_hub(request):
    return render(request, 'core/hubs/inventory_hub.html')

@login_required
def insights_hub(request):
    return render(request, 'core/hubs/insights_hub.html')

@login_required
def admin_hub(request):
    return render(request, 'core/hubs/admin_hub.html')


@login_required
@role_required(['admin', 'manager'])
def how_it_works(request):
    """How It Works guide — accessible to admins and managers."""
    return render(request, 'core/how_it_works.html')

