<?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;

class ExpiryBatchesReport extends Page implements HasForms
{
    use InteractsWithForms;

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

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

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

    protected static ?int $navigationSort = 9;

    public function getTitle(): string
    {
        return __('filament/admin/reports.expiry_batches');
    }

    public static function getNavigationLabel(): string
    {
        return __('filament/admin/reports.expiry_batches');
    }

    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(Product::where('has_expiry_date', true)->pluck('name', 'id'))
                            ->searchable()
                            ->preload(),

                        Select::make('warehouse_id')
                            ->label(__('filament/admin/reports.warehouse'))
                            ->placeholder(__('filament/admin/reports.select_warehouse'))
                            ->options(Warehouse::pluck('name', 'id'))
                            ->searchable()
                            ->preload(),

                        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
    {
        $productId = $this->data['product_id'] ?? null;
        $warehouseId = $this->data['warehouse_id'] ?? null;
        $expiryFromDate = isset($this->data['expiry_from_date']) ? Carbon::parse($this->data['expiry_from_date'])->startOfDay() : null;
        $expiryToDate = isset($this->data['expiry_to_date']) ? Carbon::parse($this->data['expiry_to_date'])->endOfDay() : null;

        // جلب الدفعات (مجموعات تاريخ الصلاحية) مع أرصدة موجبة
        $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,
                'product_code' => $product?->code,
                'warehouse_name' => $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'
        );
    }
}
