from django.shortcuts import render
from django.http import JsonResponse
from django.db.models import Q, Sum, Count, F
from django.db.models.functions import TruncMonth
from django.urls import reverse
from inventory.models import Product
from customers.models import Customer
from suppliers.models import Supplier
from sales.models import Sale
from hr.models import Employee, Attendance
from orders.models import Order
from expenses.models import Expense
from django.contrib.auth.decorators import login_required
from django.utils import timezone
from datetime import timedelta


@login_required
def global_search(request):
    query = request.GET.get('q', '').strip()

    if len(query) < 2:
        return JsonResponse({'results': []})

    results = []

    # Search Products
    try:
        products = Product.objects.filter(
            Q(name__icontains=query) | 
            Q(barcode__icontains=query) |
            Q(description__icontains=query),
            is_active=True
        )[:5]

        for product in products:
            results.append({
                'category': 'Product',
                'title': product.name,
                'subtitle': f'Price: KSh {product.selling_price} | Stock: {product.stock_quantity}',
                'url': reverse('product_detail', args=[product.id])
            })
    except:
        pass

    # Search Customers
    try:
        customers = Customer.objects.filter(
            Q(first_name__icontains=query) | 
            Q(last_name__icontains=query) |
            Q(phone__icontains=query) |
            Q(email__icontains=query) |
            Q(customer_id__icontains=query)
        )[:5]

        for customer in customers:
            results.append({
                'category': 'Customer',
                'title': f'{customer.first_name} {customer.last_name}',
                'subtitle': f'ID: {customer.customer_id} | Phone: {customer.phone}',
                'url': reverse('customer_detail', args=[customer.customer_id])
            })
    except:
        pass

    # Search Suppliers
    try:
        suppliers = Supplier.objects.filter(
            Q(name__icontains=query) |
            Q(contact_person__icontains=query) |
            Q(phone__icontains=query) |
            Q(email__icontains=query) |
            Q(supplier_id__icontains=query)
        )[:5]

        for supplier in suppliers:
            results.append({
                'category': 'Supplier',
                'title': supplier.name,
                'subtitle': f'ID: {supplier.supplier_id} | Contact: {supplier.contact_person or "N/A"}',
                'url': reverse('view_supplier', args=[supplier.id])
            })
    except:
        pass

    # Search Sales
    try:
        sales = Sale.objects.filter(
            Q(id__icontains=query) |
            Q(customer__first_name__icontains=query) |
            Q(customer__last_name__icontains=query)
        )[:3]

        for sale in sales:
            customer_name = f'{sale.customer.first_name} {sale.customer.last_name}' if sale.customer else 'Walk-in Customer'
            results.append({
                'category': 'Sale',
                'title': f'Sale #{sale.id}',
                'subtitle': f'Customer: {customer_name} | Amount: KSh {sale.total_amount}',
                'url': reverse('sale_detail', args=[sale.id])
            })
    except:
        pass

    # Search Employees
    try:
        employees = Employee.objects.filter(
            Q(first_name__icontains=query) |
            Q(last_name__icontains=query) |
            Q(employee_id__icontains=query) |
            Q(job_title__icontains=query)
        )[:3]

        for employee in employees:
            results.append({
                'category': 'Employee',
                'title': f'{employee.first_name} {employee.last_name}',
                'subtitle': f'ID: {employee.employee_id} | Position: {employee.job_title}',
                'url': reverse('employee_detail', args=[employee.id])
            })
    except:
        pass

    # Search Orders
    try:
        orders = Order.objects.filter(
            Q(order_number__icontains=query) |
            Q(supplier__name__icontains=query)
        )[:3]

        for order in orders:
            results.append({
                'category': 'Order',
                'title': f'Order {order.order_number}',
                'subtitle': f'Supplier: {order.supplier.name} | Total: KSh {order.total_cost}',
                'url': reverse('order_detail', args=[order.id])
            })
    except:
        pass

    return JsonResponse({'results': results})


