<?php

namespace App\Filament\Resources;

use AlperenErsoy\FilamentExport\Actions\FilamentExportBulkAction;
use App\Filament\Exports\ProductionPlanExporter;
use App\Filament\Imports\ProductionPlanImporter;
use App\Filament\Resources\ProductionPlanResource\Pages;
use App\Models\Block;
use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProductionPlan;
use App\Models\Shift;
use Carbon\Carbon;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;

class ProductionPlanResource extends Resource
{
    protected static ?string $model = ProductionPlan::class;

    protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';

    // protected static ?string $navigationParentItem = 'Production Line Stops';

    protected static ?string $navigationGroup = 'Production';

    protected static ?int $navigationSort = 3;

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                Section::make('')
                    ->schema([
                        Forms\Components\Select::make('plant_id')
                            ->relationship('plant', 'name')
                            ->required()
                            // ->nullable()
                            ->reactive()
                            ->options(function (callable $get) {
                                $userHas = Filament::auth()->user()->plant_id;

                                return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
                            })
                            ->default(function () {
                                return optional(ProductionPlan::latest()->first())->plant_id;
                            })
                            ->disabled(fn (Get $get) => ! empty($get('id')))
                            // ->afterStateUpdated(fn ($set) => $set('block_name', null))
                            ->afterStateUpdated(function ($state, callable $set, callable $get) {
                                $plantId = $get('plant_id');
                                $set('block_name', null);
                                if (! $plantId) {
                                    $set('ppPlantError', 'Please select a plant first.');

                                    return;
                                } else {
                                    $set('ppPlantError', null);
                                }
                            })
                            ->extraAttributes(fn ($get) => [
                                'class' => $get('ppPlantError') ? 'border-red-500' : '',
                            ])
                            ->hint(fn ($get) => $get('ppPlantError') ? $get('ppPlantError') : null)
                            ->hintColor('danger'),
                        Forms\Components\Select::make('line_id')
                            ->relationship('line', 'name')
                            ->required()
                            // ->nullable()
                            // ->options(fn (callable $get) =>
                            // \App\Models\Line::where('plant_id', $get('plant_id'))
                            //     ->pluck('name', 'id')
                            //     ->toArray() // Convert collection to array
                            // )
                            ->options(function (callable $get) {
                                if (! $get('plant_id')) {
                                    return [];
                                }

                                return Line::where('plant_id', $get('plant_id'))
                                    ->pluck('name', 'id')
                                    ->toArray();
                            })
                            ->reactive()
                            // ->default(function () {
                            //     return optional(ProductionPlan::latest()->first())->line_id;
                            // })
                            // ->afterStateUpdated(function ($state, callable $set, callable $get) {
                            //     if ($get('id')) {
                            //         $getShift = ProductionPlan::where('id', $get('id'))->first();
                            //         if ($getShift->line_id) {
                            //             $set('line_id', $getShift->line_id);
                            //             $set('ppLineError', null);
                            //         }
                            //     } else {
                            //         $currentDT = Carbon::now()->toDateTimeString();
                            //         $set('created_at', $currentDT);
                            //         $set('update_date', null);
                            //     }

                            //     $lineId = $get('line_id');
                            //     // $set('plan_quantity', null);

                            //     if (! $lineId) {
                            //         $set('ppLineError', 'Please select a line first.');

                            //         return;
                            //     } else {
                            //         $isUpdate = ! empty($get('id'));
                            //         if (! $isUpdate) {
                            //             $exists = ProductionPlan::where('plant_id', $get('plant_id'))
                            //                 ->where('shift_id', $get('shift_id'))
                            //                 ->where('line_id', $get('line_id'))
                            //                 ->whereDate('created_at', today())
                            //                 ->latest()
                            //                 ->exists();

                            //             if ($exists) {
                            //                 $set('line_id', null);
                            //                 $set('ppLineError', 'Production plan already updated.');

                            //                 return;
                            //             } else {
                            //                 $existShifts = ProductionPlan::where('plant_id', $get('plant_id'))
                            //                     ->where('shift_id', $get('shift_id'))
                            //                     ->where('line_id', $get('line_id'))
                            //                     ->whereDate('created_at', Carbon::yesterday())
                            //                     ->latest()
                            //                     ->exists();

                            //                 if ($existShifts) { // if ($existShifts->count() > 0)
                            //                     // $currentDate = date('Y-m-d');
                            //                     $yesterday = date('Y-m-d', strtotime('-1 days'));

                            //                     $shiftId = Shift::where('id', $get('shift_id'))
                            //                         ->first();

                            //                     [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
                            //                     $hRs = (int) $hRs;
                            //                     //   $miNs = (int) $miNs;-*/

                            //                     $totalMinutes = $hRs * 60 + $miNs;

                            //                     $from_dt = $yesterday.' '.$shiftId->start_time;

                            //                     $to_dt = date('Y-m-d H:i:s', strtotime($from_dt." + $totalMinutes minutes"));

                            //                     $currentDateTime = date('Y-m-d H:i:s');

                            //                     // Check if current date time is within the range
                            //                     if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
                            //                         // echo "Choosed a valid shift...";

                            //                         $set('line_id', null);
                            //                         $set('ppLineError', 'Production plan already updated.');

                            //                         // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
                            //                         return;
                            //                     } else {
                            //                         $currentDate = date('Y-m-d');

                            //                         $shiftId = Shift::where('id', $get('shift_id'))
                            //                             ->first();

                            //                         [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
                            //                         $hRs = (int) $hRs;
                            //                         //   $miNs = (int) $miNs;-*/

                            //                         $totalMinutes = $hRs * 60 + $miNs;

                            //                         $from_dt = $currentDate.' '.$shiftId->start_time;

                            //                         $to_dt = date('Y-m-d H:i:s', strtotime($from_dt." + $totalMinutes minutes"));

                            //                         $currentDateTime = date('Y-m-d H:i:s');

                            //                         // Check if current date time is within the range
                            //                         if (! ($currentDateTime >= $from_dt && $currentDateTime < $to_dt)) {
                            //                             // echo "Choosed a valid shift...";

                            //                             $set('line_id', null);
                            //                             $set('ppLineError', 'Choosed a invalid shift.');

                            //                             // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
                            //                             return;
                            //                         }
                            //                     }

                            //                     $set('ppLineError', null);

                            //                     return;
                            //                 } else {
                            //                     // $currentDate = date('Y-m-d');
                            //                     $yesterday = date('Y-m-d', strtotime('-1 days'));

                            //                     $shiftId = Shift::where('id', $get('shift_id'))
                            //                         ->first();

                            //                     [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
                            //                     $hRs = (int) $hRs;
                            //                     //   $miNs = (int) $miNs;-*/

                            //                     $totalMinutes = $hRs * 60 + $miNs;

                            //                     $from_dt = $yesterday.' '.$shiftId->start_time;

                            //                     $to_dt = date('Y-m-d H:i:s', strtotime($from_dt." + $totalMinutes minutes"));

                            //                     $currentDateTime = date('Y-m-d H:i:s');

                            //                     // Check if current date time is within the range
                            //                     if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
                            //                         // echo "Choosed a valid shift...";

                            //                         // here i'm updating created as yesterday
                            //                         $set('created_at', $from_dt);
                            //                         $set('update_date', '1');

                            //                         $set('ppLineError', null);

                            //                         // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
                            //                         return;
                            //                     } else {
                            //                         $currentDate = date('Y-m-d');

                            //                         $shiftId = Shift::where('id', $get('shift_id'))
                            //                             ->first();

                            //                         [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
                            //                         $hRs = (int) $hRs;
                            //                         //   $miNs = (int) $miNs;-*/

                            //                         $totalMinutes = $hRs * 60 + $miNs;

                            //                         $from_dt = $currentDate.' '.$shiftId->start_time;

                            //                         $to_dt = date('Y-m-d H:i:s', strtotime($from_dt." + $totalMinutes minutes"));

                            //                         $currentDateTime = date('Y-m-d H:i:s');

                            //                         // Check if current date time is within the range
                            //                         if (! ($currentDateTime >= $from_dt && $currentDateTime < $to_dt)) {
                            //                             // echo "Choosed a valid shift...";

                            //                             $set('line_id', null);
                            //                             $set('ppLineError', 'Choosed a invalid shift.');

                            //                             // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
                            //                             return;
                            //                         }
                            //                     }

                            //                     $set('ppLineError', null);

                            //                     return;
                            //                 }

                            //                 // $exists = ProductionPlan::where('plant_id', $get('plant_id'))
                            //                 //     //->where('shift_id', $get('shift_id'))
                            //                 //     ->where('line_id', $get('line_id'))
                            //                 //     ->whereDate('created_at', today())
                            //                 //     ->latest()  // Orders by created_at DESC
                            //                 //     ->first();

                            //                 // if ($exists)
                            //                 // {
                            //                 //     $existingShifts = ProductionPlan::where('plant_id', $get('plant_id'))
                            //                 //     //->where('shift_id', $get('shift_id'))
                            //                 //     ->where('line_id', $get('line_id'))
                            //                 //     // ->whereDate('created_at', today())
                            //                 //     ->whereDate('created_at', today())
                            //                 //     ->get();

                            //                 //     foreach ($existingShifts as $shift) {
                            //                 //         $curShiftId = $shift->shift_id;

                            //                 //         $currentDate = date('Y-m-d');

                            //                 //         $shiftId = \App\Models\Shift::where('id', $curShiftId)
                            //                 //         ->first();

                            //                 //         [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
                            //                 //         $hRs = (int) $hRs;
                            //                 //         //   $miNs = (int) $miNs;-*/

                            //                 //         $totalMinutes = $hRs * 60 + $miNs;

                            //                 //         $from_dt = $currentDate . ' ' . $shiftId->start_time;

                            //                 //         $to_dt = date('Y-m-d H:i:s', strtotime($from_dt . " + $totalMinutes minutes"));

                            //                 //         $currentDateTime = date('Y-m-d H:i:s');

                            //                 //         // Check if current date time is within the range
                            //                 //         if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
                            //                 //             //echo "Choosed a valid shift...";
                            //                 //             // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');

                            //                 //             $set('line_id', null);
                            //                 //             $set('ppLineError', 'Production plan already updated.');
                            //                 //             return;
                            //                 //         }
                            //                 //         // else {
                            //                 //             //     $set('ppLineError', 'Choosed a invalid shift...');
                            //                 //             //     return;
                            //                 //             // }
                            //                 //     }
                            //                 //     $set('ppLineError', null);
                            //                 //     return;
                            //                 // }
                            //             }
                            //         }
                            //         $set('ppLineError', null);
                            //     }
                            // })
                            ->afterStateUpdated(function ($state, callable $set, callable $get) {
                                $set('item_id', null);
                                $set('plan_quantity', null);
                            })
                            ->extraAttributes(fn ($get) => [
                                'class' => $get('ppLineError') ? 'border-red-500' : '',
                            ])
                            ->hint(fn ($get) => $get('ppLineError') ? $get('ppLineError') : null)
                            ->hintColor('danger'),
                        Forms\Components\Select::make('item_id')
                            ->label('Item')
                            ->reactive()
                            ->searchable()
                            ->required()
                            ->options(function (callable $get) {
                                if (! $get('plant_id')) {
                                    return [];
                                }

                                return Item::where('plant_id', $get('plant_id'))
                                    ->pluck('code', 'id')
                                    ->toArray();
                            }),
                        Forms\Components\TextInput::make('plan_quantity')
                            ->required()
                            ->integer()
                            ->label('Plan Quantity')
                            ->placeholder('Scan the valid quantity')
                            ->minValue(1)
                            ->reactive()
                            ->afterStateUpdated(function ($state, callable $set, callable $get) {
                                $planQuan = $get('plan_quantity');

                                if (! $get('update_date')) {
                                    if (! $get('id')) {
                                        $currentDT = Carbon::now()->toDateTimeString();
                                        $set('created_at', $currentDT);
                                    }
                                }

                                if (! $planQuan) {
                                    $set('ppPlanQuanError', 'Scan the valid plan quantity.');

                                    return;
                                } else {
                                    $set('ppPlanQuanError', null);
                                }
                            })
                            ->extraAttributes(fn ($get) => [
                                'class' => $get('ppPlanQuanError') ? 'border-red-500' : '',
                            ])
                            ->hint(fn ($get) => $get('ppPlanQuanError') ? $get('ppPlanQuanError') : null)
                            ->hintColor('danger'),
                        // Forms\Components\TextInput::make('production_quantity')
                        //     ->required()
                        //     ->integer()
                        //     ->label('Production Quantity')
                        //     ->readOnly(fn (callable $get) => ! $get('id'))
                        //     ->default(0),
                        Forms\Components\TextInput::make('id')
                            ->hidden()
                            ->readOnly(),
                        Forms\Components\Hidden::make('operator_id')
                            ->default(Filament::auth()->user()->name),
                    ])
                    ->columns(4),
            ]);
    }

    // public function submitForm(array $data)
    // {
    //     if (empty($data['update_date'])) {
    //         $data['created_at'] = now(); // Set current datetime if 'update_date' is empty
    //     }

    //     // Save or process form data
    //     ProductionPlan::create($data);
    // }
    // protected function afterSave(array $data)
    // {
    //     if ($this->model instanceof ProductionPlan && empty($data['update_date'])) {
    //         $this->model->created_at = now(); // Set current datetime if 'update_date' is empty
    //         $this->model->save();
    //     }
    // }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                // Tables\Columns\TextColumn::make('id')
                //     ->label('ID')
                //     ->numeric()
                //     ->sortable(),
                Tables\Columns\TextColumn::make('No.')
                    ->label('No.')
                    ->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
                        $paginator = $livewire->getTableRecords();
                        $perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
                        $currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;

                        return ($currentPage - 1) * $perPage + $rowLoop->iteration;
                    }),
                Tables\Columns\TextColumn::make('plant.name')
                    ->label('Plant')
                    ->alignCenter()
                    ->sortable()
                    ->searchable(),
                Tables\Columns\TextColumn::make('line.name')
                    ->label('Plant')
                    ->alignCenter()
                    ->sortable()
                    ->searchable(),
                Tables\Columns\TextColumn::make('item.code')
                    ->label('Item')
                    ->alignCenter()
                    ->sortable()
                    ->searchable(),
                Tables\Columns\TextColumn::make('plan_quantity')
                    ->label('Plan Quantity')
                    ->alignCenter()
                    ->numeric()
                    ->sortable()
                    ->searchable(),
                Tables\Columns\TextColumn::make('working_days')
                    ->label('Working Days')
                    ->alignCenter()
                    ->numeric()
                    ->sortable()
                    ->searchable(),
                Tables\Columns\TextColumn::make('production_quantity')
                    ->label('Production Quantity')
                    ->alignCenter()
                    ->numeric()
                    ->sortable()
                    ->searchable(),
                // Tables\Columns\TextColumn::make('line.name')
                //     ->label('Line')
                //     ->alignCenter()
                //     ->sortable(), // ->searchable(),
                // Tables\Columns\TextColumn::make('shift.block.name')
                //     ->label('Block')
                //     ->alignCenter()
                //     ->sortable(),
                // Tables\Columns\TextColumn::make('shift.name')
                //     ->label('Shift')
                //     ->alignCenter()
                //     ->sortable(), // ->searchable(),

                Tables\Columns\TextColumn::make('created_at')
                    ->label('Created At')
                    ->dateTime()
                    ->alignCenter()
                    ->sortable(),
                Tables\Columns\TextColumn::make('updated_at')
                    ->label('Updated At')
                    ->dateTime()
                    ->alignCenter()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
                Tables\Columns\TextColumn::make('deleted_at')
                    ->label('Deleted At')
                    ->dateTime()
                    ->alignCenter()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
                Tables\Columns\TextColumn::make('operator_id')
                    ->label('Operator ID')
                    ->alignCenter()
                    ->sortable(),
            ])
            ->filters([
                Tables\Filters\TrashedFilter::make(),
                Filter::make('advanced_filters')
                    ->label('Advanced Filters')
                    ->form([
                        // plant
                        Select::make('Plant')
                            ->label('Select Plant')
                            ->nullable()
                            // ->options(function () {
                            //     return Plant::pluck('name', 'id'); // Assuming 'name' is the column you want to display
                            // })
                            ->options(function (callable $get) {
                                $userHas = Filament::auth()->user()->plant_id;

                                return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
                            })
                            ->reactive()
                            ->afterStateUpdated(function ($state, callable $set, callable $get) {
                                $set('Line', null);
                                $set('Block', null);
                                $set('Shift', null);
                            }),

                        // line
                        Select::make('Line')
                            ->label('Select line')
                            ->nullable()
                            ->options(function (callable $get) {
                                $plantId = $get('Plant');

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

                                return Line::where('plant_id', $plantId)
                                    ->pluck('name', 'id');
                            })
                            ->reactive(),

                        // block
                        Select::make('Block')
                            ->label('Select Block')
                            ->nullable()
                            ->options(function (callable $get) {
                                $plantId = $get('Plant');

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

                                return Block::where('plant_id', $get('Plant'))->pluck('name', 'id');
                            })
                            ->reactive()
                            ->afterStateUpdated(function ($state, callable $set, callable $get) {
                                $set('Shift', null);
                            }),

                        // shift
                        Select::make('Shift')
                            ->label('Select Shift')
                            ->nullable()
                            ->options(function (callable $get) {
                                $plantId = $get('Plant');
                                $blockId = $get('Block');

                                if (! $plantId || ! $blockId) {
                                    return []; // Return empty if plant or block is not selected
                                }

                                return Shift::where('plant_id', $plantId)
                                    ->where('block_id', $blockId)
                                    ->pluck('name', 'id');
                            })
                            ->reactive(),

                        DateTimePicker::make(name: 'created_from')
                            ->label('Created From')
                            ->placeholder(placeholder: 'Select From DateTime')
                            ->reactive()
                            ->native(false),

                        DateTimePicker::make('created_to')
                            ->label('Created To')
                            ->placeholder(placeholder: 'Select To DateTime')
                            ->reactive()
                            ->native(false),
                    ])
                    ->query(function ($query, array $data) {
                        if (empty($data['Plant']) && empty($data['Shift']) && empty($data['Line']) && empty($data['created_from']) && empty($data['created_to'])) {
                            return $query->whereRaw('1 = 0');
                        }

                        if (! empty($data['Plant'])) {// if ($plant = $data['Plant'] ?? null) {
                            $query->where('plant_id', $data['Plant']);
                        } else {
                            $userHas = Filament::auth()->user()->plant_id;

                            if ($userHas && strlen($userHas) > 0) {
                                return $query->whereRaw('1 = 0');
                            }
                        }

                        if (! empty($data['Shift'])) {// if ($shift = $data['Shift'] ?? null) {
                            $query->where('shift_id', $data['Shift']);
                        }


                        if (! empty($data['Line'])) {// if ($line = $data['Line'] ?? null) {
                            $query->where('line_id', $data['Line']);
                        }

                        if (! empty($data['created_from'])) {// if ($from = $data['created_from'] ?? null) {
                            $query->where('created_at', '>=', $data['created_from']);
                        }

                        if (! empty($data['created_to'])) {// if ($to = $data['created_to'] ?? null) {
                            $query->where('created_at', '<=', $data['created_to']);
                        }

                        return $query;
                    })
                    ->indicateUsing(function (array $data) {
                        $indicators = [];

                        if (! empty($data['Plant'])) {
                            $indicators[] = 'Plant: '.Plant::where('id', $data['Plant'])->value('name');
                        } else {
                            $userHas = Filament::auth()->user()->plant_id;

                            if ($userHas && strlen($userHas) > 0) {
                                return 'Plant: Choose plant to filter records.';
                            }
                        }

                        if (! empty($data['Shift'])) {
                            $indicators[] = 'Shift: '.Shift::where('id', $data['Shift'])->value('name');
                        }

                        if (! empty($data['Line'])) {
                            $indicators[] = 'Line: '.Line::where('id', $data['Line'])->value('name');
                        }

                        if (! empty($data['created_from'])) {
                            $indicators[] = 'From: '.$data['created_from'];
                        }

                        if (! empty($data['created_to'])) {
                            $indicators[] = 'To: '.$data['created_to'];
                        }

                        return $indicators;
                    }),
            ])
            ->filtersFormMaxHeight('280px')
            ->actions([
                Tables\Actions\ViewAction::make(),
                Tables\Actions\EditAction::make(),
            ])
            ->bulkActions([
                Tables\Actions\BulkActionGroup::make([
                    Tables\Actions\DeleteBulkAction::make(),
                    Tables\Actions\ForceDeleteBulkAction::make(),
                    Tables\Actions\RestoreBulkAction::make(),
                    FilamentExportBulkAction::make('export'),
                ]),
            ])
            ->headerActions([
                ImportAction::make()
                    ->label('Import Production Plans')
                    ->color('warning')
                    ->importer(ProductionPlanImporter::class)
                    ->visible(function () {
                        return Filament::auth()->user()->can('view import production plan');
                    }),
                ExportAction::make()
                    ->label('Export Production Plans')
                    ->color('warning')
                    ->exporter(ProductionPlanExporter::class)
                    ->visible(function () {
                        return Filament::auth()->user()->can('view export production plan');
                    }),
            ]);
    }

    public static function getRelations(): array
    {
        return [
            //
        ];
    }

    public static function getPages(): array
    {
        return [
            'index' => Pages\ListProductionPlans::route('/'),
            'create' => Pages\CreateProductionPlan::route('/create'),
            'view' => Pages\ViewProductionPlan::route('/{record}'),
            'edit' => Pages\EditProductionPlan::route('/{record}/edit'),
        ];
    }

    public static function getEloquentQuery(): Builder
    {
        return parent::getEloquentQuery()
            ->withoutGlobalScopes([
                SoftDeletingScope::class,
            ]);
    }
}
