<?php

namespace App\Filament\Pages;

use App\Models\Machine;
use App\Models\StockMovement;
use Filament\Pages\Page;
use Filament\Schemas\Schema;
use Filament\Forms\Components\Select;
use Filament\Forms\Contracts\HasForms;
use Filament\Schemas\Components\Section;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Concerns\InteractsWithForms;
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
use Filament\Support\Icons\Heroicon;

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

    protected string $view = 'filament.pages.spare-parts-by-machine-report';

    protected static string|\BackedEnum|null $navigationIcon = Heroicon::OutlinedDocumentChartBar;
    protected static ?string $navigationLabel = null;
    protected static ?int $navigationSort = 5;

    public static function getNavigationGroup(): string|null
    {
        return __('filament/admin/spare_parts_by_machine_report.navigation_group');
    }

    public ?array $data = [];

    public array $rows = [];

    public function mount(): void
    {
        $this->form->fill([
            'machine_id' => null,
            'from_date' => now()->startOfMonth()->toDateString(),
            'to_date' => now()->endOfMonth()->toDateString(),
        ]);
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->statePath('data')
            ->components([
                Section::make(__('filament/admin/spare_parts_by_machine_report.فلاترالتقرير'))
                    ->columns(3)
                    ->schema([
                        Select::make('machine_id')
                            ->label(__('filament/admin/spare_parts_by_machine_report.المعدة'))
                            ->options(fn () => Machine::query()->where('is_active', true)->orderBy('name')->pluck('name', 'id')->toArray())
                            ->searchable()
                            ->preload(),

                        DatePicker::make('from_date')
                            ->label(__('filament/admin/spare_parts_by_machine_report.منتاريخ'))
                            ->native(false),

                        DatePicker::make('to_date')
                            ->label(__('filament/admin/spare_parts_by_machine_report.إلىتاريخ'))
                            ->native(false),
                    ]),
            ]);
    }

    public function generateReport(): void
    {
        $machineId = $this->data['machine_id'] ?? null;
        $fromDate = $this->data['from_date'] ?? null;
        $toDate = $this->data['to_date'] ?? null;

        $movementsQuery = StockMovement::query()
            ->with(['product', 'sparePartInstallations.machine'])
            ->where('movement_type', 'out')
            ->whereHas('product', fn ($query) => $query->where('is_spare_part', true));

        if ($fromDate) {
            $movementsQuery->whereDate('date', '>=', $fromDate);
        }

        if ($toDate) {
            $movementsQuery->whereDate('date', '<=', $toDate);
        }

        if ($machineId) {
            $movementsQuery->whereHas('sparePartInstallations', fn ($query) => $query->where('machine_id', $machineId));
        }

        $movements = $movementsQuery->orderByDesc('date')->get();

        $this->rows = $movements->map(function (StockMovement $movement): array {
            $installedQty = (float) $movement->sparePartInstallations->sum('installed_qty');
            $remainingQty = (float) $movement->quantity - $installedQty;

            $machines = $movement->sparePartInstallations
                ->map(fn ($installation) => $installation->machine?->name)
                ->filter()
                ->unique()
                ->values()
                ->implode('، ');

            return [
                'date' => $movement->date?->format('Y-m-d') ?? '-',
                'reference_number' => $movement->reference_number ?? ('SM-' . $movement->id),
                'part_code' => $movement->product?->code ?? '-',
                'part_name' => $movement->product?->name ?? '-',
                'issued_qty' => (float) $movement->quantity,
                'installed_qty' => $installedQty,
                'remaining_qty' => $remainingQty,
                'machines' => $machines ?: '-',
            ];
        })->toArray();
    }

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

    public static function canAccess(): bool
    {
        return auth()->check();
    }
    public static function getNavigationLabel(): string
    {
        return __('filament/admin/spare_parts_by_machine_report.navigation_label');
    }

}
