from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.core.paginator import Paginator
from .models import Product, ProductCategory, InventoryTransaction
from .forms import ProductForm, ProductCategoryForm
from django.core.exceptions import PermissionDenied
from core.utils import check_limit_or_block
from accounts.decorators import role_required

def dashboard(request):
    return render(request, 'inventory/dashboard.html')

@login_required
def inventory_dashboard(request):
    # Get statistics
    total_products = Product.objects.count()
    total_stock = Product.objects.aggregate(total=Sum('stock_quantity'))['total'] or 0
    low_stock_count = Product.objects.filter(stock_status='low_stock').count()
    out_of_stock_count = Product.objects.filter(stock_status='out_of_stock').count()
    
    # Get recent products
    recent_products = Product.objects.order_by('-created_at')[:5]
    
    # Separate low stock and out-of-stock products
    low_stock_products = Product.objects.filter(stock_status='low_stock')[:5]
    out_of_stock_products = Product.objects.filter(stock_status='out_of_stock')[:5]
    
    context = {
        'total_products': total_products,
        'total_stock': total_stock,
        'low_stock_count': low_stock_count,
        'out_of_stock_count': out_of_stock_count,
        'recent_products': recent_products,
        'low_stock_products': low_stock_products,
        'out_of_stock_products': out_of_stock_products,  # Added this line
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'inventory/dashboard.html', context)

@login_required
def product_list(request):
    query = request.GET.get('q', '')
    category_id = request.GET.get('category', '')
    status = request.GET.get('status', '')
    stock_status = request.GET.get('stock_status', '')
    
    products = Product.objects.select_related('category').all()
    
    if query:
        products = products.filter(
            Q(name__icontains=query) | 
            Q(sku__icontains=query) | 
            Q(barcode__icontains=query)
        )
    
    if category_id:
        products = products.filter(category_id=category_id)
    
    if status:
        products = products.filter(status=status)
    
    if stock_status:
        products = products.filter(stock_status=stock_status)
    
    # Pagination
    paginator = Paginator(products, 20)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    categories = ProductCategory.objects.all()
    
    context = {
        'page_obj': page_obj,
        'categories': categories,
        'query': query,
        'selected_category': category_id,
        'selected_status': status,
        'selected_stock_status': stock_status,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'inventory/product_list.html', context)


# inventory/views.py (complete add and edit functions)
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db.models import Q, F, Sum
from django.core.paginator import Paginator
from .models import Product, ProductCategory, InventoryTransaction, StockAdjustment
from .forms import ProductForm, ProductCategoryForm
@login_required
def add_product(request):
    """
    Add a new product to inventory, respecting plan limits.
    """
    # Check limit before even showing the form
    try:
        check_limit_or_block("products")
    except PermissionDenied as e:
        messages.error(request, str(e))
        return redirect('inventory:product_list')

    if request.method == 'POST':
        form = ProductForm(request.POST, request.FILES)
        if form.is_valid():
            try:
                # Check again in case another user added product in between
                check_limit_or_block("products")

                # Save the product
                product = form.save()

                # Create initial stock transaction if quantity > 0
                if product.stock_quantity > 0:
                    InventoryTransaction.objects.create(
                        product=product,
                        transaction_type='in',
                        quantity=product.stock_quantity,
                        reference=f'Initial stock for {product.name}',
                        created_by=request.user.username
                    )

                messages.success(request, f'Product "{product.name}" added successfully!')
                return redirect('inventory:product_list')
            except PermissionDenied as e:
                messages.error(request, str(e))
                return redirect('inventory:product_list')
            except Exception as e:
                messages.error(request, f'Error adding product: {str(e)}')
        else:
            messages.error(request, 'Please correct the errors below.')
    else:
        form = ProductForm()

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



