<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\V1;

use App\Domain\Account\Models\Account;
use App\Domain\Backup\Models\Backup;
use App\Http\Controllers\Controller;
use App\Http\Resources\Api\V1\BackupResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

/**
 * Backups resource — create, list, show, delete + restore action.
 */
class BackupsApiController extends Controller
{
    public function index(Request $request): JsonResponse
    {
        $this->requireAbility($request, 'backups:read');

        $query = Backup::query();
        $user = $request->user();

        if (! $user->hasRole('admin')) {
            $accountId = Account::where('owner_user_id', $user->id)->value('id');
            $query->where('account_id', $accountId);
        } elseif ($accountId = $request->integer('account_id')) {
            $query->where('account_id', $accountId);
        }

        if ($status = $request->get('status')) {
            $query->where('status', $status);
        }
        if ($type = $request->get('type')) {
            $query->where('type', $type);
        }

        $backups = $query->latest()->paginate($request->integer('per_page', 25));

        return BackupResource::collection($backups)->response();
    }

    public function show(Request $request, Backup $backup): JsonResponse
    {
        $this->requireAbility($request, 'backups:read');
        $this->authorizeScope($request, $backup->account_id);

        return (new BackupResource($backup))->response();
    }

    public function store(Request $request): JsonResponse
    {
        $this->requireAbility($request, 'backups:write');

        $validated = $request->validate([
            'account_id' => ['required', 'exists:accounts,id'],
            'type' => ['required', 'in:full,incremental,files,databases'],
        ]);

        $this->authorizeScope($request, (int) $validated['account_id']);

        $backup = Backup::create([
            'account_id' => $validated['account_id'],
            'type' => $validated['type'],
            'trigger' => 'api',
            'status' => 'pending',
            'started_at' => now(),
        ]);

        return (new BackupResource($backup))->response()->setStatusCode(201);
    }

    public function destroy(Request $request, Backup $backup): JsonResponse
    {
        $this->requireAbility($request, 'backups:write');
        $this->authorizeScope($request, $backup->account_id);

        $backup->delete();

        return response()->json(['data' => ['message' => 'Yedek silindi.']]);
    }

    public function restore(Request $request, Backup $backup): JsonResponse
    {
        $this->requireAbility($request, 'backups:write');
        $this->authorizeScope($request, $backup->account_id);

        if ($backup->status?->value !== 'completed') {
            return response()->json([
                'error' => [
                    'code' => 'BACKUP_NOT_READY',
                    'message' => 'Sadece tamamlanmış yedekler restore edilebilir.',
                ],
            ], 422);
        }

        // Restore job dispatch — Phase 3'te gerçek implementasyon
        $backup->update(['status' => 'restoring']);

        return response()->json([
            'data' => [
                'message' => 'Restore işlemi başlatıldı.',
                'backup' => new BackupResource($backup->fresh()),
            ],
        ]);
    }

    // ─── Helpers ─────────────────────────────────────────────────────────

    private function requireAbility(Request $request, string $ability): void
    {
        $token = $request->user()?->currentAccessToken();
        if ($token && ! in_array('*', $token->abilities, true) && ! in_array($ability, $token->abilities, true)) {
            abort(403, "Token için '{$ability}' yetkisi gerekli.");
        }
    }

    private function authorizeScope(Request $request, int $accountId): void
    {
        $user = $request->user();
        if ($user->hasRole('admin')) {
            return;
        }
        $ownAccountId = Account::where('owner_user_id', $user->id)->value('id');
        if ($ownAccountId !== $accountId) {
            abort(403, 'Bu kaynağa erişim yetkiniz yok.');
        }
    }
}
