<?php

declare(strict_types=1);

namespace App\Filament\System\Pages;

use App\Filament\System\Widgets\ControlTowerHealthIndicator;
use App\Filament\System\Widgets\ControlTowerKpis;
use App\Filament\System\Widgets\CustomerHealthKpis;
use App\Filament\System\Widgets\CustomerHealthTopWorkspaces;
use App\Filament\System\Widgets\ProductTelemetryKpis;
use App\Filament\System\Widgets\ControlTowerRecentFailures;
use App\Filament\System\Widgets\ControlTowerTopOffenders;
use App\Models\PlatformUser;
use App\Services\Auth\BreakGlassSession;
use App\Support\Auth\PlatformCapabilities;
use App\Support\SystemConsole\SystemConsoleWindow;
use Filament\Actions\Action;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Notifications\Notification;
use Filament\Pages\Dashboard as BaseDashboard;
use Filament\Widgets\Widget;
use Filament\Widgets\WidgetConfiguration;
use Illuminate\Database\Eloquent\Model;

class Dashboard extends BaseDashboard
{
    public string $window = SystemConsoleWindow::LastDay;

    public function getTitle(): string
    {
        return __('localization.dashboard.system_title');
    }

    /**
     * @param  array<mixed>  $parameters
     */
    public static function getUrl(array $parameters = [], bool $isAbsolute = true, ?string $panel = null, ?Model $tenant = null, bool $shouldGuessMissingParameters = false): string
    {
        return parent::getUrl($parameters, $isAbsolute, $panel ?? 'system', $tenant, $shouldGuessMissingParameters);
    }

    public static function canAccess(): bool
    {
        $user = auth('platform')->user();

        if (! $user instanceof PlatformUser) {
            return false;
        }

        if (! $user->hasCapability(PlatformCapabilities::ACCESS_SYSTEM_PANEL)) {
            return false;
        }

        return $user->hasCapability(PlatformCapabilities::CONSOLE_VIEW)
            || ($user->hasCapability(PlatformCapabilities::OPS_VIEW) && $user->hasCapability(PlatformCapabilities::RUNBOOKS_VIEW));
    }

    public function mount(): void
    {
        $this->window = SystemConsoleWindow::fromNullable((string) request()->query('window', $this->window))->value;
    }

    /**
     * @return array<class-string<Widget> | WidgetConfiguration>
     */
    public function getWidgets(): array
    {
        return [
            ControlTowerHealthIndicator::class,
            new WidgetConfiguration(CustomerHealthKpis::class, [
                'window' => $this->window,
            ]),
            new WidgetConfiguration(CustomerHealthTopWorkspaces::class, [
                'window' => $this->window,
            ]),
            new WidgetConfiguration(ControlTowerKpis::class, [
                'window' => $this->window,
            ]),
            new WidgetConfiguration(ProductTelemetryKpis::class, [
                'window' => $this->window,
            ]),
            new WidgetConfiguration(ControlTowerTopOffenders::class, [
                'window' => $this->window,
            ]),
            new WidgetConfiguration(ControlTowerRecentFailures::class, [
                'window' => $this->window,
            ]),
        ];
    }

    public function getColumns(): int|array
    {
        return 1;
    }

    public function selectedWindow(): SystemConsoleWindow
    {
        return SystemConsoleWindow::fromNullable($this->window);
    }

    /**
     * @return array<Action>
     */
    protected function getHeaderActions(): array
    {
        $breakGlass = app(BreakGlassSession::class);
        $user = auth('platform')->user();

        $canUseBreakGlass = $breakGlass->isEnabled()
            && $user instanceof PlatformUser
            && $user->hasCapability(PlatformCapabilities::USE_BREAK_GLASS);

        return [
            Action::make('set_window')
                ->label(__('localization.dashboard.time_window'))
                ->icon('heroicon-o-clock')
                ->color('gray')
                ->form([
                    Select::make('window')
                        ->label(__('localization.dashboard.window'))
                        ->options(SystemConsoleWindow::options())
                        ->default($this->window)
                        ->required(),
                ])
                ->action(function (array $data): void {
                    $window = SystemConsoleWindow::fromNullable((string) ($data['window'] ?? null));

                    $this->window = $window->value;

                    $this->redirect(static::getUrl([
                        'window' => $window->value,
                    ]));
                }),

            Action::make('enter_break_glass')
                ->label(__('localization.dashboard.enter_break_glass'))
                ->color('danger')
                ->visible(fn (): bool => $canUseBreakGlass && ! $breakGlass->isActive())
                ->requiresConfirmation()
                ->modalHeading('Enter break-glass mode')
                ->modalDescription('Recovery mode is time-limited and fully audited. Use for recovery only.')
                ->form([
                    Textarea::make('reason')
                        ->label('Reason')
                        ->required()
                        ->minLength(5)
                        ->maxLength(500)
                        ->rows(4),
                ])
                ->action(function (array $data, BreakGlassSession $breakGlass): void {
                    $user = auth('platform')->user();

                    if (! $user instanceof PlatformUser) {
                        abort(403);
                    }

                    if (! $user->hasCapability(PlatformCapabilities::USE_BREAK_GLASS)) {
                        abort(403);
                    }

                    $breakGlass->start($user, (string) ($data['reason'] ?? ''));

                    Notification::make()
                        ->title(__('localization.dashboard.recovery_mode_enabled'))
                        ->success()
                        ->send();
                }),

            Action::make('exit_break_glass')
                ->label(__('localization.dashboard.exit_break_glass'))
                ->color('gray')
                ->visible(fn (): bool => $canUseBreakGlass && $breakGlass->isActive())
                ->requiresConfirmation()
                ->modalHeading('Exit break-glass mode')
                ->modalDescription('This will immediately end recovery mode.')
                ->action(function (BreakGlassSession $breakGlass): void {
                    $user = auth('platform')->user();

                    if (! $user instanceof PlatformUser) {
                        abort(403);
                    }

                    $breakGlass->exit($user);

                    Notification::make()
                        ->title(__('localization.dashboard.recovery_mode_ended'))
                        ->success()
                        ->send();
                }),
        ];
    }
}