@login_required(login_url='/auth/login/')
def dashboard_view(request):
    # Get the current date
    today = timezone.now().date()
    expiry_threshold = today + timedelta(days=30)

    # Calculate time periods
    start_of_week = today - timedelta(days=today.weekday())
    start_of_month = today.replace(day=1)
    six_months_ago = today - timedelta(days=6*30)
    two_weeks_ago = today - timedelta(days=14)

    # Sales Overview - Use the same comprehensive approach as sales dashboard
    daily_sales = Sale.objects.filter(sale_date__date=today).aggregate(
        total_sales=Sum('total_amount'),
        cash_sales=Sum('total_amount', filter=Q(payment_method='cash')),
        mpesa_sales=Sum('total_amount', filter=Q(payment_method='mpesa')),
        credit_sales=Sum('total_amount', filter=Q(payment_method='credit')),
        cheque_sales=Sum('total_amount', filter=Q(payment_method='cheque')),
        transaction_count=Count('id')
    )

    weekly_sales = Sale.objects.filter(sale_date__date__gte=start_of_week).aggregate(
        total_sales=Sum('total_amount'),
        cash_sales=Sum('total_amount', filter=Q(payment_method='cash')),
        mpesa_sales=Sum('total_amount', filter=Q(payment_method='mpesa')),
        credit_sales=Sum('total_amount', filter=Q(payment_method='credit')),
        cheque_sales=Sum('total_amount', filter=Q(payment_method='cheque'))
    )

    monthly_sales = Sale.objects.filter(sale_date__date__gte=start_of_month).aggregate(
        total_sales=Sum('total_amount'),
        cash_sales=Sum('total_amount', filter=Q(payment_method='cash')),
        mpesa_sales=Sum('total_amount', filter=Q(payment_method='mpesa')),
        credit_sales=Sum('total_amount', filter=Q(payment_method='credit')),
        cheque_sales=Sum('total_amount', filter=Q(payment_method='cheque'))
    )

    # Overall totals
    total_sales = Sale.objects.aggregate(total=Sum('total_amount'))['total'] or 0
    total_expenses = Expense.objects.aggregate(total=Sum('amount'))['total'] or 0
    profit_loss = total_sales - total_expenses

    # Sales by payment method
    sales_by_payment_method = Sale.objects.values('payment_method').annotate(
        total=Sum('total_amount')
    ).order_by('-total')

    # Orders
    try:
        pending_orders = Order.objects.filter(is_received=False).count()
    except:
        pending_orders = 0

    # Inventory Overview
    try:
        low_stock_count = Product.objects.filter(stock_quantity__lt=F('low_stock_threshold')).count()
        near_expiry_count = Product.objects.filter(expiry_date__lte=expiry_threshold, expiry_date__gte=today).count()
        inventory_value = Product.objects.filter(stock_quantity__gt=0, buying_price__gt=0).aggregate(
            total_value=Sum(F('stock_quantity') * F('buying_price'))
        )['total_value'] or 0
    except:
        low_stock_count = 0
        near_expiry_count = 0
        inventory_value = 0

    # Customer Overview
    try:
        top_customers = Customer.objects.annotate(
            total_spent=Sum('sale__total_amount')
        ).filter(total_spent__gt=0).order_by('-total_spent')[:5]
        customer_growth = Customer.objects.filter(date_added__gte=start_of_month).count()
    except:
        top_customers = []
        customer_growth = 0

    # HR Overview
    try:
        employee_count = Employee.objects.filter(is_active=True).count()
        employee_attendance = Attendance.objects.filter(date=today)
    except:
        employee_count = 0
        employee_attendance = []

    context = {
        'total_sales': total_sales,
        'total_expenses': total_expenses,
        'profit_loss': profit_loss,
        'pending_orders': pending_orders,
        'low_stock_count': low_stock_count,
        'near_expiry_count': near_expiry_count,
        'inventory_value': inventory_value,
        'inventory_report_url': reverse('reports:inventory_report'),
        'daily_sales': daily_sales['total_sales'] or 0,
        'weekly_sales': weekly_sales['total_sales'] or 0,
        'monthly_sales': monthly_sales['total_sales'] or 0,
        'sales_by_payment_method': sales_by_payment_method,
        'top_customers': top_customers,
        'customer_growth': customer_growth,
        'employee_count': employee_count,
        'employee_attendance': employee_attendance,
    }

    return render(request, 'dashboard/dashboard.html', context)
