<?php

declare(strict_types=1);

namespace Database\Seeders;

use App\Models\NovaCard;
use App\Models\NovaCardAsset;
use App\Models\NovaCardAssetPack;
use App\Models\NovaCardCategory;
use App\Models\NovaCardChallenge;
use App\Models\NovaCardChallengeEntry;
use App\Models\NovaCardCollection;
use App\Models\NovaCardCollectionItem;
use App\Models\NovaCardTag;
use App\Models\NovaCardTemplate;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class NovaCardDemoSeeder extends Seeder
{
    public function run(): void
    {
        if (! (bool) config('nova_cards.seed_demo_cards.enabled', false)) {
            return;
        }

        $userConfig = (array) config('nova_cards.seed_demo_cards.user', []);
        $user = User::query()->firstOrCreate(
            ['email' => (string) Arr::get($userConfig, 'email', 'nova-cards-demo@skinbase.test')],
            [
                'username' => (string) Arr::get($userConfig, 'username', 'nova.cards'),
                'name' => (string) Arr::get($userConfig, 'name', 'Nova Cards'),
                'password' => (string) Arr::get($userConfig, 'password', 'password'),
                'role' => 'user',
            ]
        );

        $cards = [
            [
                'slug' => 'official-spark',
                'title' => 'Official Spark',
                'quote_text' => 'Small moments of focus turn into visible momentum.',
                'quote_author' => 'Skinbase Nova',
                'quote_source' => 'Launch Collection',
                'description' => 'An official Nova Cards demo card for featured browse surfaces.',
                'category_slug' => 'motivation',
                'template_slug' => 'neon-nova',
                'format' => NovaCard::FORMAT_SQUARE,
                'featured' => true,
                'tags' => ['focus', 'launch'],
                'project_json' => [
                    'layout' => ['layout' => 'quote_heavy', 'position' => 'center', 'alignment' => 'center', 'padding' => 'comfortable', 'max_width' => 'balanced'],
                    'typography' => ['font_preset' => 'bold-poster', 'text_color' => '#e0f2fe', 'accent_color' => '#ffffff', 'quote_size' => 80, 'author_size' => 24, 'letter_spacing' => 1, 'line_height' => 1.05, 'shadow_preset' => 'strong'],
                    'background' => ['type' => 'gradient', 'gradient_preset' => 'midnight-nova', 'gradient_colors' => ['#0f172a', '#1d4ed8'], 'solid_color' => '#111827', 'overlay_style' => 'dark-strong', 'focal_position' => 'center', 'blur_level' => 0, 'opacity' => 65],
                ],
            ],
            [
                'slug' => 'soft-breath',
                'title' => 'Soft Breath',
                'quote_text' => 'Rest is not a pause from growth. It is part of it.',
                'quote_author' => 'Skinbase Nova',
                'quote_source' => 'Healing Notes',
                'description' => 'A calm demo card showing the softer side of Nova Cards.',
                'category_slug' => 'healing',
                'template_slug' => 'soft-pastel',
                'format' => NovaCard::FORMAT_PORTRAIT,
                'featured' => false,
                'tags' => ['healing', 'calm'],
                'project_json' => [
                    'layout' => ['layout' => 'centered', 'position' => 'center', 'alignment' => 'center', 'padding' => 'airy', 'max_width' => 'compact'],
                    'typography' => ['font_preset' => 'soft-handwritten', 'text_color' => '#1f2937', 'accent_color' => '#6d28d9', 'quote_size' => 72, 'author_size' => 24, 'letter_spacing' => 0, 'line_height' => 1.2, 'shadow_preset' => 'none'],
                    'background' => ['type' => 'gradient', 'gradient_preset' => 'soft-pastel', 'gradient_colors' => ['#f9a8d4', '#c4b5fd'], 'solid_color' => '#f5d0fe', 'overlay_style' => 'light-soft', 'focal_position' => 'center', 'blur_level' => 0, 'opacity' => 35],
                ],
            ],
            [
                'slug' => 'night-echo',
                'title' => 'Night Echo',
                'quote_text' => 'Not every quiet room is empty. Some are full of answers.',
                'quote_author' => 'Skinbase Nova',
                'quote_source' => 'Dark Mood Study',
                'description' => 'A darker official demo card for mood-oriented discovery blocks.',
                'category_slug' => 'dark-mood',
                'template_slug' => 'cinematic-dark',
                'format' => NovaCard::FORMAT_LANDSCAPE,
                'featured' => false,
                'tags' => ['night', 'mood'],
                'project_json' => [
                    'layout' => ['layout' => 'minimal', 'position' => 'lower-middle', 'alignment' => 'left', 'padding' => 'comfortable', 'max_width' => 'wide'],
                    'typography' => ['font_preset' => 'modern-sans', 'text_color' => '#f8fafc', 'accent_color' => '#93c5fd', 'quote_size' => 68, 'author_size' => 20, 'letter_spacing' => 1, 'line_height' => 1.2, 'shadow_preset' => 'soft'],
                    'background' => ['type' => 'gradient', 'gradient_preset' => 'deep-cinema', 'gradient_colors' => ['#020617', '#334155'], 'solid_color' => '#020617', 'overlay_style' => 'dark-strong', 'focal_position' => 'center', 'blur_level' => 0, 'opacity' => 80],
                ],
            ],
            [
                'slug' => 'editorial-glow',
                'title' => 'Editorial Glow',
                'quote_text' => 'Design with restraint, then let one accent do the speaking.',
                'quote_author' => 'Skinbase Nova',
                'quote_source' => 'Editorial Kit',
                'description' => 'A crisp editorial-format demo card for official collections.',
                'category_slug' => 'motivation',
                'template_slug' => 'golden-serif',
                'format' => NovaCard::FORMAT_PORTRAIT,
                'featured' => true,
                'tags' => ['editorial', 'gold'],
                'project_json' => [
                    'layout' => ['layout' => 'author_emphasis', 'position' => 'center', 'alignment' => 'center', 'padding' => 'comfortable', 'max_width' => 'compact'],
                    'typography' => ['font_preset' => 'elegant-serif', 'text_color' => '#fffbeb', 'accent_color' => '#fbbf24', 'quote_size' => 76, 'author_size' => 24, 'letter_spacing' => 1, 'line_height' => 1.15, 'shadow_preset' => 'soft'],
                    'background' => ['type' => 'gradient', 'gradient_preset' => 'amber-glow', 'gradient_colors' => ['#451a03', '#b45309'], 'solid_color' => '#451a03', 'overlay_style' => 'dark-soft', 'focal_position' => 'center', 'blur_level' => 0, 'opacity' => 70],
                ],
            ],
            [
                'slug' => 'story-bloom',
                'title' => 'Story Bloom',
                'quote_text' => 'If the layout breathes, the words can reach further.',
                'quote_author' => 'Skinbase Nova',
                'quote_source' => 'Story Vertical Pack',
                'description' => 'A vertical story-oriented demo card for public browsing and challenges.',
                'category_slug' => 'healing',
                'template_slug' => 'story-vertical',
                'format' => NovaCard::FORMAT_STORY,
                'featured' => false,
                'tags' => ['story', 'vertical'],
                'project_json' => [
                    'layout' => ['layout' => 'centered', 'position' => 'center', 'alignment' => 'center', 'padding' => 'airy', 'max_width' => 'balanced'],
                    'typography' => ['font_preset' => 'modern-sans', 'text_color' => '#ecfdf5', 'accent_color' => '#6ee7b7', 'quote_size' => 82, 'author_size' => 24, 'letter_spacing' => 0, 'line_height' => 1.18, 'shadow_preset' => 'soft'],
                    'background' => ['type' => 'gradient', 'gradient_preset' => 'emerald-bloom', 'gradient_colors' => ['#064e3b', '#10b981'], 'solid_color' => '#022c22', 'overlay_style' => 'dark-soft', 'focal_position' => 'center', 'blur_level' => 0, 'opacity' => 65],
                ],
            ],
            [
                'slug' => 'remix-launch-variant',
                'title' => 'Remix Launch Variant',
                'quote_text' => 'Take the spark and give it a new rhythm.',
                'quote_author' => 'Skinbase Nova',
                'quote_source' => 'Remix Lab',
                'description' => 'A seeded remix showing lineage in demo content.',
                'category_slug' => 'motivation',
                'template_slug' => 'bold-statement',
                'format' => NovaCard::FORMAT_SQUARE,
                'featured' => false,
                'tags' => ['remix', 'launch'],
                'project_json' => [
                    'layout' => ['layout' => 'quote_heavy', 'position' => 'center', 'alignment' => 'left', 'padding' => 'comfortable', 'max_width' => 'wide'],
                    'typography' => ['font_preset' => 'bold-poster', 'text_color' => '#ffffff', 'accent_color' => '#38bdf8', 'quote_size' => 80, 'author_size' => 22, 'letter_spacing' => 1, 'line_height' => 1.05, 'shadow_preset' => 'strong'],
                    'background' => ['type' => 'gradient', 'gradient_preset' => 'midnight-nova', 'gradient_colors' => ['#082f49', '#1d4ed8'], 'solid_color' => '#0f172a', 'overlay_style' => 'dark-strong', 'focal_position' => 'center', 'blur_level' => 0, 'opacity' => 75],
                ],
            ],
        ];

        $seededCards = collect();

        foreach ($cards as $index => $definition) {
            $category = NovaCardCategory::query()->where('slug', $definition['category_slug'])->first();
            $template = NovaCardTemplate::query()->where('slug', $definition['template_slug'])->first();

            $card = NovaCard::query()->updateOrCreate(
                ['slug' => $definition['slug']],
                [
                    'uuid' => NovaCard::query()->where('slug', $definition['slug'])->value('uuid') ?: (string) Str::uuid(),
                    'user_id' => $user->id,
                    'category_id' => $category?->id,
                    'template_id' => $template?->id,
                    'title' => $definition['title'],
                    'quote_text' => $definition['quote_text'],
                    'quote_author' => $definition['quote_author'],
                    'quote_source' => $definition['quote_source'],
                    'description' => $definition['description'],
                    'format' => $definition['format'],
                    'project_json' => [
                        'content' => [
                            'title' => $definition['title'],
                            'quote_text' => $definition['quote_text'],
                            'quote_author' => $definition['quote_author'],
                            'quote_source' => $definition['quote_source'],
                        ],
                        ...$definition['project_json'],
                        'decorations' => [],
                    ],
                    'render_version' => 1,
                    'background_type' => 'gradient',
                    'visibility' => NovaCard::VISIBILITY_PUBLIC,
                    'status' => NovaCard::STATUS_PUBLISHED,
                    'moderation_status' => NovaCard::MOD_APPROVED,
                    'featured' => (bool) $definition['featured'],
                    'allow_download' => true,
                    'views_count' => 25 - ($index * 4),
                    'shares_count' => 6 - $index,
                    'downloads_count' => 3 - min($index, 2),
                    'likes_count' => max(1, 8 - $index),
                    'favorites_count' => max(0, 5 - $index),
                    'saves_count' => max(0, 4 - $index),
                    'published_at' => now()->subDays($index + 1),
                ]
            );

            $tagIds = collect($definition['tags'])
                ->map(function (string $tag): int {
                    $model = NovaCardTag::query()->firstOrCreate(
                        ['slug' => Str::slug($tag)],
                        ['name' => Str::title(str_replace('-', ' ', $tag))]
                    );

                    return (int) $model->id;
                })
                ->all();

            $card->tags()->sync($tagIds);
            $seededCards->push($card->fresh());
        }

        $source = $seededCards->firstWhere('slug', 'official-spark');
        $remix = $seededCards->firstWhere('slug', 'remix-launch-variant');

        if ($source && $remix) {
            $remix->forceFill([
                'original_card_id' => $source->id,
                'root_card_id' => $source->id,
                'remixes_count' => 0,
            ])->save();

            $source->forceFill([
                'remixes_count' => 1,
            ])->save();
        }

        foreach (array_merge(
            (array) config('nova_cards.asset_packs', []),
            (array) config('nova_cards.template_packs', [])
        ) as $index => $packConfig) {
            $pack = NovaCardAssetPack::query()->updateOrCreate(
                ['slug' => (string) ($packConfig['slug'] ?? ('pack-' . $index))],
                [
                    'name' => (string) ($packConfig['name'] ?? 'Nova Card Pack'),
                    'description' => $packConfig['description'] ?? null,
                    'type' => (string) ($packConfig['type'] ?? NovaCardAssetPack::TYPE_ASSET),
                    'manifest_json' => $packConfig['manifest_json'] ?? [],
                    'official' => (bool) ($packConfig['official'] ?? true),
                    'active' => (bool) ($packConfig['active'] ?? true),
                    'order_num' => $index,
                ]
            );

            foreach ((array) data_get($packConfig, 'manifest_json.items', []) as $itemIndex => $item) {
                NovaCardAsset::query()->updateOrCreate(
                    ['asset_pack_id' => $pack->id, 'asset_key' => (string) ($item['key'] ?? ('asset-' . $itemIndex))],
                    [
                        'label' => (string) ($item['label'] ?? 'Nova Asset'),
                        'type' => (string) ($item['type'] ?? 'glyph'),
                        'preview_image' => $item['preview_image'] ?? null,
                        'data_json' => $item,
                        'official' => true,
                        'active' => true,
                        'order_num' => $itemIndex,
                    ]
                );
            }
        }

        $collection = NovaCardCollection::query()->updateOrCreate(
            ['user_id' => $user->id, 'slug' => 'editorial-favorites'],
            [
                'name' => 'Editorial Favorites',
                'description' => 'Officially curated Nova Cards spotlighting launch visuals, remixes, and story-first layouts.',
                'visibility' => NovaCardCollection::VISIBILITY_PUBLIC,
                'official' => true,
                'featured' => true,
                'cards_count' => 0,
            ]
        );

        $challengeCollection = NovaCardCollection::query()->updateOrCreate(
            ['user_id' => $user->id, 'slug' => 'challenge-winners'],
            [
                'name' => 'Challenge Winners',
                'description' => 'Official challenge highlights and standout seeded examples.',
                'visibility' => NovaCardCollection::VISIBILITY_PUBLIC,
                'official' => true,
                'featured' => false,
                'cards_count' => 0,
            ]
        );

        foreach ($seededCards->take(4)->values() as $position => $card) {
            NovaCardCollectionItem::query()->updateOrCreate(
                ['collection_id' => $collection->id, 'card_id' => $card->id],
                ['sort_order' => $position + 1, 'note' => $position === 0 ? 'Launch anchor card for the collection.' : null],
            );
        }

        $collection->forceFill(['cards_count' => NovaCardCollectionItem::query()->where('collection_id', $collection->id)->count()])->save();

        foreach ($seededCards->slice(2, 4)->values() as $position => $card) {
            NovaCardCollectionItem::query()->updateOrCreate(
                ['collection_id' => $challengeCollection->id, 'card_id' => $card->id],
                ['sort_order' => $position + 1, 'note' => $position === 0 ? 'Seeded challenge highlight.' : null],
            );
        }

        $challengeCollection->forceFill(['cards_count' => NovaCardCollectionItem::query()->where('collection_id', $challengeCollection->id)->count()])->save();

        $challenge = NovaCardChallenge::query()->updateOrCreate(
            ['slug' => 'launch-remix-run'],
            [
                'user_id' => $user->id,
                'title' => 'Launch Remix Run',
                'description' => 'A seeded official challenge for remix-ready launch cards.',
                'prompt' => 'Remix one official card and push the layout into a fresh direction.',
                'status' => NovaCardChallenge::STATUS_ACTIVE,
                'official' => true,
                'featured' => true,
                'starts_at' => now()->subDays(2),
                'ends_at' => now()->addDays(10),
            ]
        );

        $secondaryChallenge = NovaCardChallenge::query()->updateOrCreate(
            ['slug' => 'minimal-poster-week'],
            [
                'user_id' => $user->id,
                'title' => 'Minimal Poster Week',
                'description' => 'A seeded editorial challenge focused on restraint and poster typography.',
                'prompt' => 'Build a bold quote poster with minimal decoration and strong hierarchy.',
                'status' => NovaCardChallenge::STATUS_COMPLETED,
                'official' => true,
                'featured' => false,
                'starts_at' => now()->subDays(14),
                'ends_at' => now()->subDays(3),
            ]
        );

        foreach ($seededCards->take(3)->values() as $position => $card) {
            NovaCardChallengeEntry::query()->updateOrCreate(
                ['challenge_id' => $challenge->id, 'card_id' => $card->id],
                ['user_id' => $user->id, 'status' => $position === 0 ? 'featured' : 'active', 'note' => $position === 0 ? 'Seeded featured entry.' : null],
            );
        }

        foreach ($seededCards->slice(3, 3)->values() as $position => $card) {
            NovaCardChallengeEntry::query()->updateOrCreate(
                ['challenge_id' => $secondaryChallenge->id, 'card_id' => $card->id],
                ['user_id' => $user->id, 'status' => $position === 0 ? 'winner' : 'active', 'note' => $position === 0 ? 'Seeded winner entry.' : null],
            );
        }

        $challenge->forceFill([
            'entries_count' => NovaCardChallengeEntry::query()->where('challenge_id', $challenge->id)->count(),
            'winner_card_id' => $seededCards->first()?->id,
        ])->save();

        $secondaryChallenge->forceFill([
            'entries_count' => NovaCardChallengeEntry::query()->where('challenge_id', $secondaryChallenge->id)->count(),
            'winner_card_id' => $seededCards->get(3)?->id,
        ])->save();
    }
}