@login_required
def edit_product(request, product_id):
    """
    Edit an existing product
    """
    product = get_object_or_404(Product, id=product_id)
    
    if request.method == 'POST':
        form = ProductForm(request.POST, request.FILES, instance=product)
        if form.is_valid():
            try:
                # Get old stock quantity before save
                old_stock = product.stock_quantity
                
                # Save the updated product
                updated_product = form.save()
                
                # If stock quantity changed, create adjustment transaction
                new_stock = updated_product.stock_quantity
                if old_stock != new_stock:
                    diff = new_stock - old_stock
                    transaction_type = 'in' if diff > 0 else 'out'
                    quantity = abs(diff)
                    
                    InventoryTransaction.objects.create(
                        product=updated_product,
                        transaction_type=transaction_type,
                        quantity=quantity,
                        reference=f'Stock adjustment for {updated_product.name}',
                        created_by=request.user.username
                    )
                
                messages.success(request, f'Product "{updated_product.name}" updated successfully!')
                return redirect('inventory:product_detail', product_id=updated_product.id)
            except Exception as e:
                messages.error(request, f'Error updating product: {str(e)}')
        else:
            messages.error(request, 'Please correct the errors below.')
    else:
        form = ProductForm(instance=product)
    
    context = {
        'form': form,
        'product': product,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'inventory/edit_product.html', context)



@login_required
def product_detail(request, product_id):
    """
    View product details with transactions and adjustments
    """
    product = get_object_or_404(Product, id=product_id)
    transactions = InventoryTransaction.objects.filter(product=product).order_by('-created_at')[:10]
    adjustments = StockAdjustment.objects.filter(product=product).order_by('-created_at')[:10]
    
    context = {
        'product': product,
        'transactions': transactions,
        'adjustments': adjustments,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'inventory/product_detail.html', context)


@login_required
def product_category_list(request):
    categories = ProductCategory.objects.all()
    
    context = {
        'categories': categories,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'inventory/category_list.html', context)

@login_required
def add_category(request):
    """
    Add a new product category, respecting plan limits.
    """
    try:
        check_limit_or_block("categories")
    except PermissionDenied as e:
        messages.error(request, str(e))
        return redirect('inventory:category_list')

    if request.method == 'POST':
        form = ProductCategoryForm(request.POST)
        if form.is_valid():
            try:
                # Check again in case someone else added a category
                check_limit_or_block("categories")
                category = form.save()
                messages.success(request, f'Category "{category.name}" created successfully!')
                return redirect('inventory:category_list')
            except PermissionDenied as e:
                messages.error(request, str(e))
                return redirect('inventory:category_list')
            except Exception as e:
                messages.error(request, f'Error creating category: {str(e)}')
        else:
            messages.error(request, 'Please correct the errors below.')
    else:
        form = ProductCategoryForm()

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

@login_required
def adjust_stock(request, product_id):
    product = get_object_or_404(Product, id=product_id)
    
    if request.method == 'POST':
        quantity = int(request.POST.get('quantity', 0))
        transaction_type = request.POST.get('transaction_type', 'adjustment')
        notes = request.POST.get('notes', '')
        
        # Update stock
        if transaction_type == 'in':
            product.stock_quantity += quantity
        elif transaction_type == 'out':
            product.stock_quantity -= quantity
        else:  # adjustment
            product.stock_quantity = quantity
        
        product.save()
        
        # Create transaction record
        InventoryTransaction.objects.create(
            product=product,
            transaction_type=transaction_type,
            quantity=quantity,
            notes=notes,
            created_by=request.user.username
        )
        
        messages.success(request, f'Stock adjusted for {product.name}')
        return redirect('inventory:product_detail', product_id=product.id)
    
    context = {
        'product': product,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'inventory/adjust_stock.html', context)


# inventory/views.py (add to existing views)
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db.models import Q, F, Sum
from django.core.paginator import Paginator
from .models import Product, ProductCategory, InventoryTransaction, StockAdjustment
from .forms import ProductForm, ProductCategoryForm

@login_required
def restock_product(request, product_id):
    product = get_object_or_404(Product, id=product_id)
    
    if request.method == 'POST':
        quantity = int(request.POST.get('quantity', 0))
        reason = request.POST.get('reason', '')
        reference = request.POST.get('reference_number', '')
        
        if quantity <= 0:
            messages.error(request, 'Quantity must be greater than 0')
            return redirect('inventory:restock_product', product_id=product.id)
        
        # Create stock adjustment record
        StockAdjustment.objects.create(
            product=product,
            adjustment_type='restock',
            quantity=quantity,
            reason=reason,
            reference_number=reference,
            performed_by=request.user.username
        )
        
        messages.success(request, f'Successfully restocked {quantity} units of {product.name}')
        return redirect('inventory:product_detail', product_id=product.id)
    
    context = {
        'product': product,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'inventory/restock_product.html', context)

