<?php

namespace App\Livewire\Inventory;

use App\Models\Branch;
use App\Models\Category;
use App\Models\Product;
use App\Models\ProductStock;
use App\Models\Setting;
use Livewire\Component;
use App\Exports\GenericExport;
use Maatwebsite\Excel\Facades\Excel;
use Livewire\WithPagination;

class LowStock extends Component
{
    use WithPagination;

    public string $search = '';
    public string $categoryFilter = '';
    public string $branchFilter = '';
    public string $sortField = 'quantity';
    public string $sortDirection = 'asc';
    public int $perPage = 25;

    public function updatingSearch()
    {
        $this->resetPage();
    }

    public function sortBy(string $field)
    {
        if ($this->sortField === $field) {
            $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
        } else {
            $this->sortField = $field;
            $this->sortDirection = 'asc';
        }
    }

    public function getLowStockCountProperty()
    {
        $branchId = $this->branchFilter ?: (auth()->user()->branch_id ?? 1);
        return ProductStock::where('branch_id', $branchId)
            ->join('products', 'inventory.product_id', '=', 'products.id')
            ->whereColumn('inventory.quantity', '<=', 'products.min_stock_level')
            ->where('products.is_active', true)
            ->count();
    }

    public function getOutOfStockCountProperty()
    {
        $branchId = $this->branchFilter ?: (auth()->user()->branch_id ?? 1);
        return ProductStock::where('branch_id', $branchId)
            ->where('quantity', '<=', 0)
            ->whereHas('product', fn($q) => $q->where('is_active', true))
            ->count();
    }

    protected function getFilteredQuery($branchId)
    {
        $query = ProductStock::query()
            ->with(['product.category', 'branch'])
            ->where('branch_id', $branchId)
            ->whereHas('product', fn($q) => $q->where('is_active', true))
            ->join('products', 'inventory.product_id', '=', 'products.id')
            ->whereColumn('inventory.quantity', '<=', 'products.min_stock_level')
            ->select('inventory.*');

        if ($this->search) {
            $query->where(function ($q) {
                $q->where('products.name', 'like', '%' . $this->search . '%')
                  ->orWhere('products.name_ar', 'like', '%' . $this->search . '%')
                  ->orWhere('products.sku', 'like', '%' . $this->search . '%');
            });
        }

        if ($this->categoryFilter) {
            $query->where('products.category_id', $this->categoryFilter);
        }

        return $query;
    }

    public function export()
    {
        $branchId = $this->branchFilter ?: (auth()->user()->branch_id ?? 1);
        $query = $this->getFilteredQuery($branchId);

        // Sorting
        if ($this->sortField === 'name') {
            $query->orderBy('products.name', $this->sortDirection);
        } elseif ($this->sortField === 'quantity') {
            $query->orderBy('inventory.quantity', $this->sortDirection);
        } elseif ($this->sortField === 'min_stock') {
            $query->orderBy('products.min_stock_level', $this->sortDirection);
        } else {
            $query->orderBy('inventory.' . $this->sortField, $this->sortDirection);
        }

        $items = $query->get();

        return Excel::download(new GenericExport(
            $items,
            ['Product', 'SKU', 'Category', 'Stock Level', 'Min Level', 'Needed'],
            function ($item) {
                return [
                    $item->product->localized_name,
                    $item->product->sku,
                    $item->product->category?->localized_name ?? '-',
                    $item->quantity,
                    $item->product->min_stock_level,
                    max(0, $item->product->min_stock_level - $item->quantity),
                ];
            },
            'Low_Stock_Alerts_' . now()->format('Y-m-d')
        ), 'low_stock_' . now()->format('YmdHis') . '.xlsx');
    }

    public function render()
    {
        $branchId = $this->branchFilter ?: (auth()->user()->branch_id ?? 1);

        $query = $this->getFilteredQuery($branchId);

        // Sorting
        if ($this->sortField === 'name') {
            $query->orderBy('products.name', $this->sortDirection);
        } elseif ($this->sortField === 'quantity') {
            $query->orderBy('inventory.quantity', $this->sortDirection);
        } elseif ($this->sortField === 'min_stock') {
            $query->orderBy('products.min_stock_level', $this->sortDirection);
        } else {
            $query->orderBy('inventory.' . $this->sortField, $this->sortDirection);
        }

        $items = $query->paginate($this->perPage);

        $categories = Category::active()->orderBy('name')->get();
        $branches = Branch::active()->get();

        return view('livewire.inventory.low-stock', [
            'items' => $items,
            'categories' => $categories,
            'branches' => $branches,
            'branchId' => $branchId,
            'currency' => Setting::get('default_currency', 'EGP'),
        ]);
    }
}
