<?php

namespace App\Livewire\Sales;

use App\Models\SaleReturn;
use App\Models\Setting;
use Livewire\Component;
use App\Exports\GenericExport;
use Maatwebsite\Excel\Facades\Excel;
use Livewire\WithPagination;

class SalesReturnsIndex extends Component
{
    use WithPagination;

    protected $paginationTheme = 'bootstrap';

    public string $search = '';
    public string $dateFrom = '';
    public string $dateTo = '';
    public string $sortField = 'created_at';
    public string $sortDirection = 'desc';
    public int $perPage = 15;

    public bool $showDetailsModal = false;
    public ?SaleReturn $selectedReturn = null;

    public array $selectedRows = [];
    public bool $selectAll = false;

    public function updatedSelectAll($value)
    {
        if ($value) {
            $this->selectedRows = $this->getFilteredQuery()->pluck('id')->map(fn($id) => (string)$id)->toArray();
        } else {
            $this->selectedRows = [];
        }
    }

    protected $queryString = [
        'search' => ['except' => ''],
        'dateFrom' => ['except' => ''],
        'dateTo' => ['except' => ''],
    ];

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

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

    public function updatedDateTo()
    {
        $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 viewDetails(int $returnId)
    {
        $this->selectedReturn = SaleReturn::with([
            'sale.customer', 
            'items.product',
            'user',
            'branch'
        ])->findOrFail($returnId);
        $this->showDetailsModal = true;
    }

    public function closeDetails()
    {
        $this->showDetailsModal = false;
        $this->selectedReturn = null;
    }

    protected function getFilteredQuery()
    {
        return SaleReturn::query()
            ->with(['sale.customer', 'user'])
            ->when($this->search, function ($query) {
                $query->where(function ($q) {
                    $q->where('return_number', 'like', '%' . $this->search . '%')
                      ->orWhereHas('sale', function ($sq) {
                          $sq->where('sale_number', 'like', '%' . $this->search . '%')
                             ->orWhereHas('customer', function ($cq) {
                                 $cq->where('name', 'like', '%' . $this->search . '%');
                             });
                      });
                });
            })
            ->when($this->dateFrom, fn($q) => $q->whereDate('created_at', '>=', $this->dateFrom))
            ->when($this->dateTo, fn($q) => $q->whereDate('created_at', '<=', $this->dateTo));
    }

    public function export()
    {
        $query = !empty($this->selectedRows)
            ? SaleReturn::query()->whereIn('id', $this->selectedRows)
            : $this->getFilteredQuery();

        $returns = $query->with(['sale.customer', 'user'])
            ->orderBy($this->sortField, $this->sortDirection)
            ->get();

        return Excel::download(new GenericExport(
            $returns,
            ['Date', 'Return #', 'Invoice #', 'Customer', 'Total', 'Reason'],
            function ($return) {
                return [
                    $return->created_at->format('Y-m-d H:i'),
                    $return->return_number,
                    $return->sale?->sale_number ?? '-',
                    $return->sale?->customer?->name ?? 'Walk-in',
                    number_format($return->total, 2),
                    $return->reason ?? '-',
                ];
            },
            'Sales_Returns_' . now()->format('Y-m-d')
        ), 'sales_returns_' . now()->format('YmdHis') . '.xlsx');
    }

    public function render()
    {
        $returns = $this->getFilteredQuery()
            ->orderBy($this->sortField, $this->sortDirection)
            ->paginate($this->perPage);

        return view('livewire.sales.returns.index', [
            'returns' => $returns,
            'currency' => Setting::get('default_currency', 'EGP'),
        ]);
    }
}
