<?php

declare(strict_types=1);

namespace App\Http\Controllers\Settings;

use App\Http\Controllers\Controller;
use App\Http\Requests\Academy\UpsertAcademyBadgeRequest;
use App\Http\Requests\Academy\UpsertAcademyCategoryRequest;
use App\Http\Requests\Academy\UpsertAcademyChallengeRequest;
use App\Http\Requests\Academy\UpsertAcademyLessonRequest;
use App\Http\Requests\Academy\UpsertAcademyPromptPackRequest;
use App\Http\Requests\Academy\UpsertAcademyPromptTemplateRequest;
use App\Models\AcademyBadge;
use App\Models\AcademyCategory;
use App\Models\AcademyChallenge;
use App\Models\AcademyChallengeSubmission;
use App\Models\AcademyLesson;
use App\Models\AcademyPromptPack;
use App\Models\AcademyPromptPackItem;
use App\Models\AcademyPromptTemplate;
use App\Services\Academy\AcademyCacheService;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

final class AcademyAdminController extends Controller
{
    public function __construct(private readonly AcademyCacheService $cache)
    {
    }

    public function dashboard(): Response
    {
        return Inertia::render('Admin/Academy/Dashboard', [
            'stats' => [
                'lessons' => AcademyLesson::query()->count(),
                'prompts' => AcademyPromptTemplate::query()->count(),
                'packs' => AcademyPromptPack::query()->count(),
                'challenges' => AcademyChallenge::query()->count(),
                'submissions' => AcademyChallengeSubmission::query()->count(),
                'badges' => AcademyBadge::query()->count(),
                'creator_subscribers' => 0,
                'pro_subscribers' => 0,
                'mrr' => 0,
            ],
            'links' => [
                'categories' => route('admin.academy.categories.index'),
                'lessons' => route('admin.academy.lessons.index'),
                'prompts' => route('admin.academy.prompts.index'),
                'packs' => route('admin.academy.packs.index'),
                'challenges' => route('admin.academy.challenges.index'),
                'submissions' => route('admin.academy.submissions.index'),
                'badges' => route('admin.academy.badges.index'),
            ],
        ]);
    }

    public function categoriesIndex(): Response
    {
        return $this->renderIndex('categories');
    }

    public function categoriesCreate(): Response
    {
        return $this->renderForm('categories', new AcademyCategory());
    }

    public function categoriesStore(UpsertAcademyCategoryRequest $request): RedirectResponse
    {
        $category = new AcademyCategory();
        $category->fill($request->validated())->save();
        $this->cache->clearAll();

        return redirect()->route('admin.academy.categories.edit', ['academyCategory' => $category])->with('success', 'Academy category created.');
    }

    public function categoriesEdit(AcademyCategory $academyCategory): Response
    {
        return $this->renderForm('categories', $academyCategory);
    }

    public function categoriesUpdate(UpsertAcademyCategoryRequest $request, AcademyCategory $academyCategory): RedirectResponse
    {
        $academyCategory->fill($request->validated())->save();
        $this->cache->clearAll();

        return redirect()->route('admin.academy.categories.edit', ['academyCategory' => $academyCategory])->with('success', 'Academy category updated.');
    }

    public function categoriesDestroy(AcademyCategory $academyCategory): RedirectResponse
    {
        $academyCategory->delete();
        $this->cache->clearAll();

        return redirect()->route('admin.academy.categories.index')->with('success', 'Academy category deleted.');
    }

    public function lessonsIndex(): Response
    {
        return $this->renderIndex('lessons');
    }

    public function lessonsCreate(): Response
    {
        return $this->renderForm('lessons', new AcademyLesson());
    }

    public function lessonsStore(UpsertAcademyLessonRequest $request): RedirectResponse
    {
        $lesson = new AcademyLesson();
        $lesson->fill($request->validated())->save();
        $this->cache->clearAll();

        return redirect()->route('admin.academy.lessons.edit', ['academyLesson' => $lesson])->with('success', 'Academy lesson created.');
    }

    public function lessonsEdit(AcademyLesson $academyLesson): Response
    {
        return $this->renderForm('lessons', $academyLesson);
    }

    public function lessonsUpdate(UpsertAcademyLessonRequest $request, AcademyLesson $academyLesson): RedirectResponse
    {
        $academyLesson->fill($request->validated())->save();
        $this->cache->clearAll();

        return redirect()->route('admin.academy.lessons.edit', ['academyLesson' => $academyLesson])->with('success', 'Academy lesson updated.');
    }

