# analytics/views.py
"""
Analytics dashboard views — all company-scoped.
Cashiers get read-only access; admin/manager get full access.
"""
import logging
from datetime import timedelta
from decimal import Decimal

from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.utils import timezone
from django.db.models import Sum, Count, Q
from django.core.paginator import Paginator

from accounts.decorators import role_required, perm_required

logger = logging.getLogger(__name__)


def _get_company(request):
    return getattr(request, 'company', None)


# ─── INSIGHTS DASHBOARD ───────────────────────────────────────────────────────

@login_required
@perm_required('can_view_analytics')
def insights_dashboard(request):
    """Business Insights — gated by can_view_analytics permission."""
    from analytics.models import Insight

    company = _get_company(request)
    if not company:
        return redirect('company_inactive')

    category_filter = request.GET.get('category', '')
    priority_filter = request.GET.get('priority', '')

    qs = Insight.objects.filter(company=company)
    if category_filter:
        qs = qs.filter(category=category_filter)
    if priority_filter:
        qs = qs.filter(priority=priority_filter)

    paginator = Paginator(qs, 20)
    page_obj = paginator.get_page(request.GET.get('page'))

    unread_count = Insight.objects.filter(company=company, is_read=False).count()
    high_priority = Insight.objects.filter(company=company, priority='high', is_read=False).count()

    context = {
        'page_obj': page_obj,
        'unread_count': unread_count,
        'high_priority': high_priority,
        'category_filter': category_filter,
        'priority_filter': priority_filter,
        'categories': Insight.CATEGORY_CHOICES,
        'priorities': Insight.PRIORITY_CHOICES,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'analytics/insights.html', context)


@login_required
@require_POST
def mark_insight_read(request, pk):
    """AJAX: toggle is_read for an insight."""
    from analytics.models import Insight
    company = _get_company(request)
    insight = get_object_or_404(Insight, pk=pk, company=company)
    insight.is_read = not insight.is_read
    insight.save(update_fields=['is_read'])
    return JsonResponse({'is_read': insight.is_read})


@login_required
@require_POST
def mark_all_insights_read(request):
    """Mark all unread insights as read."""
    from analytics.models import Insight
    company = _get_company(request)
    Insight.objects.filter(company=company, is_read=False).update(is_read=True)
    return JsonResponse({'status': 'ok'})


# ─── NOTIFICATIONS ────────────────────────────────────────────────────────────

@login_required
def notifications_panel(request):
    """Notifications inbox — all roles."""
    from analytics.models import Notification
    company = _get_company(request)
    if not company:
        return redirect('company_inactive')

    notifs = Notification.objects.filter(
        company=company
    ).filter(
        Q(user=request.user) | Q(user__isnull=True)
    ).order_by('-created_at')

    unread = notifs.filter(is_read=False).count()

    paginator = Paginator(notifs, 25)
    page_obj = paginator.get_page(request.GET.get('page'))

    context = {
        'page_obj': page_obj,
        'unread_count': unread,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'analytics/notifications.html', context)


@login_required
@require_POST
def mark_notification_read(request, pk):
    """AJAX: mark a notification as read."""
    from analytics.models import Notification
    company = _get_company(request)
    notif = get_object_or_404(
        Notification, pk=pk, company=company
    )
    notif.is_read = True
    notif.save(update_fields=['is_read'])
    return JsonResponse({'status': 'ok'})


# ─── STOCK FORECAST ───────────────────────────────────────────────────────────

