<?php

namespace App\Filament\Pages;

use Carbon\Carbon;
use App\Models\Product;
use Filament\Pages\Page;
use App\Models\Warehouse;
use App\Models\StockMovement;
use Filament\Schemas\Schema;
use Illuminate\Contracts\View\View;
use Filament\Forms\Components\Select;
use Filament\Forms\Contracts\HasForms;
use Filament\Schemas\Components\Section;
use Filament\Forms\Components\DatePicker;
use App\Exports\ExpiryBatchesExport;
use Maatwebsite\Excel\Facades\Excel;
use Filament\Forms\Concerns\InteractsWithForms;
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
use Filament\Support\Icons\Heroicon;

class ExpiryBatchesReport extends Page implements HasForms
{
    use InteractsWithForms;
    use HasPageShield;

    protected string $view = 'filament.pages.expiry-batches-report';

    public ?array $data = [];
    public array $report_data = [];

    protected static string|\BackedEnum|null $navigationIcon = Heroicon::OutlinedCalendarDays;

    protected static string|\UnitEnum|null $navigationGroup = 'products';

    protected static ?int $navigationSort = 9;

    public function getTitle(): string
    {
        return 'تقرير تواريخ الصلاحية';
    }

    public static function getNavigationLabel(): string
    {
        return 'تقرير تواريخ الصلاحية';
    }

    public static function getNavigationGroup(): ?string
    {
        return __('filament.navigation_groups.products');
    }

    public function mount(): void
    {
        $this->form->fill([
            'expiry_from_date' => now(),
            'expiry_to_date' => now()->addMonths(6),
        ]);
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->statePath('data')
            ->components([
                Section::make(__('filament/admin/reports.filters'))
                    ->columns(4)
                    ->schema([
                        Select::make('product_id')
                            ->label(__('filament/admin/reports.product'))
                            ->placeholder(__('filament/admin/reports.select_product'))
                            ->options(function () {
                                return Product::where('has_expiry_date', true)->get()->mapWithKeys(function ($product) {
                                    return [$product->id => $product->name_ar ?: $product->name ?: 'منتج #' . $product->id];
                                });
                            })
                            ->searchable()
                            ->preload(),

                        Select::make('warehouse_id')
                            ->label(__('filament/admin/reports.warehouse'))
                            ->placeholder(__('filament/admin/reports.select_warehouse'))
                            ->options(function () {
                                return Warehouse::all()->mapWithKeys(function ($warehouse) {
                                    return [$warehouse->id => $warehouse->name_ar ?: $warehouse->name ?: 'مخزن #' . $warehouse->id];
                                });
                            })
                            ->searchable()
                            ->preload()
                            ->required(),

                        DatePicker::make('expiry_from_date')
                            ->label(__('filament/admin/reports.expiry_from_date'))
                            ->native(false),

                        DatePicker::make('expiry_to_date')
                            ->label(__('filament/admin/reports.expiry_to_date'))
                            ->native(false),
                    ]),
            ]);
    }

