<?php

declare(strict_types=1);

namespace App\Http\Controllers\Account\Game;

use App\Http\Controllers\Controller;
use App\Models\ProvisioningLog;
use App\Models\Service;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Inertia\Inertia;
use Inertia\Response;

class GamePanelController extends Controller
{
    public function dashboard(Request $request, Service $service): Response
    {
        $this->authorize($request, $service);

        $activities = ProvisioningLog::where('service_id', $service->id)
            ->orderByDesc('created_at')
            ->limit(10)
            ->get()
            ->map(fn (ProvisioningLog $log): array => [
                'action' => $log->action,
                'timestamp' => $log->created_at->toISOString(),
                'details' => $log->status.($log->error_message ? ': '.$log->error_message : ''),
            ])
            ->toArray();

        return Inertia::render('Services/Game/Dashboard', [
            'service' => $service->load('plan', 'subscription'),
            'recentActivity' => $activities,
        ]);
    }

    public function console(Request $request, Service $service): Response
    {
        $this->authorize($request, $service);

        $consoleUrl = $this->safeApiCall(function () use ($service): ?string {
            return $this->fetchConsoleUrl($service);
        });

        return Inertia::render('Services/Game/Console', [
            'service' => $service->load('plan'),
            'consoleUrl' => $consoleUrl,
        ]);
    }

    public function files(Request $request, Service $service): Response
    {
        $this->authorize($request, $service);

        $directory = $request->query('path', '/');

        $fileList = $this->safeApiCall(function () use ($service, $directory): array {
            return $this->fetchFiles($service, (string) $directory);
        });

        return Inertia::render('Services/Game/Files', [
            'service' => $service->load('plan'),
            'files' => $fileList ?? [],
            'currentPath' => $directory,
        ]);
    }

    public function databases(Request $request, Service $service): Response
    {
        $this->authorize($request, $service);

        $databaseList = $this->safeApiCall(function () use ($service): array {
            return $this->fetchDatabases($service);
        });

        return Inertia::render('Services/Game/Databases', [
            'service' => $service->load('plan'),
            'databases' => $databaseList ?? [],
        ]);
    }

    public function backups(Request $request, Service $service): Response
    {
        $this->authorize($request, $service);

        $backupList = $this->safeApiCall(function () use ($service): array {
            return $this->fetchBackups($service);
        });

        return Inertia::render('Services/Game/Backups', [
            'service' => $service->load('plan'),
            'backups' => $backupList ?? [],
        ]);
    }

    public function schedules(Request $request, Service $service): Response
    {
        $this->authorize($request, $service);

        $scheduleList = $this->safeApiCall(function () use ($service): array {
            return $this->fetchSchedules($service);
        });

        return Inertia::render('Services/Game/Schedules', [
            'service' => $service->load('plan'),
            'schedules' => $scheduleList ?? [],
        ]);
    }

    public function startup(Request $request, Service $service): Response
    {
        $this->authorize($request, $service);

        $startupConfig = $this->safeApiCall(function () use ($service): array {
            return $this->fetchStartupConfig($service);
        });

        return Inertia::render('Services/Game/Startup', [
            'service' => $service->load('plan'),
            'startupConfig' => $startupConfig ?? [
                'startup_command' => '',
                'variables' => [],
            ],
        ]);
    }

    public function settings(Request $request, Service $service): Response
    {
        $this->authorize($request, $service);

        return Inertia::render('Services/Game/Settings', [
            'service' => $service->load('plan'),
        ]);
    }

    public function subUsers(Request $request, Service $service): Response
    {
        $this->authorize($request, $service);

        $users = $this->safeApiCall(function () use ($service): array {
            return $this->fetchSubUsers($service);
        });

        return Inertia::render('Services/Game/SubUsers', [
            'service' => $service->load('plan'),
            'subUsers' => $users ?? [],
        ]);
    }

    private function authorize(Request $request, Service $service): void
    {
        abort_unless($service->user_id === $request->user()->id, 403);
        abort_unless($service->service_type === 'game', 404);
    }

    /**
     * @template T
     *
     * @param  callable(): T  $callback
     * @return T|null
     */
    private function safeApiCall(callable $callback): mixed
    {
        try {
            return $callback();
        } catch (\Exception $e) {
            Log::warning('Game Panel API call failed', [
                'error' => $e->getMessage(),
            ]);

            return null;
        }
    }

    private function fetchConsoleUrl(Service $service): ?string
    {
        // Pterodactyl API: GET /api/client/servers/{id}/websocket
        return null;
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    private function fetchFiles(Service $service, string $directory): array
    {
        // Pterodactyl API: GET /api/client/servers/{id}/files/list?directory={path}
        return [];
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    private function fetchDatabases(Service $service): array
    {
        // Pterodactyl API: GET /api/client/servers/{id}/databases
        return [];
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    private function fetchBackups(Service $service): array
    {
        // Pterodactyl API: GET /api/client/servers/{id}/backups
        return [];
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    private function fetchSchedules(Service $service): array
    {
        // Pterodactyl API: GET /api/client/servers/{id}/schedules
        return [];
    }

    /**
     * @return array<string, mixed>
     */
    private function fetchStartupConfig(Service $service): array
    {
        // Pterodactyl API: GET /api/client/servers/{id}/startup
        return [
            'startup_command' => '',
            'variables' => [],
        ];
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    private function fetchSubUsers(Service $service): array
    {
        // Pterodactyl API: GET /api/client/servers/{id}/users
        return [];
    }
}
