<?php

declare(strict_types=1);

namespace App\Http\Controllers\Customer;

use App\Domain\Account\Models\Account;
use App\Domain\AppInstaller\Catalog\AppCatalog;
use App\Domain\AppInstaller\Models\InstalledApp;
use App\Domain\AppInstaller\Services\AppInstallerService;
use App\Domain\Domain\Models\Domain;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
use RuntimeException;

class AppInstallerController extends Controller
{
    public function __construct(private readonly AppInstallerService $service) {}

    public function catalog(Request $request): Response
    {
        return Inertia::render('Customer/Apps/Catalog', [
            'apps' => AppCatalog::all(),
            'grouped' => AppCatalog::grouped(),
        ]);
    }

    public function show(Request $request, string $slug): Response
    {
        $catalog = AppCatalog::find($slug);
        if (! $catalog) {
            abort(404);
        }

        /** @var Account $account */
        $account = $request->attributes->get('customer_account');

        $domains = Domain::where('account_id', $account->id)
            ->whereIn('type', ['main', 'addon', 'subdomain'])
            ->whereNull('deleted_at')
            ->get(['id', 'name', 'type', 'document_root']);

        return Inertia::render('Customer/Apps/Show', [
            'app' => $catalog,
            'domains' => $domains,
        ]);
    }

    public function installed(Request $request): Response
    {
        /** @var Account $account */
        $account = $request->attributes->get('customer_account');

        $apps = InstalledApp::where('account_id', $account->id)
            ->with(['domain:id,name', 'database:id,real_db_name'])
            ->whereNull('deleted_at')
            ->latest()
            ->get()
            ->map(function (InstalledApp $a) {
                $catalog = AppCatalog::find($a->app_type);

                return [
                    'id' => $a->id,
                    'app_type' => $a->app_type,
                    'app_name' => $catalog['name'] ?? $a->app_type,
                    'app_icon' => $catalog['icon_emoji'] ?? '📦',
                    'app_color' => $catalog['color'] ?? '#6366f1',
                    'version' => $a->version,
                    'install_url' => $a->install_url,
                    'install_path' => $a->install_path,
                    'domain_name' => $a->domain?->name,
                    'database_name' => $a->database?->real_db_name,
                    'admin_username' => $a->admin_username,
                    'admin_email' => $a->admin_email,
                    'site_title' => $a->site_title,
                    'status' => $a->status,
                    'updates_available' => $a->updates_available,
                    'latest_available_version' => $a->latest_available_version,
                    'installed_at' => $a->installed_at?->format('d.m.Y H:i'),
                ];
            });

        return Inertia::render('Customer/Apps/Installed', [
            'installed' => $apps,
        ]);
    }

    public function install(Request $request, string $slug): RedirectResponse
    {
        $catalog = AppCatalog::find($slug);
        if (! $catalog) {
            abort(404);
        }

        /** @var Account $account */
        $account = $request->attributes->get('customer_account');

        $validated = $request->validate([
            'domain_id' => ['required', 'integer'],
            'install_path' => ['nullable', 'string', 'max:191'],
            'version' => ['nullable', 'string', 'max:32'],
            'site_title' => ['nullable', 'string', 'max:191'],
            'admin_username' => ['nullable', 'string', 'max:100', 'regex:/^[a-zA-Z0-9_-]+$/'],
            'admin_email' => ['nullable', 'email'],
            'admin_password' => ['nullable', 'string', 'min:8'],
            'language' => ['nullable', 'string', 'max:10'],
        ]);

        try {
            $app = $this->service->install($account, $slug, $validated);

            return redirect()->route('customer.apps.installed')
                ->with('success', "{$catalog['name']} {$app->install_url} adresine başarıyla kuruldu.");
        } catch (RuntimeException $e) {
            return back()->with('error', $e->getMessage())->withInput();
        }
    }

    public function uninstall(Request $request, InstalledApp $app): RedirectResponse
    {
        /** @var Account $account */
        $account = $request->attributes->get('customer_account');
        if ($app->account_id !== $account->id) {
            abort(403);
        }

        $deleteDb = $request->boolean('delete_database', false);

        try {
            $this->service->uninstall($app, $deleteDb);

            return back()->with('success', 'Uygulama kaldırıldı.');
        } catch (RuntimeException $e) {
            return back()->with('error', $e->getMessage());
        }
    }
}
