<?php

namespace App\Filament\Pages;

use App\Models\CustomerPoMaster;
use App\Models\Plant;
use App\Models\WireMasterPacking;
use Filament\Facades\Filament;
use Filament\Pages\Page;
use Illuminate\Support\Facades\Auth;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Form;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Illuminate\Support\Facades\Log;

class WireMasterPrint extends Page
{
    protected static ?string $navigationIcon = 'heroicon-o-document-text';

    protected static string $view = 'filament.pages.wire-master-print';

    protected static ?string $navigationGroup = 'Master Packing';

    use InteractsWithForms;

    public $pId, $palletNo, $serialNo;
    public $snoCount = 0;

    public bool $disableSerialNo = false;
    public bool $disablePalletNo = false;

    public $locatorNumber;
    public $state = [];

    public $plantId;

    public $scanLocator;

    public $locators;

    public array $filters = [];

    public function mount()
    {
        $this->form->fill([
            'plant_id'=>$this->plantId,
            'pallet_quantity' => 0,
        ]);
    }

    public function form(Form $form): Form
    {
        return $form
            ->statePath('filters')
            ->schema([
                Section::make('')
                    ->schema([
                        Select::make('plant_id')
                            ->label('Plant')
                            ->reactive()
                            //->options(Plant::pluck('name', 'id'))
                            ->options(function (callable $get) {
                                $userHas = Filament::auth()->user()->plant_id;
                                return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
                            })
                            ->required(),
                        Select::make('customer_po_master_id')
                            ->label('Customer PO')
                            ->reactive()
                            ->searchable()
                            ->options(function (callable $get) {
                                $plantId = $get('plant_id');
                                if (empty($plantId)) {
                                    return [];
                                }

                                return CustomerPoMaster::where('plant_id', $plantId)->distinct()->pluck('customer_po', 'customer_po'); //->pluck('customer_po', 'id'); ->distinct()
                            })
                            ->required()
                            ->afterStateUpdated(function ($state, callable $set) {
                                $set('scan_pallet_no', null);
                            }),
                        Select::make('scan_pallet_no')
                            ->label('Scan Pallet No')
                            ->reactive()
                            ->searchable()
                            ->options(function ($get) {

                                // $plantId = $get('plant_id');
                                // $customerPoId = $get('customer_po_master_id');

                                // if (! $plantId || ! $customerPoId) {
                                //     return [];
                                // }

                                // $palletNumbers = WireMasterPacking::query()
                                //     ->select('wire_packing_number')
                                //     ->where('plant_id', $plantId)
                                //     ->where('customer_po_master_id', $customerPoId)
                                //     ->whereNotNull('wire_packing_number')
                                //     ->groupBy('wire_packing_number')
                                //     ->havingRaw('COUNT(*) = COUNT(wire_packing_status)')
                                //     ->havingRaw("SUM(CASE WHEN TRIM(wire_packing_status) = '' THEN 1 ELSE 0 END) = 0")
                                //     ->orderBy('wire_packing_number', 'asc')
                                //     ->pluck('wire_packing_number')
                                //     ->toArray();

                                // return collect($palletNumbers)
                                //     ->mapWithKeys(fn ($number) => [$number => $number])
                                //     ->toArray();

                                //..New Logic

                                $plantId = $get('plant_id');
                                $customerPo = $get('customer_po_master_id');

                                if (! $plantId || ! $customerPo)
                                {
                                    return [];
                                }

                                $poIds = CustomerPoMaster::where('plant_id', $plantId)->where('customer_po', $customerPo)->pluck('id');
                                $palletNumbers = WireMasterPacking::query()
                                    ->where('plant_id', $plantId)
                                    ->whereIn('customer_po_master_id', $poIds)
                                    ->whereNotNull('wire_packing_number')
                                    ->groupBy('wire_packing_number')
                                    ->havingRaw('COUNT(*) = COUNT(wire_packing_status)')
                                    ->havingRaw("SUM(CASE WHEN TRIM(wire_packing_status) = '' THEN 1 ELSE 0 END) = 0")
                                    ->orderBy('wire_packing_number')
                                    ->pluck('wire_packing_number')
                                    ->toArray();
                                return collect($palletNumbers) ->mapWithKeys(fn ($number) => [$number => $number]) ->toArray();
                            })
                            ->afterStateUpdated(function ($state, callable $set, $get) {
                                $palletNo = $state;
                                $plantId = $get('plant_id');


                                $this->dispatch('loadData', $palletNo, $plantId);
                            })
                            ->extraAttributes([
                                'wire:keydown.enter' => 'processPalletNo($event.target.value)',
                            ]),
                        // TextInput::make('customer_name')
                        //     ->label('Customer Name')
                        //     ->required()
                        //     ->reactive(),
                    ])
                    ->columns(3)
            ]);
    }

