<?php

namespace App\Filament\Pages;

use App\Filament\Widgets\GuardPatrolHourlyChart;
use App\Models\CheckPointName;
use App\Models\CheckPointTime;
use App\Models\GuardPatrolEntry;
use App\Models\Plant;
use Carbon\Carbon;
use Filament\Facades\Filament;
use Filament\Pages\Page;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
use Filament\Forms\Form;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\DatePicker;
use Illuminate\Support\Facades\Auth;

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

    protected static string $view = 'filament.pages.guard-patrol-hourly-count';

    protected static ?string $navigationGroup = 'Guard DashBoard';


    use HasFiltersForm;

    public function mount(): void
    {
        session()->forget(['selected_plant']);
        session()->forget(['selected_date']);
        session()->forget(['selected_name']);
        session()->forget(['selected_time']);
        session()->forget(['valid_sessions']);
        $this->filtersForm->fill([
            'plant' => null,
            'date' => null,
            'time_range' => null,
            'guard_name' => null
        ]);
    }

    public function filtersForm(Form $form): Form
    {
        return $form
            ->statePath('filters')
            ->schema([
                Select::make('plant')
                    ->label('Select Plant')
                    //->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();
                    })
                    ->reactive()
                    ->required()
                    ->afterStateUpdated(function ($state,callable $set) {
                        if (is_null($state)) {
                            session()->forget('selected_plant');
                        } else {
                            session(['selected_plant' => $state]);
                        }

                        session(['selected_plant' => $state]);

                        $set('date', null);
                        session()->forget('selected_date');

                        $set('guard_name', null);
                        session()->forget('selected_name');

                        $set('time_range', null);
                        session()->forget('selected_time');
                        session()->forget('valid_sessions');

                      // $this->dispatch('patrolEntryChart');
                   }),
                DatePicker::make('date')
                    ->label('Select Date')
                    ->placeholder('Select Date')
                    ->reactive()
                    ->required()
                    ->beforeOrEqual(now())
                    ->default(now()->format('Y-m-d'))
                    ->afterStateUpdated(function ($state,callable $set) {
                       session(['selected_date' => $state]);
                        $set('guard_name', null);
                        session()->forget('selected_name');
                        $set('time_range', null);
                        session()->forget('selected_time');
                        session()->forget('valid_sessions');

                      // $this->dispatch('patrolEntryChart');
                   }),
                Select::make('guard_name')
                    ->label('Guard Name')
                    ->options(function (callable $get) {
                        $plantId = $get('plant');
                        $Date = $get('date');
                        if (!$plantId || !$Date) {
                            return [];
                        }

                   return GuardPatrolEntry::with('guardNames')->where('plant_id', $plantId)
                        ->whereDate('patrol_time', $Date)->orderBy('patrol_time','asc')
                        ->get()
                        ->unique('guard_name_id')
                        ->pluck('guardNames.name', 'guard_name_id')
                        ->toArray();

                    })
                    ->reactive()
                    ->required()
                    ->afterStateUpdated(function ($state,callable $set)
                    {
                            if (is_null($state))
                            {
                                session()->forget('selected_name');
                            }
                            else
                            {
                                session(['selected_name' => $state]);
                            }

                            // Clear the time range field and its session
                            $set('time_range', null);
                            session()->forget('selected_time');
                            session()->forget('valid_sessions');
                   }),

            // Select::make('time_range')
            //     ->label('Patrol Time Range')
            //     ->options(function (callable $get) {
            //         $plantId = $get('plant');
            //         $guardId = $get('guard_name');
            //         $date = $get('date');

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

            //         $patrols = GuardPatrolEntry::where('plant_id', $plantId)
            //             ->where('guard_name_id', $guardId)
            //             ->whereDate('patrol_time', $date)
            //             ->orderBy('patrol_time', 'asc')
            //             ->get(['patrol_time']);

            //         if ($patrols->isEmpty())
            //         {
            //             return [];
            //         }

            //         $chunkSize = CheckPointTime::where('plant_id', $plantId)->count()+ 1;;
            //         $chunks = $patrols->chunk($chunkSize);

            //         $options = [];
            //         foreach ($chunks as $index => $chunk) {
            //             $first = $chunk->first();
            //             $last = $chunk->last();
            //             $start = Carbon::parse($first->patrol_time)->format('H:i:s');
            //             $end = Carbon::parse($last->patrol_time)->format('H:i:s');
            //             $timeRange = "$start - $end";
            //             $options[$timeRange] = $timeRange;
            //         }

            //         return $options;
            //     })
            //     ->reactive()
            //     ->required()
            //     ->afterStateUpdated(function ($state) {
            //         session(['selected_time' => $state]);
            //     })
            Select::make('time_range')
            ->label('Patrol Time Range')
            ->options(function (callable $get) {
                $plantId = $get('plant');
                $guardId = $get('guard_name');
                $date = $get('date');

                if (!$plantId || !$guardId || !$date) {
                    session(['valid_sessions' => []]);
                    return [];
                }

                // Get patrols with checkpoints
                $patrols = GuardPatrolEntry::where('plant_id', $plantId)
                    ->where('guard_name_id', $guardId)
                    ->whereDate('patrol_time', $date)
                    ->orderBy('patrol_time', 'asc')
                    ->get(['patrol_time', 'check_point_name_id']);

                if ($patrols->isEmpty()) {
                    session(['valid_sessions' => []]);
                    return [];
                }

                // Get checkpoint sequence
                $checkPointTimes = CheckPointTime::where('plant_id', $plantId)
                    ->orderBy('sequence_number')
                    ->get(['check_point1_id', 'check_point2_id']);

                // Build expected sequence
                $expectedSequence = [];
                foreach ($checkPointTimes as $row) {
                    $expectedSequence[] = $row->check_point1_id;
                }
                if ($checkPointTimes->isNotEmpty()) {
                    $expectedSequence[] = $checkPointTimes->last()->check_point2_id;
                }

                $chunkSize = $checkPointTimes->count() + 1;
                $chunks = $patrols->chunk($chunkSize);

                $options = [];
                $validSessions = [];

                foreach ($chunks as $index => $chunk) {
                    $first = $chunk->first();
                    $last = $chunk->last();
                    $start = Carbon::parse($first->patrol_time)->format('H:i:s');
                    $end = Carbon::parse($last->patrol_time)->format('H:i:s');
                    $timeRange = "$start - $end";

                    // Validate sequence for this chunk
                    $currentSeqIndex = 0;
                    $isValid = true;
                    $anyMatch = false;

                    foreach ($chunk as $patrol) {
                        if ($currentSeqIndex < count($expectedSequence) &&
                            $patrol->check_point_name_id == $expectedSequence[$currentSeqIndex]) {
                            $currentSeqIndex++;
                            $anyMatch = true;
                        } else {
                            $isValid = false;
                        }
                    }

                    // Consider valid only if at least one checkpoint matches
                    $isValid = $isValid && $anyMatch;
                    $validSessions[$timeRange] = $isValid;
                    $options[$timeRange] = $timeRange;
                }

                session(['valid_sessions' => $validSessions]);
                return $options;
            })
            ->reactive()
            ->required()
            ->afterStateUpdated(function ($state) {
                session(['selected_time' => $state]);
            })

            ])
            ->columns(4);
    }

    public function getWidgets(): array
    {
        return [
            GuardPatrolHourlyChart::class,
        ];
    }

    public static function canAccess(): bool
    {
        return Auth::check() && Auth::user()->can('view guard patrol hourly count dashboard');
    }
}