    public function lessonsDestroy(AcademyLesson $academyLesson): RedirectResponse
    {
        $academyLesson->delete();
        $this->cache->clearAll();

        return redirect()->route('admin.academy.lessons.index')->with('success', 'Academy lesson deleted.');
    }

    public function promptsIndex(): Response
    {
        return $this->renderIndex('prompts');
    }

    public function promptsCreate(): Response
    {
        return $this->renderForm('prompts', new AcademyPromptTemplate());
    }

    public function promptsStore(UpsertAcademyPromptTemplateRequest $request): RedirectResponse
    {
        $prompt = new AcademyPromptTemplate();
        $prompt->fill($request->validated())->save();
        $this->cache->clearAll();

        return redirect()->route('admin.academy.prompts.edit', ['academyPromptTemplate' => $prompt])->with('success', 'Academy prompt created.');
    }

    public function promptsEdit(AcademyPromptTemplate $academyPromptTemplate): Response
    {
        return $this->renderForm('prompts', $academyPromptTemplate);
    }

    public function promptsUpdate(UpsertAcademyPromptTemplateRequest $request, AcademyPromptTemplate $academyPromptTemplate): RedirectResponse
    {
        $academyPromptTemplate->fill($request->validated())->save();
        $this->cache->clearAll();

        return redirect()->route('admin.academy.prompts.edit', ['academyPromptTemplate' => $academyPromptTemplate])->with('success', 'Academy prompt updated.');
    }

    public function promptsDestroy(AcademyPromptTemplate $academyPromptTemplate): RedirectResponse
    {
        $academyPromptTemplate->delete();
        $this->cache->clearAll();

        return redirect()->route('admin.academy.prompts.index')->with('success', 'Academy prompt deleted.');
    }

    public function packsIndex(): Response
    {
        return $this->renderIndex('packs');
    }

    public function packsCreate(): Response
    {
        return $this->renderForm('packs', new AcademyPromptPack());
    }

    public function packsStore(UpsertAcademyPromptPackRequest $request): RedirectResponse
    {
        $pack = new AcademyPromptPack();
        $pack->fill(collect($request->validated())->except('prompt_ids')->all())->save();
        $this->syncPackItems($pack, $request->validated('prompt_ids', []));
        $this->cache->clearAll();

        return redirect()->route('admin.academy.packs.edit', ['academyPromptPack' => $pack])->with('success', 'Academy prompt pack created.');
    }

    public function packsEdit(AcademyPromptPack $academyPromptPack): Response
    {
        $academyPromptPack->load('prompts');

        return $this->renderForm('packs', $academyPromptPack);
    }

    public function packsUpdate(UpsertAcademyPromptPackRequest $request, AcademyPromptPack $academyPromptPack): RedirectResponse
    {
        $academyPromptPack->fill(collect($request->validated())->except('prompt_ids')->all())->save();
        $this->syncPackItems($academyPromptPack, $request->validated('prompt_ids', []));
        $this->cache->clearAll();

        return redirect()->route('admin.academy.packs.edit', ['academyPromptPack' => $academyPromptPack])->with('success', 'Academy prompt pack updated.');
    }

    public function packsDestroy(AcademyPromptPack $academyPromptPack): RedirectResponse
    {
        $academyPromptPack->delete();
        $this->cache->clearAll();

        return redirect()->route('admin.academy.packs.index')->with('success', 'Academy prompt pack deleted.');
    }

    public function challengesIndex(): Response
    {
        return $this->renderIndex('challenges');
    }

    public function challengesCreate(): Response
    {
        return $this->renderForm('challenges', new AcademyChallenge());
    }

    public function challengesStore(UpsertAcademyChallengeRequest $request): RedirectResponse
    {
        $challenge = new AcademyChallenge();
        $challenge->fill($request->validated())->save();
        $this->cache->clearAll();

        return redirect()->route('admin.academy.challenges.edit', ['academyChallenge' => $challenge])->with('success', 'Academy challenge created.');
    }

    public function challengesEdit(AcademyChallenge $academyChallenge): Response
    {
        return $this->renderForm('challenges', $academyChallenge);
    }

    public function challengesUpdate(UpsertAcademyChallengeRequest $request, AcademyChallenge $academyChallenge): RedirectResponse
    {
        $academyChallenge->fill($request->validated())->save();
        $this->cache->clearAll();

        return redirect()->route('admin.academy.challenges.edit', ['academyChallenge' => $academyChallenge])->with('success', 'Academy challenge updated.');
    }

