<?php

namespace App\Filament\Resources\Users;

use App\Filament\Resources\Users\Pages;
use App\Models\User;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Grid;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Toggle;
use Filament\Tables\Table;
use Filament\Tables;
use Filament\Notifications\Notification;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Hash;
use Filament\Actions;
use Filament\Actions\Action;
use Filament\Actions\CreateAction;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\EditAction;
use Filament\Actions\DeleteAction;
use Filament\Actions\DeleteBulkAction;
use UnitEnum;
use BackedEnum;

class UserResource extends Resource
{
    protected static ?string $model = User::class;
    protected static string|BackedEnum|null $navigationIcon  = null;         // icon is on the group
    protected static string|UnitEnum|null $navigationGroup = 'Administration';
    protected static ?string $navigationLabel = 'Staff Accounts';
    protected static ?int    $navigationSort  = 1;

    // ── Access control ────────────────────────────────────────────

    /**
     * Only admin+ can reach this resource.
     * Staff cannot manage other users.
     */
    public static function canAccess(): bool
    {
        return auth()->user()?->hasRole(['super_admin', 'admin']) ?? false;
    }

    /**
     * Admins see all users EXCEPT super_admin accounts.
     * Super admins see everyone.
     */
    public static function getEloquentQuery(): Builder
    {
        $query = parent::getEloquentQuery();

        // Admin can see admin, staff and clients — not super_admin
        if (auth()->user()?->hasRole('admin')) {
            $query->where('role', '!=', 'super_admin');
        }

        return $query;
    }

    // ── Form ──────────────────────────────────────────────────────

    public static function form(Schema $schema): Schema
    {
        $isSuperAdmin = auth()->user()?->hasRole('super_admin');

        return $schema->components([

            Section::make('Account Information')
                ->schema([
                    Grid::make(2)->schema([

                        TextInput::make('name')
                            ->required()
                            ->maxLength(255),

                        TextInput::make('phone')
                            ->tel()
                            ->required()
                            ->unique(ignoreRecord: true)
                            ->helperText('Used for login and cargo auto-linking'),

                        TextInput::make('email')
                            ->email()
                            ->nullable()
                            ->unique(ignoreRecord: true),

                        Select::make('role')
                            ->options(self::availableRoleOptions())
                            ->required()
                            ->native(false)
                            ->helperText(
                                $isSuperAdmin
                                    ? 'You can assign any role including Super Admin.'
                                    : 'Admins can create staff and client accounts.'
                            ),

                        TextInput::make('password')
                            ->password()
                            ->revealable()
                            ->dehydrateStateUsing(fn ($state) =>
                                filled($state) ? Hash::make($state) : null
                            )
                            ->dehydrated(fn ($state) => filled($state))
                            ->required(fn (string $operation): bool =>
                                $operation === 'create'
                            )
                            ->label(fn (string $operation): string =>
                                $operation === 'edit'
                                    ? 'New Password (leave blank to keep current)'
                                    : 'Password'
                            )
                            ->helperText('Minimum 8 characters'),

                        Toggle::make('is_active')
                            ->label('Account Active')
                            ->default(true)
                            ->helperText('Inactive accounts cannot log in'),

                    ]),
                ]),
        ]);
    }

    // ── Table ─────────────────────────────────────────────────────

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                Tables\Columns\TextColumn::make('name')
                    ->searchable()
                    ->sortable()
                    ->weight('bold'),

                Tables\Columns\TextColumn::make('phone')
                    ->searchable()
                    ->copyable(),

                Tables\Columns\TextColumn::make('email')
                    ->searchable()
                    ->placeholder('—')
                    ->toggleable(),

                Tables\Columns\TextColumn::make('role')
                    ->badge()
                    ->color(fn (string $state): string => match ($state) {
                        'super_admin' => 'danger',
                        'admin'       => 'warning',
                        'accountant'  => 'info',
                        'cashier'     => 'success',
                        'warehouse'   => 'primary',
                        'staff'       => 'gray',
                        'director'    => 'info',
                        default       => 'gray',
                    })
                    ->formatStateUsing(fn (string $state): string =>
                        ucwords(str_replace('_', ' ', $state))
                    ),

