<?php

namespace App\Livewire\Reports;

use App\Models\Product;
use App\Models\ProductStock;
use App\Models\Location;
use App\Models\Setting;
use Illuminate\Support\Facades\DB;
use Livewire\Component;
use App\Exports\GenericExport;
use Maatwebsite\Excel\Facades\Excel;
use Livewire\WithPagination;

class InventoryReport extends Component
{
    use WithPagination;

    public string $search = '';
    public string $categoryFilter = '';
    public string $branchFilter = '';
    public string $locationFilter = '';
    public string $sortField = 'value';
    public string $sortDirection = 'desc';
    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 = 'desc';
        }
    }

    public function getTotalStockValueProperty()
    {
        $branchId = $this->branchFilter ?: (auth()->user()->branch_id ?? 1);
        return ProductStock::where('branch_id', $branchId)
            ->when($this->locationFilter, fn($q) => $q->where('location_id', $this->locationFilter))
            ->join('products', 'inventory.product_id', '=', 'products.id')
            ->selectRaw('SUM(inventory.quantity * products.cost_price) as total')
            ->value('total') ?? 0;
    }

    public function getTotalRetailValueProperty()
    {
        $branchId = $this->branchFilter ?: (auth()->user()->branch_id ?? 1);
        return ProductStock::where('branch_id', $branchId)
            ->when($this->locationFilter, fn($q) => $q->where('location_id', $this->locationFilter))
            ->join('products', 'inventory.product_id', '=', 'products.id')
            ->selectRaw('SUM(inventory.quantity * products.selling_price) as total')
            ->value('total') ?? 0;
    }

    public function getTotalProductsProperty()
    {
        return Product::active()->count();
    }

    public function getTotalUnitsProperty()
    {
        $branchId = $this->branchFilter ?: (auth()->user()->branch_id ?? 1);
        return ProductStock::where('branch_id', $branchId)
            ->when($this->locationFilter, fn($q) => $q->where('location_id', $this->locationFilter))
            ->sum('quantity');
    }

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

        $query = Product::query()
            ->with(['category', 'stocks' => fn($q) => $q->where('branch_id', $branchId)
                ->when($this->locationFilter, fn($sq) => $sq->where('location_id', $this->locationFilter))])
            ->active()
            ->when($this->search, function ($q) {
                $q->where(function ($sq) {
                    $sq->where('name', 'like', '%' . $this->search . '%')
                       ->orWhere('name_ar', 'like', '%' . $this->search . '%')
                       ->orWhere('sku', 'like', '%' . $this->search . '%');
                });
            })
            ->when($this->categoryFilter, fn($q) => $q->where('category_id', $this->categoryFilter));

        // Custom sorting
        if ($this->sortField === 'value') {
            $query->orderBy(DB::raw('(SELECT SUM(quantity) FROM inventory WHERE inventory.product_id = products.id AND branch_id = ' . $branchId . ') * cost_price'), $this->sortDirection);
        } elseif ($this->sortField === 'quantity') {
            $query->orderBy(DB::raw('(SELECT SUM(quantity) FROM inventory WHERE inventory.product_id = products.id AND branch_id = ' . $branchId . ')'), $this->sortDirection);
        } else {
            $query->orderBy($this->sortField, $this->sortDirection);
        }

        return $query;
    }

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

        return Excel::download(new GenericExport(
            $products,
            ['Product', 'SKU', 'Category', 'Quantity', 'Cost Price', 'Stock Value'],
            function ($product) {
                $qty = $product->stocks->sum('quantity');
                return [
                    $product->localized_name,
                    $product->sku,
                    $product->category?->localized_name ?? '-',
                    $qty,
                    number_format($product->cost_price, 2),
                    number_format($qty * $product->cost_price, 2),
                ];
            },
            'Inventory_Report_' . now()->format('Y-m-d')
        ), 'inventory_report_' . now()->format('YmdHis') . '.xlsx');
    }

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

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

        return view('livewire.reports.inventory', [
            'products' => $products,
            'categories' => $categories,
            'branches' => $branches,
            'locations' => $locations,
            'branchId' => $branchId,
            'totalStockValue' => $this->totalStockValue,
            'totalRetailValue' => $this->totalRetailValue,
            'totalProducts' => $this->totalProducts,
            'totalUnits' => $this->totalUnits,
            'currency' => Setting::get('default_currency', 'EGP'),
        ]);
    }
}