    public function challengesDestroy(AcademyChallenge $academyChallenge): RedirectResponse
    {
        $academyChallenge->delete();
        $this->cache->clearAll();

        return redirect()->route('admin.academy.challenges.index')->with('success', 'Academy challenge deleted.');
    }

    public function badgesIndex(): Response
    {
        return $this->renderIndex('badges');
    }

    public function badgesCreate(): Response
    {
        return $this->renderForm('badges', new AcademyBadge());
    }

    public function badgesStore(UpsertAcademyBadgeRequest $request): RedirectResponse
    {
        $badge = new AcademyBadge();
        $badge->fill($request->validated())->save();

        return redirect()->route('admin.academy.badges.edit', ['academyBadge' => $badge])->with('success', 'Academy badge created.');
    }

    public function badgesEdit(AcademyBadge $academyBadge): Response
    {
        return $this->renderForm('badges', $academyBadge);
    }

    public function badgesUpdate(UpsertAcademyBadgeRequest $request, AcademyBadge $academyBadge): RedirectResponse
    {
        $academyBadge->fill($request->validated())->save();

        return redirect()->route('admin.academy.badges.edit', ['academyBadge' => $academyBadge])->with('success', 'Academy badge updated.');
    }

    public function badgesDestroy(AcademyBadge $academyBadge): RedirectResponse
    {
        $academyBadge->delete();

        return redirect()->route('admin.academy.badges.index')->with('success', 'Academy badge deleted.');
    }

    public function submissionsIndex(Request $request): Response
    {
        $submissions = AcademyChallengeSubmission::query()
            ->with(['challenge', 'artwork', 'user'])
            ->latest('submitted_at')
            ->paginate(25)
            ->withQueryString();

        $submissions->getCollection()->transform(fn (AcademyChallengeSubmission $submission): array => [
            'id' => (int) $submission->id,
            'moderation_status' => (string) $submission->moderation_status,
            'submitted_at' => $submission->submitted_at?->toISOString(),
            'ai_tool_used' => (string) ($submission->ai_tool_used ?? ''),
            'prompt_used' => (string) ($submission->prompt_used ?? ''),
            'workflow_notes' => (string) ($submission->workflow_notes ?? ''),
            'challenge' => $submission->challenge ? [
                'title' => (string) $submission->challenge->title,
                'slug' => (string) $submission->challenge->slug,
            ] : null,
            'user' => $submission->user ? [
                'name' => (string) $submission->user->name,
                'username' => (string) ($submission->user->username ?? ''),
            ] : null,
            'artwork' => $submission->artwork ? [
                'id' => (int) $submission->artwork->id,
                'title' => (string) ($submission->artwork->title ?? 'Untitled artwork'),
                'thumb_url' => $submission->artwork->thumbUrl('sm'),
            ] : null,
            'approve_url' => route('admin.academy.submissions.approve', ['academyChallengeSubmission' => $submission]),
            'reject_url' => route('admin.academy.submissions.reject', ['academyChallengeSubmission' => $submission]),
        ]);

        return Inertia::render('Admin/Academy/Submissions', [
            'submissions' => $submissions,
        ]);
    }

    public function approveSubmission(AcademyChallengeSubmission $academyChallengeSubmission): RedirectResponse
    {
        $academyChallengeSubmission->forceFill(['moderation_status' => 'approved'])->save();

        return back()->with('success', 'Challenge submission approved.');
    }

    public function rejectSubmission(AcademyChallengeSubmission $academyChallengeSubmission): RedirectResponse
    {
        $academyChallengeSubmission->forceFill(['moderation_status' => 'rejected'])->save();

        return back()->with('success', 'Challenge submission rejected.');
    }

    private function renderIndex(string $resource): Response
    {
        $meta = $this->resourceMeta($resource);
        $items = $meta['model']::query()->latest('updated_at')->paginate(25)->withQueryString();
        $items->getCollection()->transform(fn (Model $model): array => $this->serializeIndexItem($resource, $model));

        return Inertia::render('Admin/Academy/CrudIndex', [
            'resource' => $resource,
            'title' => $meta['title'],
            'subtitle' => $meta['subtitle'],
            'items' => $items,
            'columns' => $meta['columns'],
            'createUrl' => route($meta['route_base'] . '.create'),
        ]);
    }

