from django.shortcuts import render, redirect
from django.views import View
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin

from inventory.models import Asset, Stock_Item, Stock_Transaction
from hr_department.models import Team, Vendors
from program_department.models import Projects


def has_perm(user, field_name):
    try:
        return getattr(user.user_type.user_permission, field_name) == 1
    except Exception:
        return False


class InventoryDashboardView(LoginRequiredMixin, View):

    def get(self, request):
        if not (has_perm(request.user, 'inventory_asset_view') or has_perm(request.user, 'inventory_stock_view')):
            messages.error(request, "You don't have permission to view this dashboard.")
            return redirect('userDepartmentView')

        stock_items = Stock_Item.objects.all()
        low_stock_count = sum(1 for item in stock_items if item.is_low_stock)

        return render(request, "inventory-dashboard.html", {
            'total_assets': Asset.objects.count(),
            'assets_issued': Asset.objects.filter(status='Issued').count(),
            'total_stock_items': stock_items.count(),
            'low_stock_count': low_stock_count,
        })


class AssetRegistrationView(LoginRequiredMixin, View):

    def get(self, request):
        vendors = Vendors.objects.all()
        members = Team.objects.all()
        return render(request, "asset-registration.html", {'vendors': vendors, 'members': members})

    def post(self, request):
        if not has_perm(request.user, 'inventory_asset_add'):
            messages.error(request, "You don't have permission to add assets.")
            return redirect('AssetsView')
        asset = Asset()
        asset.asset_name = request.POST.get('asset_name')
        asset.category = request.POST.get('category')
        asset.asset_tag = request.POST.get('asset_tag')
        asset.purchase_date = request.POST.get('purchase_date') or None
        asset.purchase_cost = request.POST.get('purchase_cost')
        asset.vendor_id = request.POST.get('vendor') or None
        asset.condition = request.POST.get('condition')
        asset.status = request.POST.get('status')
        asset.assigned_to_id = request.POST.get('assigned_to') or None
        asset.issue_date = request.POST.get('issue_date') or None
        asset.return_date = request.POST.get('return_date') or None
        asset.warranty_expiry = request.POST.get('warranty_expiry') or None
        asset.notes = request.POST.get('notes')
        if request.FILES.get('photo'):
            asset.photo = request.FILES.get('photo')
        if request.FILES.get('invoice'):
            asset.invoice = request.FILES.get('invoice')
        try:
            asset.save()
        except Exception as e:
            messages.error(request, f"Could not save asset: {e}")
            return redirect('AssetRegistrationView')
        messages.success(request, "Asset registered successfully.")
        return redirect('AssetsView')


class AssetsView(LoginRequiredMixin, View):

    def get(self, request):
        assets = Asset.objects.all()
        if 'status' in request.GET and request.GET['status'] != "All":
            assets = assets.filter(status=request.GET['status'])
            status = request.GET['status']
        else:
            status = 'All'
        if 'category' in request.GET and request.GET['category'] != "All":
            assets = assets.filter(category=request.GET['category'])
            category = request.GET['category']
        else:
            category = 'All'
        return render(request, "assets.html", {'assets': assets, 'status': status, 'category': category})

    def post(self, request):
        if not has_perm(request.user, 'inventory_asset_delete'):
            messages.error(request, "You don't have permission to delete assets.")
            return redirect('AssetsView')
        try:
            asset = Asset.objects.get(id=request.POST.get('id'))
            asset.delete()
            messages.success(request, "Asset deleted successfully.")
        except Asset.DoesNotExist:
            messages.error(request, "Asset doesn't exist.")
        return redirect('AssetsView')


class EditAssetView(LoginRequiredMixin, View):

    def get(self, request, id):
        asset = Asset.objects.get(id=id)
        vendors = Vendors.objects.all()
        members = Team.objects.all()
        return render(request, "edit-asset.html", {'asset': asset, 'vendors': vendors, 'members': members})

    def post(self, request, id):
        if not has_perm(request.user, 'inventory_asset_edit'):
            messages.error(request, "You don't have permission to edit assets.")
            return redirect('AssetsView')
        asset = Asset.objects.get(id=id)
        asset.asset_name = request.POST.get('asset_name')
        asset.category = request.POST.get('category')
        asset.asset_tag = request.POST.get('asset_tag')
        asset.purchase_date = request.POST.get('purchase_date') or None
        asset.purchase_cost = request.POST.get('purchase_cost')
        asset.vendor_id = request.POST.get('vendor') or None
        asset.condition = request.POST.get('condition')
        asset.status = request.POST.get('status')
        asset.assigned_to_id = request.POST.get('assigned_to') or None
        asset.issue_date = request.POST.get('issue_date') or None
        asset.return_date = request.POST.get('return_date') or None
        asset.warranty_expiry = request.POST.get('warranty_expiry') or None
        asset.notes = request.POST.get('notes')
        if request.FILES.get('photo'):
            asset.photo = request.FILES.get('photo')
        if request.FILES.get('invoice'):
            asset.invoice = request.FILES.get('invoice')
        try:
            asset.save()
        except Exception as e:
            messages.error(request, f"Could not save asset: {e}")
            return redirect('EditAssetView', id=id)
        messages.success(request, "Asset updated successfully.")
        return redirect('AssetsView')


