<?php

namespace App\Filament\SuperAdmin\Pages;

use App\Filament\Clusters\RareAdmin\RareAdminCluster;
use App\Models\InfrastructureActionLog;
use App\Services\Dokploy\DokployClient;
use BackedEnum;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Illuminate\Support\Arr;

class DokployDeployments extends Page
{
    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-wrench-screwdriver';

    protected static ?string $navigationLabel = 'Infrastructure';

    protected static ?string $title = 'Infrastructure Controls';

    protected static null|string|\UnitEnum $navigationGroup = null;

    protected static ?string $cluster = RareAdminCluster::class;

    protected string $view = 'filament.super-admin.pages.dokploy-deployments';

    public array $composes = [];

    public array $recentLogs = [];

    public ?string $dokployWebUrl = null;

    public static function getNavigationGroup(): \UnitEnum|string|null
    {
        return __('admin.nav.infrastructure');
    }

    public function mount(DokployClient $client): void
    {
        $this->dokployWebUrl = config('dokploy.web_url');
        $this->refreshComposes($client);
        $this->refreshLogs();
    }

    public function redeploy(string $composeId): void
    {
        $this->performAction($composeId, 'redeploy');
    }

    public function stop(string $composeId): void
    {
        $this->performAction($composeId, 'stop');
    }

    protected function performAction(string $composeId, string $action): void
    {
        $client = app(DokployClient::class);

        if (! $this->isKnownCompose($composeId)) {
            Notification::make()
                ->danger()
                ->title('Unknown service')
                ->body("The compose ID {$composeId} is not configured.")
                ->send();

            return;
        }

        try {
            match ($action) {
                'redeploy' => $client->redeployCompose($composeId, auth()->user()),
                'stop' => $client->stopCompose($composeId, auth()->user()),
                default => throw new \RuntimeException("Unsupported action [{$action}]"),
            };

            Notification::make()
                ->success()
                ->title(ucfirst($action).' requested')
                ->body("Dokploy accepted the {$action} action for {$composeId}.")
                ->send();
        } catch (\Throwable $exception) {
            Notification::make()
                ->danger()
                ->title('Dokploy request failed')
                ->body($exception->getMessage())
                ->send();
        }

        $this->refreshComposes($client);
        $this->refreshLogs();
    }

    protected function refreshComposes(DokployClient $client): void
    {
        $composeMap = config('dokploy.composes', []);
        $results = [];

        foreach ($composeMap as $label => $id) {
            try {
                $status = $client->composeStatus($id);
                $compose = Arr::get($status, 'compose', []);

                $results[] = [
                    'label' => ucfirst($label),
                    'compose_id' => $id,
                    'status' => Arr::get($compose, 'composeStatus', 'unknown'),
                ];
            } catch (\Throwable $e) {
                $results[] = [
                    'label' => ucfirst($label),
                    'compose_id' => $id,
                    'status' => 'error',
                ];
            }
        }

        $this->composes = $results;
    }

    protected function refreshLogs(): void
    {
        $this->recentLogs = InfrastructureActionLog::query()
            ->with('user')
            ->latest()
            ->limit(5)
            ->get()
            ->map(fn ($log) => [
                'created_at' => $log->created_at->diffForHumans(),
                'user' => $log->user?->name ?? 'System',
                'service_id' => $log->service_id,
                'action' => $log->action,
                'status_code' => $log->status_code,
            ])
            ->toArray();
    }

    protected function isKnownCompose(string $composeId): bool
    {
        return in_array($composeId, array_values(config('dokploy.composes', [])), true);
    }
}