    public function generateReport(): void
    {
        $formData = $this->form->getState();
        $productId = $formData['product_id'] ?? null;
        $warehouseId = $formData['warehouse_id'] ?? null;

        if (!$warehouseId) {
            \Filament\Notifications\Notification::make()
                ->title('يرجى اختيار مخزن')
                ->warning()
                ->send();
            return;
        }

        $expiryFromDate = isset($formData['expiry_from_date']) ? Carbon::parse($formData['expiry_from_date'])->startOfDay() : null;
        $expiryToDate = isset($formData['expiry_to_date']) ? Carbon::parse($formData['expiry_to_date'])->endOfDay() : null;

        if ($expiryFromDate && $expiryToDate && $expiryToDate->lt($expiryFromDate)) {
            \Filament\Notifications\Notification::make()
                ->title('تاريخ النهاية يجب أن يكون بعد أو يساوي تاريخ البداية')
                ->warning()
                ->send();
            $this->report_data = [];
            return;
        }

        // جلب الدفعات (مجموعات تاريخ الصلاحية) مع أرصدة موجبة
        $query = StockMovement::selectRaw('
            expiry_date, 
            product_id,
            warehouse_id,
            SUM(CASE WHEN movement_type = "in" THEN quantity ELSE -quantity END) as balance,
            COUNT(DISTINCT reference_id) as transaction_count,
            MIN(date) as first_date,
            MAX(date) as last_date
        ')
            ->groupBy('expiry_date', 'product_id', 'warehouse_id')
            ->having('balance', '>', 0);

        // تطبيق التصفيات
        if ($productId) {
            $query->where('product_id', $productId);
        }

        if ($warehouseId) {
            $query->where('warehouse_id', $warehouseId);
        }

        if ($expiryFromDate) {
            $query->where(function ($q) use ($expiryFromDate) {
                $q->whereNull('expiry_date')
                    ->orWhere('expiry_date', '>=', $expiryFromDate);
            });
        }

        if ($expiryToDate) {
            $query->where(function ($q) use ($expiryToDate) {
                $q->whereNull('expiry_date')
                    ->orWhere('expiry_date', '<=', $expiryToDate);
            });
        }

        $batches = $query->orderBy('expiry_date')->get();

        // إثراء البيانات بمعلومات المنتج والمستودع
        $enrichedBatches = $batches->map(function ($batch) {
            $product = Product::find($batch->product_id);
            $warehouse = Warehouse::find($batch->warehouse_id);

            return [
                'expiry_date' => $batch->expiry_date ? $batch->expiry_date->format('Y-m-d') : __('filament/admin/reports.no_expiry'),
                'expiry_date_raw' => $batch->expiry_date,
                'days_until_expiry' => $batch->expiry_date ? $batch->expiry_date->diffInDays(now()) : null,
                'is_expired' => $batch->expiry_date && $batch->expiry_date < now(),
                'product_name' => $product?->name_ar ?? $product?->name,
                'product_code' => $product?->code,
                'warehouse_name' => $warehouse?->name_ar ?? $warehouse?->name,
                'balance' => $batch->balance,
                'transaction_count' => $batch->transaction_count,
                'first_date' => $batch->first_date ? Carbon::parse($batch->first_date)->format('Y-m-d') : null,
                'last_date' => $batch->last_date ? Carbon::parse($batch->last_date)->format('Y-m-d') : null,
            ];
        });

        // حساب الإجماليات
        $totalBatches = $enrichedBatches->count();
        $totalQuantity = $enrichedBatches->sum('balance');
        $expiredCount = $enrichedBatches->filter(fn($b) => $b['is_expired'])->count();
        $nearExpiry = $enrichedBatches->filter(fn($b) => $b['days_until_expiry'] !== null && $b['days_until_expiry'] <= 30 && !$b['is_expired'])->count();

        $this->report_data = [
            'batches' => $enrichedBatches,
            'total_batches' => $totalBatches,
            'total_quantity' => $totalQuantity,
            'expired_count' => $expiredCount,
            'near_expiry_count' => $nearExpiry,
            'expiry_from_date' => $expiryFromDate?->format('Y-m-d'),
            'expiry_to_date' => $expiryToDate?->format('Y-m-d'),
            'filter_product' => $productId ? Product::find($productId)?->name : __('filament/admin/reports.all_products'),
            'filter_warehouse' => $warehouseId ? Warehouse::find($warehouseId)?->name : __('filament/admin/reports.all_warehouses'),
        ];
    }

    public function exportExcel(): void
    {
        if (empty($this->report_data) || empty($this->report_data['batches'])) {
            return;
        }

        Excel::download(
            new ExpiryBatchesExport($this->report_data),
            'expiry-batches-' . date('Y-m-d-H-i-s') . '.xlsx'
        );
    }
}