@login_required
def reduce_stock(request, product_id):
    product = get_object_or_404(Product, id=product_id)
    
    if request.method == 'POST':
        quantity = int(request.POST.get('quantity', 0))
        reason = request.POST.get('reason', '')
        reference = request.POST.get('reference_number', '')
        
        if quantity <= 0:
            messages.error(request, 'Quantity must be greater than 0')
            return redirect('inventory:reduce_stock', product_id=product.id)
        
        if quantity > product.stock_quantity:
            messages.error(request, f'Cannot reduce stock by {quantity}. Current stock is {product.stock_quantity}')
            return redirect('inventory:reduce_stock', product_id=product.id)
        
        # Create stock adjustment record
        StockAdjustment.objects.create(
            product=product,
            adjustment_type='reduce',
            quantity=quantity,
            reason=reason,
            reference_number=reference,
            performed_by=request.user.username
        )
        
        messages.success(request, f'Successfully reduced {quantity} units of {product.name}')
        return redirect('inventory:product_detail', product_id=product.id)
    
    context = {
        'product': product,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'inventory/reduce_stock.html', context)

@login_required
def stock_adjustment_history(request):
    adjustments = StockAdjustment.objects.select_related('product').all().order_by('-created_at')
    
    # Filtering
    product_id = request.GET.get('product', '')
    adjustment_type = request.GET.get('type', '')
    
    if product_id:
        adjustments = adjustments.filter(product_id=product_id)
    
    if adjustment_type:
        adjustments = adjustments.filter(adjustment_type=adjustment_type)
    
    # Pagination
    paginator = Paginator(adjustments, 25)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    products = Product.objects.all()
    
    context = {
        'page_obj': page_obj,
        'products': products,
        'selected_product': product_id,
        'selected_type': adjustment_type,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'inventory/stock_adjustment_history.html', context)

@login_required
def product_detail(request, product_id):
    product = get_object_or_404(Product, id=product_id)
    transactions = InventoryTransaction.objects.filter(product=product).order_by('-created_at')[:10]
    adjustments = StockAdjustment.objects.filter(product=product).order_by('-created_at')[:10]
    
    context = {
        'product': product,
        'transactions': transactions,
        'adjustments': adjustments,
        'user_role': request.user.role,
        'user_name': request.user.get_full_name() or request.user.username,
    }
    return render(request, 'inventory/product_detail.html', context)


from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.core.paginator import Paginator

import csv
import io

from .models import Product, ProductCategory, InventoryTransaction, StockAdjustment
from .forms import ProductForm, ProductCategoryForm

import datetime
from django.http import HttpResponse


import csv
import io
from decimal import Decimal, InvalidOperation

from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required

from .models import ProductCategory, Product, InventoryTransaction


