<?php

declare(strict_types=1);

namespace App\Filament\System\Widgets;

use App\Models\PlatformUser;
use App\Support\Auth\PlatformCapabilities;
use App\Support\Badges\BadgeDomain;
use App\Support\Badges\BadgeRenderer;
use App\Support\CustomerHealth\WorkspaceHealthSummaryQuery;
use App\Support\SystemConsole\SystemConsoleWindow;
use App\Support\System\SystemOperationRunLinks;
use Filament\Widgets\Widget;

class CustomerHealthTopWorkspaces extends Widget
{
    protected static bool $isLazy = false;

    protected int|string|array $columnSpan = 'full';

    protected string $view = 'filament.system.widgets.customer-health-top-workspaces';

    public ?string $window = null;

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

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

        if ($user->hasCapability(PlatformCapabilities::DIRECTORY_VIEW)) {
            return true;
        }

        if (! static::canOpenRuns($user)) {
            return false;
        }

        $window = SystemConsoleWindow::fromNullable((string) request()->query('window'));

        return app(WorkspaceHealthSummaryQuery::class)
            ->attentionNeeded($window, 10)
            ->contains(fn (array $summary): bool => static::canAccessNextLink($summary['next_link'], $user));
    }

    /**
     * @return array<string, mixed>
     */
    protected function getViewData(): array
    {
        $window = SystemConsoleWindow::fromNullable($this->window ?? (string) request()->query('window'));
        $windowLabel = SystemConsoleWindow::options()[$window->value] ?? 'Last 24 hours';
        $user = auth('platform')->user();

        return [
            'windowLabel' => $windowLabel,
            'rows' => app(WorkspaceHealthSummaryQuery::class)
                ->attentionNeeded($window, 10)
                ->filter(fn (array $summary): bool => $user instanceof PlatformUser && static::canAccessNextLink($summary['next_link'], $user))
                ->map(fn (array $summary): array => $this->presentSummary($summary)),
        ];
    }

    /**
     * @param  array{label: string, url: string}  $nextLink
     */
    private static function canAccessNextLink(array $nextLink, PlatformUser $user): bool
    {
        if ($user->hasCapability(PlatformCapabilities::DIRECTORY_VIEW)) {
            return true;
        }

        return static::canOpenRuns($user)
            && $nextLink['url'] === SystemOperationRunLinks::index();
    }

    private static function canOpenRuns(PlatformUser $user): bool
    {
        return $user->hasCapability(PlatformCapabilities::OPERATIONS_VIEW)
            || ($user->hasCapability(PlatformCapabilities::OPS_VIEW) && $user->hasCapability(PlatformCapabilities::RUNBOOKS_VIEW));
    }

    /**
     * @param  array{
     *     workspace_id: int,
     *     workspace_name: string,
     *     overall_level: string,
     *     dimensions: array<string, array{label: string, level: string, windowed: bool}>,
     *     dominant_dimension_keys: list<string>,
     *     non_ok_dimension_count: int,
     *     next_link: array{label: string, url: string}
     * }  $summary
     * @return array{
     *     workspace_id: int,
     *     workspace_label: string,
     *     overall: array{label: string, color: string, icon: ?string},
     *     dominant_copy: string,
     *     dominant_dimensions: list<array{label: string, color: string, icon: ?string}>,
     *     next_link: array{label: string, url: string}
     * }
     */
    private function presentSummary(array $summary): array
    {
        $dominantDimensions = collect($summary['dominant_dimension_keys'])
            ->take(2)
            ->map(function (string $dimensionKey) use ($summary): array {
                $dimension = $summary['dimensions'][$dimensionKey];
                $badge = BadgeRenderer::spec(BadgeDomain::SystemHealth, $dimension['level']);

                return [
                    'label' => $dimension['label'],
                    'color' => $badge->color,
                    'icon' => $badge->icon,
                ];
            })
            ->values()
            ->all();

        $overallBadge = BadgeRenderer::spec(BadgeDomain::SystemHealth, $summary['overall_level']);

        return [
            'workspace_id' => $summary['workspace_id'],
            'workspace_label' => $summary['workspace_name'],
            'overall' => [
                'label' => $overallBadge->label,
                'color' => $overallBadge->color,
                'icon' => $overallBadge->icon,
            ],
            'dominant_copy' => implode(', ', array_column($dominantDimensions, 'label')),
            'dominant_dimensions' => $dominantDimensions,
            'next_link' => $summary['next_link'],
        ];
    }
}