    private function renderForm(string $resource, Model $record): Response
    {
        $meta = $this->resourceMeta($resource);

        return Inertia::render('Admin/Academy/CrudForm', [
            'resource' => $resource,
            'title' => $record->exists ? 'Edit ' . $meta['singular'] : 'Create ' . $meta['singular'],
            'subtitle' => $meta['subtitle'],
            'fields' => $meta['fields'],
            'record' => $this->serializeFormRecord($resource, $record),
            'submitUrl' => $record->exists ? route($meta['route_base'] . '.update', $this->routeParams($resource, $record)) : route($meta['route_base'] . '.store'),
            'indexUrl' => route($meta['route_base'] . '.index'),
            'destroyUrl' => $record->exists ? route($meta['route_base'] . '.destroy', $this->routeParams($resource, $record)) : null,
            'method' => $record->exists ? 'patch' : 'post',
        ]);
    }

    private function resourceMeta(string $resource): array
    {
        return match ($resource) {
            'categories' => [
                'model' => AcademyCategory::class,
                'title' => 'Academy Categories',
                'singular' => 'category',
                'subtitle' => 'Manage lesson, prompt, pack, and challenge categories.',
                'route_base' => 'admin.academy.categories',
                'columns' => ['name', 'type', 'slug', 'active'],
                'fields' => [
                    ['name' => 'type', 'label' => 'Type', 'type' => 'select', 'options' => [['value' => 'lesson', 'label' => 'Lesson'], ['value' => 'prompt', 'label' => 'Prompt'], ['value' => 'challenge', 'label' => 'Challenge'], ['value' => 'pack', 'label' => 'Pack']]],
                    ['name' => 'name', 'label' => 'Name', 'type' => 'text'],
                    ['name' => 'slug', 'label' => 'Slug', 'type' => 'text'],
                    ['name' => 'description', 'label' => 'Description', 'type' => 'textarea'],
                    ['name' => 'icon', 'label' => 'Icon', 'type' => 'text'],
                    ['name' => 'order_num', 'label' => 'Order', 'type' => 'number'],
                    ['name' => 'active', 'label' => 'Active', 'type' => 'checkbox'],
                ],
            ],
            'lessons' => [
                'model' => AcademyLesson::class,
                'title' => 'Academy Lessons',
                'singular' => 'lesson',
                'subtitle' => 'Create and publish Academy lessons.',
                'route_base' => 'admin.academy.lessons',
                'columns' => ['title', 'difficulty', 'access_level', 'featured', 'active'],
                'fields' => [
                    ['name' => 'category_id', 'label' => 'Category', 'type' => 'select', 'options' => $this->categoryOptions('lesson')],
                    ['name' => 'title', 'label' => 'Title', 'type' => 'text'],
                    ['name' => 'slug', 'label' => 'Slug', 'type' => 'text'],
                    ['name' => 'excerpt', 'label' => 'Excerpt', 'type' => 'textarea'],
                    ['name' => 'content', 'label' => 'Content', 'type' => 'textarea'],
                    ['name' => 'difficulty', 'label' => 'Difficulty', 'type' => 'select', 'options' => $this->difficultyOptions()],
                    ['name' => 'access_level', 'label' => 'Access', 'type' => 'select', 'options' => $this->accessOptions()],
                    ['name' => 'lesson_type', 'label' => 'Lesson Type', 'type' => 'text'],
                    ['name' => 'cover_image', 'label' => 'Cover Image', 'type' => 'text'],
                    ['name' => 'video_url', 'label' => 'Video URL', 'type' => 'text'],
                    ['name' => 'reading_minutes', 'label' => 'Reading Minutes', 'type' => 'number'],
                    ['name' => 'published_at', 'label' => 'Published At', 'type' => 'datetime-local'],
                    ['name' => 'seo_title', 'label' => 'SEO Title', 'type' => 'text'],
                    ['name' => 'seo_description', 'label' => 'SEO Description', 'type' => 'textarea'],
                    ['name' => 'featured', 'label' => 'Featured', 'type' => 'checkbox'],
                    ['name' => 'active', 'label' => 'Active', 'type' => 'checkbox'],
                ],
            ],
            'prompts' => [
                'model' => AcademyPromptTemplate::class,
                'title' => 'Academy Prompt Templates',
                'singular' => 'prompt template',
                'subtitle' => 'Manage prompt previews, premium prompts, and prompt of the week.',
                'route_base' => 'admin.academy.prompts',
                'columns' => ['title', 'difficulty', 'access_level', 'prompt_of_week', 'active'],
                'fields' => [
                    ['name' => 'category_id', 'label' => 'Category', 'type' => 'select', 'options' => $this->categoryOptions('prompt')],
                    ['name' => 'title', 'label' => 'Title', 'type' => 'text'],
                    ['name' => 'slug', 'label' => 'Slug', 'type' => 'text'],
                    ['name' => 'excerpt', 'label' => 'Excerpt', 'type' => 'textarea'],
                    ['name' => 'prompt', 'label' => 'Prompt', 'type' => 'textarea'],
                    ['name' => 'negative_prompt', 'label' => 'Negative Prompt', 'type' => 'textarea'],
                    ['name' => 'usage_notes', 'label' => 'Usage Notes', 'type' => 'textarea'],
                    ['name' => 'workflow_notes', 'label' => 'Workflow Notes', 'type' => 'textarea'],
                    ['name' => 'difficulty', 'label' => 'Difficulty', 'type' => 'select', 'options' => $this->difficultyOptions()],
                    ['name' => 'access_level', 'label' => 'Access', 'type' => 'select', 'options' => $this->accessOptions()],
                    ['name' => 'aspect_ratio', 'label' => 'Aspect Ratio', 'type' => 'text'],
                    ['name' => 'tags', 'label' => 'Tags', 'type' => 'csv'],
                    ['name' => 'preview_image', 'label' => 'Preview Image', 'type' => 'text'],
                    ['name' => 'published_at', 'label' => 'Published At', 'type' => 'datetime-local'],
                    ['name' => 'seo_title', 'label' => 'SEO Title', 'type' => 'text'],
                    ['name' => 'seo_description', 'label' => 'SEO Description', 'type' => 'textarea'],
                    ['name' => 'featured', 'label' => 'Featured', 'type' => 'checkbox'],
                    ['name' => 'prompt_of_week', 'label' => 'Prompt Of Week', 'type' => 'checkbox'],
                    ['name' => 'active', 'label' => 'Active', 'type' => 'checkbox'],
                ],
            ],
            'packs' => [
                'model' => AcademyPromptPack::class,
                'title' => 'Academy Prompt Packs',
                'singular' => 'prompt pack',
                'subtitle' => 'Bundle Academy prompts into reusable packs.',
                'route_base' => 'admin.academy.packs',
                'columns' => ['title', 'access_level', 'featured', 'active'],
                'fields' => [
                    ['name' => 'title', 'label' => 'Title', 'type' => 'text'],
                    ['name' => 'slug', 'label' => 'Slug', 'type' => 'text'],
                    ['name' => 'excerpt', 'label' => 'Excerpt', 'type' => 'textarea'],
                    ['name' => 'description', 'label' => 'Description', 'type' => 'textarea'],
                    ['name' => 'access_level', 'label' => 'Access', 'type' => 'select', 'options' => $this->accessOptions()],
                    ['name' => 'one_time_price_cents', 'label' => 'One-time Price (cents)', 'type' => 'number'],
                    ['name' => 'currency', 'label' => 'Currency', 'type' => 'text'],
                    ['name' => 'cover_image', 'label' => 'Cover Image', 'type' => 'text'],
                    ['name' => 'tags', 'label' => 'Tags', 'type' => 'csv'],
                    ['name' => 'prompt_ids', 'label' => 'Prompt Templates', 'type' => 'multiselect', 'options' => $this->promptOptions()],
                    ['name' => 'published_at', 'label' => 'Published At', 'type' => 'datetime-local'],
                    ['name' => 'featured', 'label' => 'Featured', 'type' => 'checkbox'],
                    ['name' => 'active', 'label' => 'Active', 'type' => 'checkbox'],
                ],
            ],
            'challenges' => [
                'model' => AcademyChallenge::class,
                'title' => 'Academy Challenges',
                'singular' => 'challenge',
                'subtitle' => 'Create and moderate Academy challenge briefs.',
                'route_base' => 'admin.academy.challenges',
                'columns' => ['title', 'status', 'access_level', 'featured', 'active'],
                'fields' => [
                    ['name' => 'title', 'label' => 'Title', 'type' => 'text'],
                    ['name' => 'slug', 'label' => 'Slug', 'type' => 'text'],
                    ['name' => 'excerpt', 'label' => 'Excerpt', 'type' => 'textarea'],
                    ['name' => 'description', 'label' => 'Description', 'type' => 'textarea'],
                    ['name' => 'brief', 'label' => 'Brief', 'type' => 'textarea'],
                    ['name' => 'rules', 'label' => 'Rules', 'type' => 'textarea'],
                    ['name' => 'access_level', 'label' => 'Access', 'type' => 'select', 'options' => $this->accessOptions()],
                    ['name' => 'status', 'label' => 'Status', 'type' => 'select', 'options' => [['value' => 'draft', 'label' => 'Draft'], ['value' => 'scheduled', 'label' => 'Scheduled'], ['value' => 'active', 'label' => 'Active'], ['value' => 'voting', 'label' => 'Voting'], ['value' => 'completed', 'label' => 'Completed'], ['value' => 'archived', 'label' => 'Archived']]],
                    ['name' => 'starts_at', 'label' => 'Starts At', 'type' => 'datetime-local'],
                    ['name' => 'ends_at', 'label' => 'Ends At', 'type' => 'datetime-local'],
                    ['name' => 'voting_starts_at', 'label' => 'Voting Starts At', 'type' => 'datetime-local'],
                    ['name' => 'voting_ends_at', 'label' => 'Voting Ends At', 'type' => 'datetime-local'],
                    ['name' => 'cover_image', 'label' => 'Cover Image', 'type' => 'text'],
                    ['name' => 'prize_text', 'label' => 'Prize Text', 'type' => 'text'],
                    ['name' => 'required_tags', 'label' => 'Required Tags', 'type' => 'csv'],
                    ['name' => 'allowed_categories', 'label' => 'Allowed Categories', 'type' => 'csv'],
                    ['name' => 'featured', 'label' => 'Featured', 'type' => 'checkbox'],
                    ['name' => 'active', 'label' => 'Active', 'type' => 'checkbox'],
                ],
            ],
            'badges' => [
                'model' => AcademyBadge::class,
                'title' => 'Academy Badges',
                'singular' => 'badge',
                'subtitle' => 'Define Academy plan and achievement badges.',
                'route_base' => 'admin.academy.badges',
                'columns' => ['name', 'badge_type', 'slug', 'active'],
                'fields' => [
                    ['name' => 'name', 'label' => 'Name', 'type' => 'text'],
                    ['name' => 'slug', 'label' => 'Slug', 'type' => 'text'],
                    ['name' => 'description', 'label' => 'Description', 'type' => 'textarea'],
                    ['name' => 'icon', 'label' => 'Icon', 'type' => 'text'],
                    ['name' => 'badge_type', 'label' => 'Badge Type', 'type' => 'text'],
                    ['name' => 'rules', 'label' => 'Rules JSON', 'type' => 'json'],
                    ['name' => 'active', 'label' => 'Active', 'type' => 'checkbox'],
                ],
            ],
            default => throw new \InvalidArgumentException('Unknown Academy resource [' . $resource . '].'),
        };
    }

