<?php

declare(strict_types=1);

namespace App\Http\Controllers\Customer;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
use Laravel\Sanctum\PersonalAccessToken;

/**
 * Müşteri personal API token yönetimi.
 *
 * Müşterinin kendi hesabını programatik olarak yönetebilmesi için
 * (sadece kendi account scope'unda). Phase 3'te public REST API ile bağlantılı.
 *
 * Sanctum paketi opsiyoneldir — kurulu değilse "kurulum gerekli" sayfası gösterir.
 * Kurulum: composer require laravel/sanctum
 */
class ApiTokenController extends Controller
{
    private function sanctumAvailable(): bool
    {
        return class_exists(PersonalAccessToken::class)
            && method_exists(User::class, 'tokens');
    }

    /**
     * Müşteri için izin verilen ability'ler (admin'inkinden ayrı, daraltılmış).
     * Phase 3 Public REST API v1 ile uyumlu scope seti.
     */
    private const CUSTOMER_ABILITIES = [
        // ── Core ───────────────────────────────────────────────────────────
        'panel:read' => 'Hesap bilgilerini oku (kendi)',
        // ── Accounts (kendi hesap) ─────────────────────────────────────────
        'accounts:read' => 'Kendi hesap bilgilerini ve kullanım istatistiklerini oku',
        // ── Domains ────────────────────────────────────────────────────────
        'domains:read' => 'Domainleri listele',
        'domains:write' => 'Domain ekle / PHP versiyonu değiştir / sil',
        // ── Databases ──────────────────────────────────────────────────────
        'databases:read' => 'Veritabanlarını listele',
        'databases:write' => 'Veritabanı oluştur / kullanıcı ekle / sil',
        // ── DNS ─────────────────────────────────────────────────────────────
        'dns:read' => 'DNS kayıtlarını oku',
        'dns:write' => 'DNS kayıtları ekle / güncelle / sil',
        // ── SSL ─────────────────────────────────────────────────────────────
        'ssl:read' => 'SSL sertifikalarını listele',
        'ssl:write' => 'SSL sertifikası oluştur / yenile / sil',
        // ── FTP ─────────────────────────────────────────────────────────────
        'ftp:read' => 'FTP kullanıcılarını listele',
        'ftp:write' => 'FTP kullanıcısı oluştur / güncelle / sil',
        // ── Email ───────────────────────────────────────────────────────────
        'email:read' => 'E-posta hesaplarını ve yönlendiricileri listele',
        'email:write' => 'E-posta hesabı ve yönlendirici ekle / güncelle / sil',
        // ── Backups ─────────────────────────────────────────────────────────
        'backups:read' => 'Yedek listesi',
        'backups:write' => 'Yedek oluştur / restore et',
        // ── Files ───────────────────────────────────────────────────────────
        'files:read' => 'Dosyaları listele / oku',
        'files:write' => 'Dosya yükle / sil',
        // ── Apps ────────────────────────────────────────────────────────────
        'apps:read' => 'Kurulu uygulamaları listele',
        'apps:install' => 'Yeni uygulama kur',
    ];

    /** Tam erişim (tüm müşteri scope'ları) — kullanıcıya uyarı gösterilir. */
    private const FULL_ACCESS_ABILITY = '*';

    public function index(Request $request): Response
    {
        if (! $this->sanctumAvailable()) {
            return Inertia::render('Customer/Api/Tokens', [
                'tokens' => [],
                'sanctum_missing' => true,
                'available_abilities' => [],
            ]);
        }

        $user = $request->user();
        $tokens = $user->tokens()
            ->latest()
            ->get()
            ->map(fn ($t) => [
                'id' => $t->id,
                'name' => $t->name,
                'abilities' => $t->abilities,
                'last_used_at' => $t->last_used_at?->format('d.m.Y H:i'),
                'last_used_at_diff' => $t->last_used_at?->diffForHumans(),
                'expires_at' => $t->expires_at?->format('d.m.Y'),
                'expires_at_diff' => $t->expires_at?->diffForHumans(),
                'is_expired' => $t->expires_at?->isPast() ?? false,
                'created_at' => $t->created_at->format('d.m.Y H:i'),
            ]);

        // Tam erişim seçeneği başa eklenir — Vue bileşeni uyarı gösterir
        $abilities = collect(['*' => 'Tam erişim (Tüm yetkiler) — Dikkat: hesabınıza tam programatik erişim sağlar!'])
            ->merge(self::CUSTOMER_ABILITIES)
            ->map(fn ($desc, $key) => [
                'key' => $key,
                'description' => $desc,
                'is_dangerous' => $key === '*',
            ])
            ->values();

        return Inertia::render('Customer/Api/Tokens', [
            'tokens' => $tokens,
            'sanctum_missing' => false,
            'available_abilities' => $abilities,
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        if (! $this->sanctumAvailable()) {
            return back()->with('error', 'Laravel Sanctum kurulu değil. Yönetici composer require laravel/sanctum çalıştırmalı.');
        }

        $validated = $request->validate([
            'name' => ['required', 'string', 'max:100'],
            'abilities' => ['required', 'array', 'min:1'],
            'abilities.*' => ['string'],
            'expires_in_days' => ['nullable', 'integer', 'min:1', 'max:365'],
        ]);

        $requestedAbilities = $validated['abilities'];
        $allowedKeys = array_keys(self::CUSTOMER_ABILITIES);

        // Tam erişim ('*') seçildiyse sadece ['*'] ability'sini kullan
        if (in_array(self::FULL_ACCESS_ABILITY, $requestedAbilities, true)) {
            $abilities = [self::FULL_ACCESS_ABILITY];
        } else {
            // Sadece izin verilen ability'lere müsaade et
            $abilities = array_values(array_intersect($requestedAbilities, $allowedKeys));
        }

        if (empty($abilities)) {
            return back()->with('error', 'En az bir geçerli ability seçmelisiniz.');
        }

        $expiresAt = $validated['expires_in_days']
            ? now()->addDays($validated['expires_in_days'])
            : null;

        $token = $request->user()->createToken(
            $validated['name'],
            $abilities,
            $expiresAt,
        );

        $successMessage = 'Token oluşturuldu! Sadece bir kez gösterilir, kaydedin.';
        if ($abilities === [self::FULL_ACCESS_ABILITY]) {
            $successMessage = 'TAM ERİŞİM token\'ı oluşturuldu. Bu token hesabınıza tam erişim sağlar — güvende tutun!';
        }

        return back()
            ->with('success', $successMessage)
            ->with('new_token', $token->plainTextToken);
    }

    public function destroy(Request $request, int $id): RedirectResponse
    {
        if (! $this->sanctumAvailable()) {
            return back()->with('error', 'Laravel Sanctum kurulu değil.');
        }

        $token = $request->user()->tokens()->where('id', $id)->firstOrFail();
        $token->delete();

        return back()->with('success', 'Token iptal edildi.');
    }
}
