<?php

namespace App\Livewire\Inventory;

use App\Models\Branch;
use App\Models\Category;
use App\Models\Location;
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 StockOverview extends Component
{
    use WithPagination;

    public string $search = '';
    public string $categoryFilter = '';
    public string $stockFilter = ''; // all, low, out
    public string $typeFilter = ''; // all, physical, service
    public string $branchFilter = '';
    public string $locationFilter = '';
    public string $sortField = 'name';
    public string $sortDirection = 'asc';
    public int $perPage = 25;

    protected $queryString = [
        'search' => ['except' => ''],
        'categoryFilter' => ['except' => ''],
        'stockFilter' => ['except' => ''],
        'typeFilter' => ['except' => ''],
        'locationFilter' => ['except' => ''],
    ];

    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 getTotalProductsProperty()
    {
        return Product::active()->count();
    }

    public function getTotalStockValueProperty()
    {
        $branchId = $this->branchFilter ?: (auth()->user()->branch_id ?? 1);
        $query = ProductStock::where('branch_id', $branchId)
            ->join('products', 'inventory.product_id', '=', 'products.id');

        if ($this->locationFilter) {
            $query->where('inventory.location_id', $this->locationFilter);
        }

        return $query->selectRaw('SUM(inventory.quantity * products.cost_price) as total')
            ->value('total') ?? 0;
    }

    public function getLowStockCountProperty()
    {
        $branchId = $this->branchFilter ?: (auth()->user()->branch_id ?? 1);
        return Product::active()
            ->whereHas('stocks', function ($q) use ($branchId) {
                $q->where('branch_id', $branchId)
                  ->whereColumn('quantity', '<=', 'products.min_stock_level');
                if ($this->locationFilter) {
                    $q->where('location_id', $this->locationFilter);
                }
            })
            ->count();
    }

    public function getOutOfStockCountProperty()
    {
        $branchId = $this->branchFilter ?: (auth()->user()->branch_id ?? 1);
        return Product::active()
            ->whereHas('stocks', function ($q) use ($branchId) {
                $q->where('branch_id', $branchId)
                  ->where('quantity', '<=', 0);
                if ($this->locationFilter) {
                    $q->where('location_id', $this->locationFilter);
                }
            })
            ->count();
    }

    protected function getFilteredQuery($branchId)
    {
        return Product::query()
            ->with(['category', 'stocks' => function ($q) use ($branchId) {
                $q->where('branch_id', $branchId)
                  ->when($this->locationFilter, fn($sq) => $sq->where('location_id', $this->locationFilter));
            }])
            ->active()
            ->when($this->search, function ($query) {
                $query->where(function ($q) {
                    $q->where('name', 'like', '%' . $this->search . '%')
                      ->orWhere('name_ar', 'like', '%' . $this->search . '%')
                      ->orWhere('sku', 'like', '%' . $this->search . '%')
                      ->orWhere('barcode', 'like', '%' . $this->search . '%');
                });
            })
            ->when($this->categoryFilter, fn($q) => $q->where('category_id', $this->categoryFilter))
            ->when($this->stockFilter === 'low', function ($q) use ($branchId) {
                $q->whereHas('stocks', function ($sq) use ($branchId) {
                    $sq->where('branch_id', $branchId)
                       ->whereColumn('quantity', '<=', 'products.min_stock_level')
                       ->where('quantity', '>', 0);
                    if ($this->locationFilter) {
                        $sq->where('location_id', $this->locationFilter);
                    }
                });
            })
            ->when($this->stockFilter === 'out', function ($q) use ($branchId) {
                $q->whereHas('stocks', function ($sq) use ($branchId) {
                    $sq->where('branch_id', $branchId)
                       ->where('quantity', '<=', 0);
                    if ($this->locationFilter) {
                        $sq->where('location_id', $this->locationFilter);
                    }
                });
            })
            ->when($this->typeFilter !== '', function ($q) {
                 if ($this->typeFilter === 'service') {
                     $q->where('is_service', true);
                 } else {
                     $q->where('is_service', false);
                 }
            });
    }

    public function export()
    {
        $branchId = $this->branchFilter ?: (auth()->user()->branch_id ?? 1);
        $products = $this->getFilteredQuery($branchId)
            ->orderBy($this->sortField, $this->sortDirection)
            ->get();

        return Excel::download(new GenericExport(
            $products,
            ['Product Name', 'SKU', 'Category', 'Current Stock', 'Min Stock', 'Value'],
            function ($product) {
                $stock = $product->stocks->sum('quantity');
                return [
                    $product->localized_name,
                    $product->sku,
                    $product->category?->localized_name ?? '-',
                    $stock,
                    $product->min_stock_level,
                    number_format($stock * $product->cost_price, 2),
                ];
            },
            'Stock_Overview_' . now()->format('Y-m-d')
        ), 'inventory_' . now()->format('YmdHis') . '.xlsx');
    }

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

        $products = $this->getFilteredQuery($branchId)
            ->orderBy($this->sortField, $this->sortDirection)
            ->paginate($this->perPage);

        $categories = Category::active()->orderBy('name')->get();
        $branches = Branch::active()->get();
        $locations = Location::where('branch_id', $branchId)->active()->orderBy('sort_order')->get();

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