    private function serializeIndexItem(string $resource, Model $model): array
    {
        return match ($resource) {
            'categories' => [
                'id' => (int) $model->id,
                'name' => (string) $model->name,
                'type' => (string) $model->type,
                'slug' => (string) $model->slug,
                'active' => (bool) $model->active,
                'edit_url' => route('admin.academy.categories.edit', ['academyCategory' => $model]),
                'destroy_url' => route('admin.academy.categories.destroy', ['academyCategory' => $model]),
            ],
            'lessons' => [
                'id' => (int) $model->id,
                'title' => (string) $model->title,
                'difficulty' => (string) $model->difficulty,
                'access_level' => (string) $model->access_level,
                'featured' => (bool) $model->featured,
                'active' => (bool) $model->active,
                'edit_url' => route('admin.academy.lessons.edit', ['academyLesson' => $model]),
                'destroy_url' => route('admin.academy.lessons.destroy', ['academyLesson' => $model]),
            ],
            'prompts' => [
                'id' => (int) $model->id,
                'title' => (string) $model->title,
                'difficulty' => (string) $model->difficulty,
                'access_level' => (string) $model->access_level,
                'prompt_of_week' => (bool) $model->prompt_of_week,
                'active' => (bool) $model->active,
                'edit_url' => route('admin.academy.prompts.edit', ['academyPromptTemplate' => $model]),
                'destroy_url' => route('admin.academy.prompts.destroy', ['academyPromptTemplate' => $model]),
            ],
            'packs' => [
                'id' => (int) $model->id,
                'title' => (string) $model->title,
                'access_level' => (string) $model->access_level,
                'featured' => (bool) $model->featured,
                'active' => (bool) $model->active,
                'edit_url' => route('admin.academy.packs.edit', ['academyPromptPack' => $model]),
                'destroy_url' => route('admin.academy.packs.destroy', ['academyPromptPack' => $model]),
            ],
            'challenges' => [
                'id' => (int) $model->id,
                'title' => (string) $model->title,
                'status' => (string) $model->status,
                'access_level' => (string) $model->access_level,
                'featured' => (bool) $model->featured,
                'active' => (bool) $model->active,
                'edit_url' => route('admin.academy.challenges.edit', ['academyChallenge' => $model]),
                'destroy_url' => route('admin.academy.challenges.destroy', ['academyChallenge' => $model]),
            ],
            'badges' => [
                'id' => (int) $model->id,
                'name' => (string) $model->name,
                'badge_type' => (string) $model->badge_type,
                'slug' => (string) $model->slug,
                'active' => (bool) $model->active,
                'edit_url' => route('admin.academy.badges.edit', ['academyBadge' => $model]),
                'destroy_url' => route('admin.academy.badges.destroy', ['academyBadge' => $model]),
            ],
            default => [],
        };
    }