@login_required
@perm_required('can_view_stock_forecast')
def stock_forecast_dashboard(request):
    """Stock Forecast dashboard — gated by can_view_stock_forecast permission."""
    from analytics.models import StockForecast
    company = _get_company(request)
    if not company:
        return redirect('company_inactive')

    health_filter = request.GET.get('health', '')
    qs = StockForecast.objects.filter(company=company).select_related('product')

    if health_filter:
        qs = qs.filter(stock_health=health_filter)

    # Sort: critical/low_risk first
    health_order = {'critical': 0, 'low_risk': 1, 'dead': 2, 'overstock': 3, 'healthy': 4}
    forecasts = sorted(qs, key=lambda x: (health_order.get(x.stock_health, 5), x.days_until_stockout or 9999))

    # Summary counts
    counts = {h: 0 for h, _ in StockForecast.HEALTH_CHOICES}
    for f in forecasts:
        counts[f.stock_health] = counts.get(f.stock_health, 0) + 1

    context = {
        'forecasts': forecasts,
        'health_filter': health_filter,
        'health_choices': StockForecast.HEALTH_CHOICES,
        'counts': counts,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'analytics/stock_forecast.html', context)


# ─── ROLE PERMISSIONS ────────────────────────────────────────────────────────

@login_required
@role_required(['admin'])
def role_permissions(request):
    """Manage per-role permissions for this company."""
    from analytics.models import RolePermission
    company = _get_company(request)
    if not company:
        return redirect('company_inactive')

    roles = ['cashier', 'manager', 'admin']
    perms = {}
    for role in roles:
        perms[role] = RolePermission.get_for_role(company, role)

    if request.method == 'POST':
        for role in ['cashier', 'manager']:
            perm = perms[role]
            bool_fields = [
                'can_delete_orders', 'can_reverse_orders', 'can_change_price_at_pos',
                'can_apply_discount',
                'can_view_profit', 'can_view_pnl', 'can_view_reports', 'can_export_data',
                'can_view_analytics', 'can_view_stock_forecast',
                'can_manage_products', 'can_manage_suppliers', 'can_manage_purchase_orders',
                'can_view_customers', 'can_manage_customers', 'can_view_credit_sales',
                'can_manage_users', 'can_view_audit_log', 'can_manage_expenses',
                'can_view_staff_performance', 'can_change_settings',
            ]
            for field in bool_fields:
                setattr(perm, field, request.POST.get(f'{role}_{field}') == 'on')
            perm.save()

        from django.contrib import messages
        messages.success(request, 'Role permissions updated successfully.')
        return redirect('analytics:role_permissions')

    PERMISSION_SECTIONS = [
        ('POS Operations', [
            ('can_delete_orders',        'Delete Orders'),
            ('can_reverse_orders',       'Reverse / Refund Orders'),
            ('can_change_price_at_pos',  'Change Price at POS'),
            ('can_apply_discount',       'Apply Discounts'),
        ]),
        ('Reports & Finance', [
            ('can_view_profit',          'View Profit Reports'),
            ('can_view_pnl',             'View P&L Report'),
            ('can_view_reports',         'View Sales / Daily Reports'),
            ('can_export_data',          'Export Data (CSV/Excel)'),
            ('can_manage_expenses',      'Manage Operating Expenses'),
        ]),
        ('Analytics & Insights', [
            ('can_view_analytics',       'View Analytics / Insights'),
            ('can_view_stock_forecast',  'View Stock Forecast'),
            ('can_view_staff_performance', 'View Staff Performance'),
        ]),
        ('Inventory Management', [
            ('can_manage_products',      'Manage Products (Add/Edit/Delete)'),
            ('can_manage_suppliers',     'Manage Suppliers & Purchase Orders'),
            ('can_manage_purchase_orders', 'Create / Receive Purchase Orders'),
        ]),
        ('Customer Management', [
            ('can_view_customers',       'View Customers List'),
            ('can_manage_customers',     'Add / Edit Customers'),
            ('can_view_credit_sales',    'View Credit Sales'),
        ]),
        ('Staff & Administration', [
            ('can_manage_users',         'Manage Staff Accounts'),
            ('can_view_audit_log',       'View Audit Log'),
            ('can_change_settings',      'Change Company Settings'),
        ]),
    ]

    # Flatten for template use
    PERMISSION_FIELDS = [
        (field, label)
        for _, entries in PERMISSION_SECTIONS
        for field, label in entries
    ]

    # Build flat lists of (field, bool_value) for cashier and manager
    all_fields = [field for field, _ in PERMISSION_FIELDS]
    cashier_perm = perms['cashier']
    manager_perm = perms['manager']
    cashier_values = [(f, getattr(cashier_perm, f, False)) for f in all_fields]
    manager_values = [(f, getattr(manager_perm, f, False)) for f in all_fields]

    context = {
        'perms': perms,
        'roles': ['cashier', 'manager'],
        'permission_sections': PERMISSION_SECTIONS,
        'permission_fields': PERMISSION_FIELDS,
        'cashier_values': cashier_values,
        'manager_values': manager_values,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'analytics/role_permissions.html', context)