    public function processPalletNo($palletNo)
    {
        $plantId = $this->form->getState()['plant_id'];

        $plantId = trim($plantId) ?? null;

        $palletNo= $this->form->getState()['scan_pallet_no'];

        $palletNo = trim($palletNo) ?? null;

        $operatorName = Filament::auth()->user()->name;

        if ($palletNo == null || $palletNo == '')
        {
            Notification::make()
                ->title("Pallet number can't be empty!")
                ->danger()
                ->duration(5000)
                ->send();

            $this->dispatch('loadLocator' ,'',$plantId);
            $this->form->fill
            ([
                'plant_id'      => $plantId,
                'scan_serial_no' => null,
                'scan_pallet_no' => null,
                'scan_locator_no' => null,
                'pallet_quantity' => 0,
                'created_by'    => $operatorName,
                'scanned_by'    => $operatorName,
            ]);
            return;
        }
        // else if (strlen($palletNo) < 10)
        // {
        //     Notification::make()
        //         ->title("Pallet number '$palletNo' must be at least 10 digits.")
        //         ->danger()
        //         ->duration(5000)
        //         ->send();

        //     $this->dispatch('loadLocator' ,'',$plantId);
        //     $this->form->fill
        //         ([
        //             'plant_id'      => $plantId,
        //             'scan_serial_no' => null,
        //             'scan_pallet_no' => null,
        //             'scan_locator_no' => null,
        //             'pallet_quantity' => 0,
        //             'created_by'    => $operatorName,
        //             'scanned_by'    => $operatorName,
        //         ]);
        //     return;
        // }

        $Palletexists = WireMasterPacking::where('wire_packing_number', $palletNo)
        ->where('plant_id',  $plantId)->first();
        if(!$Palletexists)
        {
            Notification::make()
                ->title("Pallet number '$palletNo' does not found in wire master packing table.")
                ->danger()
                ->duration(5000)
                ->send();

            $this->dispatch('loadData' ,'',$plantId);
            $this->form->fill
            ([
                'plant_id'      => $plantId,
                'scan_pallet_no' => null,
                'pallet_quantity' => 0,
                'created_by'    => $operatorName,
                'scanned_by'    => $operatorName,
            ]);
            return;
        }
        else
        {
            $this->snoCount = WireMasterPacking::where('plant_id', $plantId)
                    ->where('wire_packing_number', $palletNo)
                    ->count();

            $this->dispatch('loadData', $palletNo, $plantId);
            $this->form->fill
            ([
                'plant_id'      => $plantId,
                'scan_pallet_no' => $palletNo,
                'pallet_quantity' => $this->snoCount,
                'created_by'    => $operatorName,
                'scanned_by'    => $operatorName,
            ]);
            return;
        }
    }

    public function saveCustomerPO(){
        $plantId = $this->form->getState()['plant_id'];

        $plantId = trim($plantId) ?? null;

        $palletNo= $this->form->getState()['scan_pallet_no'];

        $palletNo = trim($palletNo) ?? null;

        $customerPO = $this->form->getState()['customer_po'];

        $customerPO = trim($customerPO) ?? null;

        $customerName = $this->form->getState()['customer_name'];

        $customerName = trim($customerName) ?? null;

        if (!$plantId || !$palletNo) {
            return; // optional validation
        }

        $record = WireMasterPacking::where('plant_id', $plantId)
            ->where('wire_packing_number', $palletNo)
            ->update([
                'customer_po' => $customerPO,
                'customer_name' => $customerName,
                'updated_at' => now(),
            ]);

        if($record){
            Notification::make()
            ->title("Customer PO updated successfully for the pallet number '$palletNo'")
            ->success()
            ->send();
            return;
        }
        else
        {
            Notification::make()
            ->title("Customer PO updation failed for the pallet number '$palletNo'")
            ->success()
            ->send();
            return;
        }
    }

    public function printPallet()
    {
        $palletNumber = $this->form->getState()['scan_pallet_no'] ?? null;
        $plantId = $this->form->getState()['plant_id'] ?? null;
        $customerId = $this->form->getState()['customer_po_master_id'] ?? null;

        $state = $this->form->getState();

        // $customerCode = $state['customer_po'] ?? null;
        // $customerName = $state['customer_name'] ?? null;

        if (!$palletNumber) {
            Notification::make()
                ->title("Pallet number cant't be empty!")
                ->danger()
                ->duration(5000)
                ->send();
            return;
        }


        // return redirect()->route('print.pallet', [
        //     'pallet' => $palletNumber,
        //     'plant'  => $plantId,
        // ]);
        $this->dispatch('open-pdf', url: route('print.pallet', [
            'pallet' => $state['scan_pallet_no'],
            'plant'  => $state['plant_id'],
            'customer'  => $state['customer_po_master_id'],
        ]));
    }

    public static function canAccess(): bool
    {
        return Auth::check() && Auth::user()->can('view wire master print page');
    }
}