class StockItemRegistrationView(LoginRequiredMixin, View):

    def get(self, request):
        return render(request, "stock-item-registration.html")

    def post(self, request):
        if not has_perm(request.user, 'inventory_stock_add'):
            messages.error(request, "You don't have permission to add stock items.")
            return redirect('StockItemsView')
        item = Stock_Item()
        item.item_name = request.POST.get('item_name')
        item.category = request.POST.get('category')
        item.unit = request.POST.get('unit')
        item.reorder_level = request.POST.get('reorder_level') or 0
        item.save()
        messages.success(request, "Stock item created successfully.")
        return redirect('StockItemsView')


class StockItemsView(LoginRequiredMixin, View):

    def get(self, request):
        items = Stock_Item.objects.all()
        if 'category' in request.GET and request.GET['category'] != "All":
            items = items.filter(category=request.GET['category'])
            category = request.GET['category']
        else:
            category = 'All'
        return render(request, "stock-items.html", {'items': items, 'category': category})

    def post(self, request):
        if not has_perm(request.user, 'inventory_stock_delete'):
            messages.error(request, "You don't have permission to delete stock items.")
            return redirect('StockItemsView')
        try:
            item = Stock_Item.objects.get(id=request.POST.get('id'))
            item.delete()
            messages.success(request, "Stock item deleted successfully.")
        except Stock_Item.DoesNotExist:
            messages.error(request, "Stock item doesn't exist.")
        return redirect('StockItemsView')


class EditStockItemView(LoginRequiredMixin, View):

    def get(self, request, id):
        item = Stock_Item.objects.get(id=id)
        return render(request, "edit-stock-item.html", {'item': item})

    def post(self, request, id):
        if not has_perm(request.user, 'inventory_stock_edit'):
            messages.error(request, "You don't have permission to edit stock items.")
            return redirect('StockItemsView')
        item = Stock_Item.objects.get(id=id)
        item.item_name = request.POST.get('item_name')
        item.category = request.POST.get('category')
        item.unit = request.POST.get('unit')
        item.reorder_level = request.POST.get('reorder_level') or 0
        item.save()
        messages.success(request, "Stock item updated successfully.")
        return redirect('StockItemsView')


class StockTransactionView(LoginRequiredMixin, View):

    def get(self, request):
        items = Stock_Item.objects.all()
        vendors = Vendors.objects.all()
        members = Team.objects.all()
        projects = Projects.objects.all()
        return render(request, "stock-transaction.html", {
            'items': items, 'vendors': vendors, 'members': members, 'projects': projects,
        })

    def post(self, request):
        if not has_perm(request.user, 'inventory_stock_add'):
            messages.error(request, "You don't have permission to record stock transactions.")
            return redirect('StockItemsView')
        item_id = request.POST.get('item')
        transaction_type = request.POST.get('transaction_type')
        quantity = request.POST.get('quantity')
        if not item_id or transaction_type not in ('In', 'Out') or not quantity:
            messages.error(request, "Please select an item, type, and quantity.")
            return redirect('StockTransactionView')

        item = Stock_Item.objects.get(id=item_id)
        quantity = int(quantity)
        if transaction_type == 'Out' and quantity > item.current_quantity:
            messages.error(request, f"Cannot issue {quantity} {item.unit} — only {item.current_quantity} {item.unit} in stock.")
            return redirect('StockTransactionView')

        Stock_Transaction.objects.create(
            item=item, transaction_type=transaction_type, quantity=quantity,
            date=request.POST.get('date'), vendor_id=request.POST.get('vendor') or None,
            issued_to_id=request.POST.get('issued_to') or None, project_id=request.POST.get('project') or None,
            notes=request.POST.get('notes'),
        )
        messages.success(request, "Stock transaction recorded successfully.")
        return redirect('StockLedgerView', id=item.id)


class StockLedgerView(LoginRequiredMixin, View):

    def get(self, request, id):
        item = Stock_Item.objects.get(id=id)
        transactions = item.transactions.order_by('date', 'id')
        running = 0
        rows = []
        for t in transactions:
            running += t.quantity if t.transaction_type == 'In' else -t.quantity
            rows.append({'transaction': t, 'balance': running})
        return render(request, "stock-ledger.html", {'item': item, 'rows': rows})