    private function serializeFormRecord(string $resource, Model $record): array
    {
        return match ($resource) {
            'categories' => [
                'type' => (string) ($record->type ?? 'lesson'),
                'name' => (string) ($record->name ?? ''),
                'slug' => (string) ($record->slug ?? ''),
                'description' => (string) ($record->description ?? ''),
                'icon' => (string) ($record->icon ?? ''),
                'order_num' => (int) ($record->order_num ?? 0),
                'active' => (bool) ($record->active ?? true),
            ],
            'lessons' => [
                'category_id' => $record->category_id,
                'title' => (string) ($record->title ?? ''),
                'slug' => (string) ($record->slug ?? ''),
                'excerpt' => (string) ($record->excerpt ?? ''),
                'content' => (string) ($record->content ?? ''),
                'difficulty' => (string) ($record->difficulty ?? 'beginner'),
                'access_level' => (string) ($record->access_level ?? 'free'),
                'lesson_type' => (string) ($record->lesson_type ?? 'article'),
                'cover_image' => (string) ($record->cover_image ?? ''),
                'video_url' => (string) ($record->video_url ?? ''),
                'reading_minutes' => (int) ($record->reading_minutes ?? 5),
                'published_at' => optional($record->published_at)?->format('Y-m-d\TH:i'),
                'seo_title' => (string) ($record->seo_title ?? ''),
                'seo_description' => (string) ($record->seo_description ?? ''),
                'featured' => (bool) ($record->featured ?? false),
                'active' => (bool) ($record->active ?? true),
            ],
            'prompts' => [
                'category_id' => $record->category_id,
                'title' => (string) ($record->title ?? ''),
                'slug' => (string) ($record->slug ?? ''),
                'excerpt' => (string) ($record->excerpt ?? ''),
                'prompt' => (string) ($record->prompt ?? ''),
                'negative_prompt' => (string) ($record->negative_prompt ?? ''),
                'usage_notes' => (string) ($record->usage_notes ?? ''),
                'workflow_notes' => (string) ($record->workflow_notes ?? ''),
                'difficulty' => (string) ($record->difficulty ?? 'beginner'),
                'access_level' => (string) ($record->access_level ?? 'free'),
                'aspect_ratio' => (string) ($record->aspect_ratio ?? ''),
                'tags' => implode(', ', (array) ($record->tags ?? [])),
                'preview_image' => (string) ($record->preview_image ?? ''),
                'published_at' => optional($record->published_at)?->format('Y-m-d\TH:i'),
                'seo_title' => (string) ($record->seo_title ?? ''),
                'seo_description' => (string) ($record->seo_description ?? ''),
                'featured' => (bool) ($record->featured ?? false),
                'prompt_of_week' => (bool) ($record->prompt_of_week ?? false),
                'active' => (bool) ($record->active ?? true),
            ],
            'packs' => [
                'title' => (string) ($record->title ?? ''),
                'slug' => (string) ($record->slug ?? ''),
                'excerpt' => (string) ($record->excerpt ?? ''),
                'description' => (string) ($record->description ?? ''),
                'access_level' => (string) ($record->access_level ?? 'creator'),
                'one_time_price_cents' => $record->one_time_price_cents,
                'currency' => (string) ($record->currency ?? 'EUR'),
                'cover_image' => (string) ($record->cover_image ?? ''),
                'tags' => implode(', ', (array) ($record->tags ?? [])),
                'prompt_ids' => $record instanceof AcademyPromptPack ? $record->prompts->pluck('id')->all() : [],
                'published_at' => optional($record->published_at)?->format('Y-m-d\TH:i'),
                'featured' => (bool) ($record->featured ?? false),
                'active' => (bool) ($record->active ?? true),
            ],
            'challenges' => [
                'title' => (string) ($record->title ?? ''),
                'slug' => (string) ($record->slug ?? ''),
                'excerpt' => (string) ($record->excerpt ?? ''),
                'description' => (string) ($record->description ?? ''),
                'brief' => (string) ($record->brief ?? ''),
                'rules' => (string) ($record->rules ?? ''),
                'access_level' => (string) ($record->access_level ?? 'free'),
                'status' => (string) ($record->status ?? 'draft'),
                'starts_at' => optional($record->starts_at)?->format('Y-m-d\TH:i'),
                'ends_at' => optional($record->ends_at)?->format('Y-m-d\TH:i'),
                'voting_starts_at' => optional($record->voting_starts_at)?->format('Y-m-d\TH:i'),
                'voting_ends_at' => optional($record->voting_ends_at)?->format('Y-m-d\TH:i'),
                'cover_image' => (string) ($record->cover_image ?? ''),
                'prize_text' => (string) ($record->prize_text ?? ''),
                'required_tags' => implode(', ', (array) ($record->required_tags ?? [])),
                'allowed_categories' => implode(', ', (array) ($record->allowed_categories ?? [])),
                'featured' => (bool) ($record->featured ?? false),
                'active' => (bool) ($record->active ?? true),
            ],
            'badges' => [
                'name' => (string) ($record->name ?? ''),
                'slug' => (string) ($record->slug ?? ''),
                'description' => (string) ($record->description ?? ''),
                'icon' => (string) ($record->icon ?? ''),
                'badge_type' => (string) ($record->badge_type ?? 'achievement'),
                'rules' => json_encode((array) ($record->rules ?? []), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES),
                'active' => (bool) ($record->active ?? true),
            ],
            default => [],
        };
    }