                Tables\Columns\IconColumn::make('is_active')
                    ->label('Active')
                    ->boolean()
                    ->trueIcon('heroicon-o-check-circle')
                    ->falseIcon('heroicon-o-x-circle')
                    ->trueColor('success')
                    ->falseColor('danger'),

                Tables\Columns\TextColumn::make('created_at')
                    ->dateTime('M d, Y')
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                Tables\Filters\SelectFilter::make('role')
                    ->options(self::availableRoleOptions()),

                Tables\Filters\TernaryFilter::make('is_active')
                    ->label('Account Status')
                    ->trueLabel('Active only')
                    ->falseLabel('Inactive only')
                    ->nullable(),
            ])
            ->actions([
                EditAction::make()
                    // Prevent editing super_admin unless you ARE super_admin
                    ->visible(fn (User $record): bool =>
                        $record->role !== 'super_admin' ||
                        auth()->user()?->hasRole('super_admin')
                    )
                    // After save, sync the Spatie role to match the role column
                    ->after(function (User $record): void {
                        $record->syncRoles([$record->role]);
                    }),

                Action::make('toggle_active')
                    ->label(fn (User $record): string =>
                        $record->is_active ? 'Deactivate' : 'Activate'
                    )
                    ->icon(fn (User $record): string =>
                        $record->is_active
                            ? 'heroicon-o-lock-closed'
                            : 'heroicon-o-lock-open'
                    )
                    ->color(fn (User $record): string =>
                        $record->is_active ? 'danger' : 'success'
                    )
                    ->requiresConfirmation()
                    ->modalHeading(fn (User $record): string =>
                        $record->is_active
                            ? "Deactivate {$record->name}?"
                            : "Activate {$record->name}?"
                    )
                    ->modalDescription(fn (User $record): string =>
                        $record->is_active
                            ? 'This account will no longer be able to log in.'
                            : 'This account will be able to log in again.'
                    )
                    // Cannot deactivate yourself
                    ->visible(fn (User $record): bool =>
                        $record->id !== auth()->id() &&
                        (
                            $record->role !== 'super_admin' ||
                            auth()->user()?->hasRole('super_admin')
                        )
                    )
                    ->action(function (User $record): void {
                        $record->update(['is_active' => ! $record->is_active]);

                        Notification::make()
                            ->title(
                                $record->is_active
                                    ? "{$record->name} activated"
                                    : "{$record->name} deactivated"
                            )
                            ->success()
                            ->send();
                    }),

                Action::make('reset_password')
                    ->label('Reset Password')
                    ->icon('heroicon-o-key')
                    ->color('gray')
                    ->form([
                        TextInput::make('new_password')
                            ->label('New Password')
                            ->password()
                            ->revealable()
                            ->required()
                            ->minLength(8),
                    ])
                    ->action(function (User $record, array $data): void {
                        $record->update([
                            'password' => Hash::make($data['new_password']),
                        ]);

                        Notification::make()
                            ->title("Password reset for {$record->name}")
                            ->success()
                            ->send();
                    })
                    ->visible(fn (User $record): bool =>
                        $record->role !== 'super_admin' ||
                        auth()->user()?->hasRole('super_admin')
                    ),
            ])
            ->defaultSort('role')
            ->groups([
                Tables\Grouping\Group::make('role')
                    ->label('Role')
                    ->getTitleFromRecordUsing(fn (User $record): string =>
                        ucwords(str_replace('_', ' ', $record->role))
                    ),
            ]);
    }

    public static function getPages(): array
    {
        return [
            'index'  => Pages\ListUsers::route('/'),
            'create' => Pages\CreateUser::route('/create'),
            'edit'   => Pages\EditUser::route('/{record}/edit'),
        ];
    }

    // ── Helpers ───────────────────────────────────────────────────

    /**
     * Role options shown in the form dropdown.
     * Admins cannot create/assign super_admin.
     */
    public static function availableRoleOptions(): array
    {
        $isSuperAdmin = auth()->user()?->hasRole('super_admin');

        $options = [
            'admin'      => 'Admin',
            'accountant' => 'Accountant',
            'cashier'    => 'Cashier',
            'warehouse'  => 'Warehouse',
            'staff'      => 'Staff',
            'director'   => 'Director',
        ];

        if ($isSuperAdmin) {
            $options = ['super_admin' => 'Super Admin'] + $options;
        }

        return $options;
    }
}