@login_required
def product_bulk_import(request):
    """Bulk import products from a CSV file."""
    if request.method == "POST":
        upload = request.FILES.get("file")
        if not upload:
            messages.error(request, "Please choose a CSV file to upload.")
            return redirect("inventory:product_bulk_import")

        if not upload.name.lower().endswith(".csv"):
            messages.error(request, "Only CSV files (.csv) are supported.")
            return redirect("inventory:product_bulk_import")

        try:
            data = upload.read().decode("utf-8")
        except UnicodeDecodeError:
            messages.error(request, "Unable to read file. Please use UTF-8 encoded CSV.")
            return redirect("inventory:product_bulk_import")

        f = io.StringIO(data)
        reader = csv.DictReader(f)

        created_count = 0
        updated_count = 0
        errors = []

        for index, row in enumerate(reader, start=2):
            try:
                # Extract and validate required fields
                name = (row.get("name") or "").strip()
                sku = (row.get("sku") or "").strip()
                category_name = (row.get("category") or "").strip()
                cost_price = row.get("cost_price", "").strip()
                stock_quantity = row.get("stock_quantity", "").strip()
                minimum_stock = row.get("minimum_stock", "").strip()
                description = (row.get("description") or "").strip()

                if not name:
                    raise ValueError("Missing product name.")

                # Validate SKU uniqueness
                if not sku:
                    raise ValueError("Missing SKU.")

                # Validate category
                category = None
                if category_name:
                    category, _ = ProductCategory.objects.get_or_create(name=category_name)

                # Convert numeric values
                def to_decimal(value, default=Decimal("0.00")):
                    value = value.strip() if value else ""
                    if not value:
                        return default
                    try:
                        return Decimal(value)
                    except InvalidOperation:
                        raise ValueError(f"Invalid decimal value: {value}")

                def to_int(value, default=0):
                    value = value.strip() if value else ""
                    if not value:
                        return default
                    try:
                        return int(float(value))
                    except ValueError:
                        raise ValueError(f"Invalid integer value: {value}")

                cost_price = to_decimal(cost_price)
                stock_quantity = to_int(stock_quantity)
                minimum_stock = to_int(minimum_stock)

                # Lookup product by SKU
                product, created = Product.objects.get_or_create(
                    sku=sku,
                    defaults={
                        "name": name,
                        "category": category,
                        "cost_price": cost_price,
                        "stock_quantity": stock_quantity,
                        "minimum_stock": minimum_stock,
                        "description": description,
                        "price": cost_price,  # Default price = cost price
                    },
                )

                if not created:
                    # Update existing product
                    product.name = name
                    if category:
                        product.category = category
                    product.cost_price = cost_price
                    product.stock_quantity += stock_quantity  # Add to existing stock
                    product.minimum_stock = minimum_stock
                    product.description = description
                    product.save()
                    updated_count += 1
                else:
                    created_count += 1
                    if stock_quantity > 0:
                        InventoryTransaction.objects.create(
                            product=product,
                            transaction_type="in",
                            quantity=stock_quantity,
                            reference=f"Bulk import initial stock for {product.name}",
                            notes="Initial stock from CSV import",
                            created_by=request.user.username,
                        )

            except Exception as e:
                errors.append(f"Row {index}: {e}")

        msg = f"Bulk import completed. Created: {created_count}, Updated: {updated_count}."
        if errors:
            msg += f" {len(errors)} rows had errors."
        messages.success(request, msg)
        if errors:
            preview = " | ".join(errors[:3])
            messages.warning(request, f"Some rows could not be imported: {preview}")

        return redirect("inventory:product_list")

    context = {
        "user_role": getattr(request.user, "role", None),
        "user_name": request.user.get_full_name() or request.user.username,
    }
    return render(request, "inventory/product_bulk_import.html", context)
    

@login_required
def product_import_template(request):
    """Download a CSV template for bulk product import."""
    response = HttpResponse(content_type="text/csv")
    response["Content-Disposition"] = 'attachment; filename="product_import_template.csv"'

    writer = csv.writer(response)
    writer.writerow(
        ["name", "sku", "category", "cost_price", "stock_quantity", "minimum_stock", "description"]
    )
    writer.writerow(
        ["Coca Cola 50cl", "CC50", "Drinks", "500", "150", "24", "Yayi"]
    )
    writer.writerow(
        ["Coca Cola 30cl", "CC30", "Drinks", "350", "150", "24", "Okay"]
    )
    return response


@login_required
def product_bulk_export(request):
    """Export all products as CSV."""
    response = HttpResponse(content_type="text/csv")
    filename = f"products_{datetime.date.today().isoformat()}.csv"
    response["Content-Disposition"] = f'attachment; filename="{filename}"'

    writer = csv.writer(response)
    writer.writerow(
        [
            "id",
            "name",
            "sku",
            "category",
            "cost_price",
            # "selling_price",
            "stock_quantity",
            "minimum_stock",
            "status",
            "stock_status",
            "created_at",
            "updated_at",
        ]
    )

    products = Product.objects.select_related("category").all().order_by("name")
    for p in products:
        writer.writerow(
            [
                p.id,
                p.name,
                p.sku or "",
                p.category.name if p.category else "",
                p.cost_price,
                # p.selling_price,
                p.stock_quantity,
                p.minimum_stock,
                p.status,
                p.stock_status,
                p.created_at,
                p.updated_at,
            ]
        )

    return response


@login_required
def category_bulk_export(request):
    """Export all product categories as CSV."""
    response = HttpResponse(content_type="text/csv")
    filename = f"categories_{datetime.date.today().isoformat()}.csv"
    response["Content-Disposition"] = f'attachment; filename="{filename}"'

    writer = csv.writer(response)
    writer.writerow(["id", "name", "description", "color_code", "icon", "created_at", "updated_at"])

    for c in ProductCategory.objects.all().order_by("name"):
        writer.writerow(
            [c.id, c.name, c.description, c.color_code, c.icon, c.created_at, c.updated_at]
        )

    return response


