<?php

declare(strict_types=1);

namespace App\Http\Controllers\Admin;

use App\Domain\WebServer\Services\WebServerFactory;
use App\Domain\WebServer\Services\WebServerManager;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Inertia\Inertia;
use Inertia\Response;

/**
 * Admin → Web Sunucusu yönetimi.
 *
 * WHM-tarzı: kurulu adapter'ları gör, kurulu olmayanı kur, aktif olanı değiştir,
 * her birinin durumunu (running, enabled, version) anlık takip et.
 *
 * Endpoint'ler:
 *   GET    /admin/webserver               → kartlar + aktif adapter + son audit
 *   POST   /admin/webserver/install       → driver kur
 *   POST   /admin/webserver/uninstall     → driver kaldır
 *   POST   /admin/webserver/switch        → aktif adapter değiştir (+ vhost migration)
 *   POST   /admin/webserver/{action}      → start | stop | restart | reload | enable | disable
 *   POST   /admin/webserver/config-test   → aktif adapter configtest
 */
class WebServerController extends Controller
{
    public function __construct(
        private readonly WebServerFactory $factory,
        private readonly WebServerManager $manager,
    ) {}

    public function index(): Response
    {
        $adapters = $this->factory->listAll();
        $activeKey = $this->factory->activeKey();
        $active = $this->factory->make();

        $recentAudit = Schema::hasTable('license_audit_log')
            ? DB::table('license_audit_log')
                ->where('action', 'like', 'webserver.%')
                ->orderByDesc('id')
                ->limit(15)
                ->get()
            : collect();

        return Inertia::render('Admin/WebServer/Index', [
            'adapters' => $adapters,
            'active_key' => $activeKey,
            'active_name' => $active->name(),
            'active_running' => $active->isInstalled() ? $active->isRunning() : false,
            'active_enabled' => $active->isInstalled() ? $active->isEnabled() : false,
            'active_version' => $active->isInstalled() ? $active->version() : null,
            'recent_audit' => $recentAudit,
            'is_windows_dev' => PHP_OS_FAMILY === 'Windows',
        ]);
    }

    public function install(Request $request): RedirectResponse
    {
        $data = $request->validate([
            'driver' => 'required|string|in:' . implode(',', $this->factory->supportedDrivers()),
        ]);

        $result = $this->manager->install($data['driver']);

        if ($result['ok']) {
            $msg = $result['message'] ?? 'Kurulum başarılı.';

            return back()->with('success', $msg);
        }

        return back()->with('error', 'Kurulum başarısız: ' . ($result['error'] ?? 'Bilinmeyen hata'));
    }

    public function uninstall(Request $request): RedirectResponse
    {
        $data = $request->validate([
            'driver' => 'required|string|in:' . implode(',', $this->factory->supportedDrivers()),
        ]);

        $activeKey = $this->factory->activeKey();
        if ($activeKey === $data['driver']) {
            return back()->with('error', 'Aktif web sunucusunu kaldıramazsınız. Önce başka bir adapter\'a geçin.');
        }

        $adapter = $this->factory->makeByKey($data['driver']);
        if (! $adapter) {
            return back()->with('error', 'Bilinmeyen driver.');
        }

        $result = $adapter->uninstall();

        return $result['ok']
            ? back()->with('success', $adapter->name() . ' kaldırıldı.')
            : back()->with('error', 'Kaldırma başarısız: ' . ($result['output'] ?? ''));
    }

    public function switch(Request $request): RedirectResponse
    {
        $data = $request->validate([
            'driver' => 'required|string|in:' . implode(',', $this->factory->supportedDrivers()),
            'migrate_vhosts' => 'sometimes|boolean',
        ]);

        $result = $this->manager->switchTo(
            $data['driver'],
            (bool) ($data['migrate_vhosts'] ?? true)
        );

        if ($result['ok']) {
            return back()->with('success', $result['message']);
        }

        if (! empty($result['requires_install'])) {
            return back()->with('warning', $result['error']);
        }

        return back()->with('error', $result['error'] ?? 'Geçiş başarısız.');
    }

    public function action(Request $request, string $action): RedirectResponse
    {
        $allowed = ['start', 'stop', 'restart', 'reload', 'enable', 'disable'];
        if (! in_array($action, $allowed, true)) {
            return back()->with('error', 'Geçersiz eylem.');
        }

        $data = $request->validate([
            'driver' => 'sometimes|string|in:' . implode(',', $this->factory->supportedDrivers()),
        ]);

        $adapter = isset($data['driver'])
            ? $this->factory->makeByKey($data['driver'])
            : $this->factory->make();

        if (! $adapter) {
            return back()->with('error', 'Adapter bulunamadı.');
        }

        if (! $adapter->isInstalled() && ! in_array($action, ['enable', 'disable'], true)) {
            return back()->with('error', $adapter->name() . ' kurulu değil. Önce kurulum yapın.');
        }

        try {
            $adapter->{$action}();

            $labels = [
                'start' => 'başlatıldı',
                'stop' => 'durduruldu',
                'restart' => 'yeniden başlatıldı',
                'reload' => 'yeniden yüklendi',
                'enable' => 'sistem başlangıcına eklendi',
                'disable' => 'sistem başlangıcından çıkarıldı',
            ];

            return back()->with('success', $adapter->name() . ' ' . $labels[$action]);
        } catch (\Throwable $e) {
            return back()->with('error', $action . ' başarısız: ' . $e->getMessage());
        }
    }

    public function configTest(Request $request): RedirectResponse
    {
        $data = $request->validate([
            'driver' => 'sometimes|string|in:' . implode(',', $this->factory->supportedDrivers()),
        ]);

        $adapter = isset($data['driver'])
            ? $this->factory->makeByKey($data['driver'])
            : $this->factory->make();

        if (! $adapter || ! $adapter->isInstalled()) {
            return back()->with('error', 'Test edilecek adapter kurulu değil.');
        }

        $result = $adapter->configTest();

        return $result['ok']
            ? back()->with('success', 'Config geçerli: ' . substr($result['output'], 0, 200))
            : back()->with('error', 'Config hatalı: ' . substr($result['output'], 0, 200));
    }
}