# ─── FEATURE USAGE (Superadmin only) ─────────────────────────────────────────

@login_required
def feature_usage_dashboard(request):
    """Superadmin: per-company feature usage analytics."""
    if not request.user.is_superuser:
        from django.http import HttpResponseForbidden
        return HttpResponseForbidden("Superadmin only.")

    from companies.models import Company
    from sales.models import POSOrder
    from inventory.models import Product
    from accounts.models import CustomUser
    from django.utils.timezone import now

    since_30 = now() - timedelta(days=30)

    companies = Company.objects.filter(is_active=True).select_related('plan', 'settings')
    data = []
    for c in companies:
        orders_30 = POSOrder.objects.filter(company=c, created_at__gte=since_30).count()
        products = Product.objects.filter(company=c).count()
        active_users = CustomUser.objects.filter(company=c, is_active=True).count()
        last_order = POSOrder.objects.filter(company=c).order_by('-created_at').first()
        data.append({
            'company': c,
            'orders_30': orders_30,
            'products': products,
            'active_users': active_users,
            'last_activity': last_order.created_at if last_order else None,
        })

    context = {
        'data': data,
        'user_role': 'superadmin',
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'analytics/feature_usage.html', context)


# ─── OPERATING EXPENSES ───────────────────────────────────────────────────────

@login_required
@perm_required('can_manage_expenses')
def expense_list(request):
    """View Operating Expenses."""
    from analytics.models import OperatingExpense
    company = _get_company(request)
    expenses = OperatingExpense.objects.filter(company=company)
    
    context = {
        'expenses': expenses,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'analytics/expenses/expense_list.html', context)

@login_required
@perm_required('can_manage_expenses')
def expense_create(request):
    """Add a new Operating Expense."""
    from analytics.forms import OperatingExpenseForm
    company = _get_company(request)
    
    if request.method == "POST":
        form = OperatingExpenseForm(request.POST, company=company)
        if form.is_valid():
            expense = form.save(commit=False)
            expense.company = company
            expense.logged_by = request.user
            expense.save()
            from django.contrib import messages
            messages.success(request, "Expense logged successfully.")
            return redirect("analytics:expense_list")
    else:
        form = OperatingExpenseForm(company=company)
        
    context = {
        'form': form,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'analytics/expenses/expense_form.html', context)

@login_required
@perm_required('can_manage_expenses')
def expense_category_list(request):
    """List Expense Categories."""
    from analytics.models import ExpenseCategory
    company = _get_company(request)
    categories = ExpenseCategory.objects.filter(company=company).annotate(expense_count=Count('expenses'))
    
    context = {
        'categories': categories,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'analytics/expenses/category_list.html', context)

@login_required
@perm_required('can_manage_expenses')
def expense_category_create(request):
    """Create a new Expense Category."""
    from analytics.forms import ExpenseCategoryForm
    company = _get_company(request)
    
    if request.method == "POST":
        form = ExpenseCategoryForm(request.POST)
        if form.is_valid():
            cat = form.save(commit=False)
            cat.company = company
            cat.save()
            from django.contrib import messages
            messages.success(request, "Category created successfully.")
            return redirect("analytics:expense_category_list")
    else:
        form = ExpenseCategoryForm()

    context = {
        'form': form,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'analytics/expenses/category_form.html', context)