@login_required
def inventory_transactions_export(request):
    """Export all inventory transactions as CSV."""
    response = HttpResponse(content_type="text/csv")
    filename = f"inventory_transactions_{datetime.date.today().isoformat()}.csv"
    response["Content-Disposition"] = f'attachment; filename="{filename}"'

    writer = csv.writer(response)
    writer.writerow(
        [
            "id",
            "product_name",
            "product_sku",
            "transaction_type",
            "quantity",
            "reference",
            "notes",
            "created_by",
            "created_at",
        ]
    )

    txns = InventoryTransaction.objects.select_related("product").all().order_by("-created_at")
    for t in txns:
        writer.writerow(
            [
                t.id,
                t.product.name if t.product else "",
                t.product.sku if t.product else "",
                t.transaction_type,
                t.quantity,
                t.reference,
                t.notes,
                t.created_by,
                t.created_at,
            ]
        )

    return response


@login_required
def stock_adjustments_export(request):
    """Export all stock adjustments as CSV."""
    response = HttpResponse(content_type="text/csv")
    filename = f"stock_adjustments_{datetime.date.today().isoformat()}.csv"
    response["Content-Disposition"] = f'attachment; filename="{filename}"'

    writer = csv.writer(response)
    writer.writerow(
        [
            "id",
            "product_name",
            "product_sku",
            "adjustment_type",
            "quantity",
            "reason",
            "reference_number",
            "performed_by",
            "created_at",
        ]
    )

    adjustments = StockAdjustment.objects.select_related("product").all().order_by("-created_at")
    for adj in adjustments:
        writer.writerow(
            [
                adj.id,
                adj.product.name if adj.product else "",
                adj.product.sku if adj.product else "",
                adj.adjustment_type,
                adj.quantity,
                adj.reason,
                adj.reference_number,
                adj.performed_by,
                adj.created_at,
            ]
        )

    return response


@login_required
def export_center(request):
    """Central page where user can export inventory & sales data."""
    context = {
        "user_role": getattr(request.user, "role", None),
        "user_name": request.user.get_full_name() or request.user.username,
    }
    return render(request, "inventory/export_center.html", context)


from .models import Product, ProductCategory, InventoryTransaction, Supplier, PurchaseOrder, PurchaseOrderItem, SupplierPayment
from .forms import ProductForm, ProductCategoryForm, SupplierForm, PurchaseOrderForm, PurchaseOrderItemForm
from django.forms import inlineformset_factory
from django.utils import timezone
from decimal import Decimal

# -----------------------------------
# SUPPLIERS

@login_required
@role_required('admin')
def supplier_list(request):
    # Fetch all suppliers
    suppliers = Supplier.objects.all().order_by("name")

    return render(request, "inventory/supplier_list.html", {
        "suppliers": suppliers,
        "user_role": request.user.role,
        "user_name": request.user.get_full_name() or request.user.username,
    })





@login_required
@role_required('admin')
def supplier_create(request):
    if request.method == "POST":
        form = SupplierForm(request.POST)
        if form.is_valid():
            supplier = form.save()
            messages.success(request, f'Supplier "{supplier.name}" added.')
            return redirect("inventory:supplier_list")
    else:
        form = SupplierForm()

    return render(request, "inventory/supplier_form.html", {"form": form, "mode": "create"})


@login_required
@role_required('admin')
def supplier_detail(request, supplier_id):
    supplier = get_object_or_404(Supplier, id=supplier_id)

    # All purchase orders for this supplier
    purchase_orders = supplier.purchase_orders.all().order_by("-created_at")

    return render(request, "inventory/supplier_detail.html", {
        "supplier": supplier,
        "purchase_orders": purchase_orders,
        "user_role": request.user.role,
        "user_name": request.user.get_full_name() or request.user.username,
    })