    private function routeParams(string $resource, Model $record): array
    {
        return match ($resource) {
            'categories' => ['academyCategory' => $record],
            'lessons' => ['academyLesson' => $record],
            'prompts' => ['academyPromptTemplate' => $record],
            'packs' => ['academyPromptPack' => $record],
            'challenges' => ['academyChallenge' => $record],
            'badges' => ['academyBadge' => $record],
            default => [],
        };
    }

    private function categoryOptions(string $type): array
    {
        return AcademyCategory::query()
            ->where('type', $type)
            ->orderBy('order_num')
            ->orderBy('name')
            ->get()
            ->map(fn (AcademyCategory $category): array => ['value' => $category->id, 'label' => $category->name])
            ->prepend(['value' => '', 'label' => 'No category'])
            ->values()
            ->all();
    }

    private function promptOptions(): array
    {
        return AcademyPromptTemplate::query()
            ->orderBy('title')
            ->get()
            ->map(fn (AcademyPromptTemplate $prompt): array => ['value' => $prompt->id, 'label' => $prompt->title])
            ->values()
            ->all();
    }

    private function difficultyOptions(): array
    {
        return collect((array) config('academy.difficulty_levels', []))
            ->map(fn (string $value): array => ['value' => $value, 'label' => ucfirst($value)])
            ->values()
            ->all();
    }

    private function accessOptions(): array
    {
        return [
            ['value' => 'free', 'label' => 'Free'],
            ['value' => 'creator', 'label' => 'Creator'],
            ['value' => 'pro', 'label' => 'Pro'],
        ];
    }

    private function syncPackItems(AcademyPromptPack $pack, array $promptIds): void
    {
        AcademyPromptPackItem::query()->where('pack_id', $pack->id)->delete();

        foreach (array_values($promptIds) as $index => $promptId) {
            AcademyPromptPackItem::query()->create([
                'pack_id' => $pack->id,
                'prompt_template_id' => (int) $promptId,
                'order_num' => $index,
            ]);
        }
    }
}