@login_required
@role_required('admin')
def supplier_record_payment(request, supplier_id):
    supplier = get_object_or_404(Supplier, id=supplier_id)

    if request.method == "POST":
        amount = request.POST.get("amount")
        notes = request.POST.get("notes", "")

        SupplierPayment.objects.create(
            supplier=supplier,
            amount=Decimal(amount),
            notes=notes
        )

        messages.success(request, "Supplier payment recorded successfully.")
        return redirect("inventory:supplier_detail", supplier_id=supplier.id)

    return render(request, "inventory/supplier_record_payment.html", {
        "supplier": supplier,
        "user_role": request.user.role,
        "user_name": request.user.get_full_name() or request.user.username,
    })



# -----------------------------------
# PURCHASE ORDERS
# -----------------------------------

@login_required
@role_required('admin')
def purchase_order_list(request):
    orders = PurchaseOrder.objects.select_related("supplier").order_by("-date_ordered", "-id")
    return render(request, "inventory/purchase_order_list.html", {"orders": orders})


from .forms import PurchaseOrderForm, PurchaseOrderItemFormSet

@login_required
@role_required('admin')
def purchase_order_create(request, supplier_id=None):
    supplier = None

    if supplier_id:
        supplier = get_object_or_404(Supplier, id=supplier_id)

    if request.method == "POST":
        form = PurchaseOrderForm(request.POST)
        formset = PurchaseOrderItemFormSet(request.POST)

        if form.is_valid() and formset.is_valid():
            po = form.save(commit=False)

            # IF creating from supplier page, lock supplier field
            if supplier:
                po.supplier = supplier

            po.save()

            formset.instance = po
            formset.save()

            messages.success(request, "Purchase order created successfully.")
            return redirect("inventory:purchase_order_detail", po.id)

    else:
        if supplier:
            form = PurchaseOrderForm(initial={"supplier": supplier})
        else:
            form = PurchaseOrderForm()

        formset = PurchaseOrderItemFormSet()

    return render(request, "inventory/purchase_order_form.html", {
        "form": form,
        "formset": formset,
        "mode": "create",
        "supplier": supplier,
        "user_role": request.user.role,
        "user_name": request.user.get_full_name() or request.user.username,
    })


@login_required
@role_required('admin')
def purchase_order_detail(request, order_id):
    po = get_object_or_404(PurchaseOrder, id=order_id)
    return render(
        request,
        "inventory/purchase_order_detail.html",
        {"order": po},
    )


# @login_required
# def purchase_order_mark_received(request, order_id):
#     po = get_object_or_404(PurchaseOrder, id=order_id)
#     if po.is_received:
#         messages.info(request, "This purchase order is already marked as received.")
#         return redirect("inventory:purchase_order_detail", order_id=po.id)

#     if request.method == "POST":
#         po.status = "received"
#         if not po.date_received:
#             po.date_received = timezone.now().date()
#         po.save()

#         _apply_purchase_order_receipt(po, request.user.username)
#         messages.success(request, "Purchase order marked as received and stock updated.")
#         return redirect("inventory:purchase_order_detail", order_id=po.id)

#     return render(
#         request,
#         "inventory/purchase_order_confirm_receive.html",
#         {"order": po},
#     )

@role_required('admin')
def _apply_purchase_order_receipt(po: PurchaseOrder, username: str):
    """
    Apply stock increases and cost_price updates when PO is received.
    - Increase product.stock_quantity
    - Update product.cost_price to latest unit_cost
    - Log InventoryTransaction or StockAdjustment
    """
    for item in po.items.select_related("product"):
        product = item.product
        qty = item.quantity or 0
        if qty <= 0:
            continue

        # Update stock quantity
        product.stock_quantity = (product.stock_quantity or 0) + qty

        # Update cost_price to latest purchase cost (simple strategy)
        product.cost_price = item.unit_cost
        product.save()

        # Log inventory transaction
        InventoryTransaction.objects.create(
            product=product,
            transaction_type="in",
            quantity=qty,
            reference=f"PO #{po.id}",
            notes=f"Purchase order received from {po.supplier.name}",
            created_by=username,
        )


@login_required
@role_required('admin')
def purchase_order_mark_received(request, order_id):
    order = get_object_or_404(PurchaseOrder, id=order_id)

    if request.method == "POST":
        order.mark_as_received()
        messages.success(request, "Purchase order marked as received, stock updated, supplier balance updated.")
        return redirect("inventory:purchase_order_detail", order_id=order_id)

    return render(request, "inventory/purchase_order_confirm_receive.html", {
        "order": order
    })

