<?php

namespace Database\Seeders;

use App\Models\BlogPost;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Intervention\Image\Facades\Image;
use MediaUploader;

/**
 * BlogPostTableSeeder (Improved)
 *
 * Creates 15 realistic blog posts with relevant titles, rich content,
 * correct author_id (admin user 1), and linked to seeded categories.
 */
class BlogPostTableSeeder extends Seeder
{
    public function run(): void
    {
        $authorId = User::whereHas('roles', fn($q) => $q->where('id', 1))->value('id') ?? 1;

        $categoryIds = DB::table('blog_categories')->pluck('id', 'name');

        $posts = [
            [
                'title'       => 'Variable Server Software v2.0.0 Released',
                'category'    => 'Product Updates',
                'excerpt'     => 'Major overhaul with improved performance, new admin dashboard, and extended API coverage.',
                'content'     => "<p>We're thrilled to announce the release of <strong>Variable Server Software v2.0.0</strong> — our most significant update yet.</p><h2>What's New</h2><ul><li>Completely redesigned admin dashboard with dark mode support</li><li>40% performance improvement in request handling</li><li>New REST API with 30+ endpoints</li><li>Multi-server clustering support</li></ul><p>Existing license holders on the Professional plan can download the update from their account immediately. Personal license holders will receive the update within your support period.</p>",
                'published_at' => now()->subDays(5),
            ],
            [
                'title'       => 'How to Activate Your License Key in 3 Steps',
                'category'    => 'Tutorials & Guides',
                'excerpt'     => 'A clear, step-by-step guide to activating your software license and registering your domain.',
                'content'     => "<p>Got your license key but not sure how to activate it? This quick guide walks you through the entire process.</p><h2>Step 1: Log into Your Account</h2><p>Navigate to your Account dashboard and click <em>Licenses</em> in the sidebar.</p><h2>Step 2: Enter Your Domain</h2><p>Click <em>Add Domain</em> next to your license key and enter your production domain (e.g., <code>yourdomain.com</code>).</p><h2>Step 3: Verify Activation</h2><p>Our system will verify the domain within 60 seconds. You'll receive a confirmation email once activated.</p><p>If you encounter any issues, our support team is available 24/7.</p>",
                'published_at' => now()->subDays(12),
            ],
            [
                'title'       => 'Why Software Licensing Models Matter for Your Business',
                'category'    => 'Licensing 101',
                'excerpt'     => 'One-time, subscription, or usage-based — choosing the right model can make or break your revenue strategy.',
                'content'     => "<p>The licensing model you choose directly impacts your revenue predictability, customer retention, and growth ceiling. Here's a breakdown of the most common models.</p><h2>One-Time Perpetual License</h2><p>The customer pays once and owns the software forever. Great for tools with a long shelf life, but limits your recurring revenue.</p><h2>Subscription (SaaS) Model</h2><p>Monthly or yearly recurring billing. Provides predictable MRR and aligns incentives — you keep improving the product to retain customers.</p><h2>Usage-Based / Metered</h2><p>Customers pay based on consumption (API calls, seats, storage). Works well for infrastructure products.</p><p>We offer both one-time licenses and subscription plans so you can pick what fits your workflow.</p>",
                'published_at' => now()->subDays(18),
            ],
            [
                'title'       => 'From Freelancer to Agency: Managing Multiple Client Licenses',
                'category'    => 'Business Tips',
                'excerpt'     => 'How professional developers manage software licenses across multiple client projects without the headache.',
                'content'     => "<p>As a freelancer scaling to agency, one of the most overlooked pain points is <strong>license management</strong>. Here's how to do it right.</p><h2>Use a Professional Multi-Domain License</h2><p>Our Professional License covers 5 domains — perfect for running dev, staging, and up to 3 client sites under a single key. No more buying separate licenses for each client.</p><h2>Centralize License Tracking</h2><p>Keep a spreadsheet or use a project management tool to track which license is active on which domain, expiry dates, and renewal status.</p><h2>Invoice Clients for Licensing</h2><p>Most clients expect to be billed for software their site runs on. Build the license cost into your project quote.</p>",
                'published_at' => now()->subDays(25),
            ],
            [
                'title'       => 'SaaS Project Manager Starter Plan — What\'s Included',
                'category'    => 'Product Updates',
                'excerpt'     => 'Everything you get with the Starter Plan and how to make the most of it for small teams.',
                'content'     => "<p>The <strong>Starter Plan</strong> for SaaS Project Manager is designed for small teams that want powerful tools without enterprise-level pricing.</p><h2>What You Get</h2><ul><li>Up to 5 team members</li><li>10GB file storage</li><li>Basic reporting &amp; analytics dashboard</li><li>Unlimited projects</li><li>Email notifications</li></ul><h2>Perfect For</h2><p>Startups, solo founders with a small team, or freelancers who need a lightweight coordination tool.</p><p>Ready to upgrade? The Agency Plan is just a click away and includes unlimited users plus advanced analytics.</p>",
                'published_at' => now()->subDays(30),
            ],
            [
                'title'       => 'How a Design Agency Saved 20 Hours/Month with SaaS Project Manager',
                'category'    => 'Case Studies',
                'excerpt'     => 'Mitchell Digital, a UK-based design agency, cut their project coordination time in half after switching.',
                'content'     => "<p><strong>Mitchell Digital</strong> is a 12-person branding agency based in London. Before adopting SaaS Project Manager, they were juggling Slack, Trello, and Google Sheets — with client feedback falling through the cracks.</p><blockquote>\"Within the first week, we eliminated our daily status meeting entirely. The dashboard tells us everything at a glance.\" — Sophia Mitchell, Founder</blockquote><h2>The Results</h2><ul><li>20+ hours saved per month across the team</li><li>Client approval cycles reduced from 5 days to 2</li><li>Zero missed deadlines in the last 3 months</li></ul><p>They're currently on the Agency Yearly plan with the Dedicated IP addon for custom tracking.</p>",
                'published_at' => now()->subDays(7),
            ],
            [
                'title'       => 'Understanding Support Policies: What\'s Covered After You Buy',
                'category'    => 'Licensing 101',
                'excerpt'     => 'What does a 6-month support policy actually include? We break down every detail.',
                'content'     => "<p>When you purchase the Variable Server Software, you get a <strong>6-month support policy</strong> included. Here's exactly what that means.</p><h2>What's Included</h2><ul><li>Priority email support with 24-hour response time</li><li>All bug fix releases (patch versions, e.g., v2.0.1, v2.0.2)</li><li>Security hotfixes regardless of support status</li><li>Access to our private knowledge base</li></ul><h2>What's Not Included</h2><ul><li>Major version upgrades (e.g., v2 → v3) — these are paid separately</li><li>Custom development or feature requests</li></ul><h2>Renewing Your Support</h2><p>When your 6 months are up, you'll receive a renewal reminder with a <strong>20% discount</strong> valid for 30 days.</p>",
                'published_at' => now()->subDays(9),
            ],
            [
                'title'       => 'Setting Up Two-Factor Authentication for Your Account',
                'category'    => 'Tutorials & Guides',
                'excerpt'     => 'A quick guide to securing your account with 2FA in under 5 minutes.',
                'content'     => "<p>Account security matters, especially when your license keys and subscription data are stored here. Enable 2FA in minutes.</p><h2>Step 1: Go to Account Settings</h2><p>Click your avatar in the top right → <em>Account Settings</em> → <em>Security</em>.</p><h2>Step 2: Enable Authenticator App</h2><p>We support Google Authenticator, Authy, and any TOTP-compatible app. Scan the QR code and enter the 6-digit code to confirm.</p><h2>Step 3: Save Your Backup Codes</h2><p>Download and store your one-time backup codes in a secure location — you'll need them if you lose access to your authenticator app.</p>",
                'published_at' => now()->subDays(11),
            ],
            [
                'title'       => 'Monthly vs Yearly Billing: Which Is Right for You?',
                'category'    => 'SaaS Insights',
                'excerpt'     => 'A data-driven look at when to commit to annual billing and when monthly flexibility makes more sense.',
                'content'     => "<p>Choosing between monthly and yearly billing is one of the first decisions every SaaS customer makes. Here's how to think about it.</p><h2>Choose Monthly If...</h2><ul><li>You're still evaluating whether the tool fits your workflow</li><li>Your budget is inconsistent month-to-month</li><li>You anticipate downgrading or cancelling soon</li></ul><h2>Choose Yearly If...</h2><ul><li>You've already validated the tool in your workflow</li><li>You want to save ~17% compared to monthly</li><li>You're billing the cost to a client project anyway</li></ul><p>For SaaS Project Manager, the Yearly plan saves you \$98/year on the Starter plan and \$98/year on Agency. That's real money.</p>",
                'published_at' => now()->subDays(14),
            ],
            [
                'title'       => 'Introducing Webhook Support for Real-Time Integrations',
                'category'    => 'Product Updates',
                'excerpt'     => 'Connect your external tools and automate workflows using our new webhook system.',
                'content'     => "<p>We're excited to launch <strong>webhook support</strong> across all plans — enabling you to integrate our platform with any external tool that accepts webhooks.</p><h2>Supported Events</h2><ul><li>order.completed</li><li>subscription.activated</li><li>subscription.cancelled</li><li>license.created</li><li>license.revoked</li></ul><h2>How to Set Up</h2><p>Go to Admin → Webhooks → Create New Webhook. Enter your endpoint URL, select the events you want to listen for, and save. We'll immediately send a test ping to verify connectivity.</p><p>Perfect for triggering onboarding flows, syncing to a CRM, or notifying Slack when a new order comes in.</p>",
                'published_at' => now()->subDays(17),
            ],
            [
                'title'       => 'The Business Case for DRM-Free Digital Products',
                'category'    => 'Business Tips',
                'excerpt'     => 'Why removing DRM restrictions increases customer trust and reduces support burden.',
                'content'     => "<p>DRM (Digital Rights Management) was once seen as essential for protecting digital products. The reality? It punishes legitimate customers more than pirates.</p><h2>Problems with DRM</h2><ul><li>Legitimate buyers can't access files on their preferred devices</li><li>DRM servers go down — customers lose access to products they paid for</li><li>High support ticket volume from frustrated users</li></ul><h2>Benefits of Going DRM-Free</h2><ul><li>Fewer refund requests — customers know exactly what they're getting</li><li>Higher review ratings — no friction, no frustration</li><li>Builds trust and encourages repeat purchases</li></ul><p>Our ebook products are 100% DRM-free because we believe in treating customers with respect.</p>",
                'published_at' => now()->subDays(20),
            ],
            [
                'title'       => 'How We Calculate Your License Expiry Date',
                'category'    => 'Licensing 101',
                'excerpt'     => 'Everything you need to know about how license validity periods are calculated from your purchase date.',
                'content'     => "<p>A common question: <em>\"When exactly does my license expire?\"</em>. Here's the definitive answer.</p><h2>One-Time Licenses</h2><p>Your license validity period starts from the <strong>order completion date</strong> — the moment your payment is confirmed. If you bought on March 1 with a 1-year validity, it expires on March 1 of the following year.</p><h2>Lifetime Licenses</h2><p>The Professional plan ships with a lifetime license — no expiry date, ever. Your license key will work indefinitely regardless of plan renewals.</p><h2>Where to Check Your Expiry</h2><p>Go to Account → Licenses. You'll see the expiry date (or \"Lifetime\" for Professional) alongside your domain list and activation status.</p>",
                'published_at' => now()->subDays(23),
            ],
            [
                'title'       => '5 Ways SaaS Businesses Reduce Churn',
                'category'    => 'SaaS Insights',
                'excerpt'     => 'Proven tactics from successful SaaS companies to keep subscribers engaged and paying.',
                'content'     => "<p>Churn is the silent killer of SaaS businesses. Here are 5 proven tactics to reduce it.</p><h2>1. Nail Your Onboarding</h2><p>First-week activation is the strongest predictor of 6-month retention. Build guided tours and proactive check-in emails.</p><h2>2. Offer Annual Billing Incentives</h2><p>Annual subscribers churn 50–80% less than monthly ones. Offer a meaningful discount (15–20%) to get customers to commit.</p><h2>3. Surface Value Regularly</h2><p>Monthly activity digests, milestone celebrations (\"You've completed 100 tasks!\"), and benchmark reports remind users why they're paying.</p><h2>4. Proactive Support</h2><p>Don't wait for tickets. Monitor usage and reach out when engagement drops.</p><h2>5. Transparent Cancellation</h2><p>A smooth cancellation flow with a pause option converts ~15% of cancellation-intent users into paused accounts instead.</p>",
                'published_at' => now()->subDays(26),
            ],
            [
                'title'       => 'Getting Started with the Dedicated IP Addon',
                'category'    => 'Tutorials & Guides',
                'excerpt'     => 'Configure your Dedicated IP for better email deliverability in under 10 minutes.',
                'content'     => "<p>The <strong>Dedicated IP addon</strong> gives your SaaS Project Manager account a unique IP for outgoing tracking and notifications — separating your reputation from shared infrastructure.</p><h2>Why It Matters</h2><p>Shared IPs carry the reputation of every tenant — one bad actor can affect everyone's deliverability. A dedicated IP is yours alone.</p><h2>Setup</h2><ol><li>Go to Account → Subscriptions → Manage Addons</li><li>Click <em>Add Dedicated IP</em></li><li>Your IP will be provisioned within 15 minutes</li><li>Update your domain DNS with the provided SPF/DKIM records</li></ol><p>Need help with DNS configuration? Our support team can walk you through it.</p>",
                'published_at' => now()->subDays(28),
            ],
            [
                'title'       => 'Annual Recap: Our Most Downloaded Products of the Year',
                'category'    => 'Case Studies',
                'excerpt'     => 'A look back at the products customers loved most and what drove their popularity.',
                'content'     => "<p>As the year wraps up, we're sharing a snapshot of what resonated most with our customers.</p><h2>Most Downloads: Variable Server Software v2.0.0</h2><p>The v2 release drove a 280% spike in downloads week-over-week. The API additions were the most-cited reason for upgrades.</p><h2>Highest-Rated: Simple Ebook Download</h2><p>Average rating: 4.8/5. Customers consistently praised the DRM-free format and clean PDF layout.</p><h2>Fastest Growing: SaaS Project Manager</h2><p>Subscription count grew 3.2x year-over-year. The Agency plan with the Dedicated IP addon was our most popular bundle.</p><p>Thank you to everyone who chose us this year. The roadmap for next year looks even more exciting — stay tuned.</p>",
                'published_at' => now()->subDays(30),
            ],
        ];

        foreach ($posts as $post) {
            // Use Eloquent create() so attachMedia() works in attachDemoBlogImages()
            BlogPost::create([
                'title'        => $post['title'],
                'slug'         => Str::slug($post['title']),
                'content'      => $post['content'],
                'author_id'    => $authorId,
                'status'       => 'published',
                'published_at' => $post['published_at'],
                'created_at'   => $post['published_at'],
                'updated_at'   => $post['published_at'],
            ]);
        }

        $this->attachDemoBlogImages();
    }

    /**
     * Attach featured images to blog posts from storage/demo/blog/.
     *
     * Images sorted alphabetically and assigned one-per-post in seeder order.
     * Mirrors AdminMediaController::store() exactly:
     *   - Uploads to uploads/YYYYMM
     *   - Creates thumbnail + medium resized variants
     *   - Saves variant paths to media->meta()
     *
     * Drop any image names into storage/demo/blog/ — no naming convention needed.
     */
    private function attachDemoBlogImages(): void
    {
        $demoDir = storage_path('demo/blog');

        if (!File::isDirectory($demoDir)) {
            return;
        }

        $validExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
        $imageFiles = collect(File::files($demoDir))
            ->filter(fn($f) => in_array(strtolower($f->getExtension()), $validExtensions))
            ->sortBy(fn($f) => $f->getFilename())
            ->values();

        if ($imageFiles->isEmpty()) {
            return;
        }

        $posts      = BlogPost::orderBy('id')->get();
        $disk       = 'public';
        $uploadPath = 'uploads/' . date('Ym');

        foreach ($posts as $index => $post) {
            if (!isset($imageFiles[$index])) {
                break;
            }

            // Skip if already has a featured image (idempotent)
            if ($post->hasMedia('featuredImage')) {
                continue;
            }

            $sourceFile = $imageFiles[$index]->getPathname();

            try {
                // Step 1: Upload via MediaUploader
                $media = MediaUploader::fromSource($sourceFile)
                    ->toDestination($disk, $uploadPath)
                    ->upload();

                // Step 2: Create resized variants
                if ($media->aggregate_type === 'image') {
                    foreach (config('media.sizes') as $name => $size) {
                        $width  = ($name !== 'medium') ? $size[0] : null;
                        $height = $size[1];

                        $resizedFilename = $media->filename . '.' . $media->extension;
                        $absPath         = $media->directory . '/' . $name . '/';
                        $fullAbsPath     = storage_path('app/' . $disk . '/' . $absPath);

                        if (!File::exists($fullAbsPath)) {
                            File::makeDirectory($fullAbsPath, 0755, true);
                        }

                        Image::make(storage_path('app/' . $disk . '/' . $media->getDiskPath()))
                            ->resize($width, $height, function ($constraint) {
                                $constraint->aspectRatio();
                                $constraint->upsize();
                            })
                            ->save($fullAbsPath . $resizedFilename);

                        // Step 3: Save meta path
                        $media->meta()->updateOrCreate(
                            ['size_name' => $name],
                            ['path'      => $absPath . $resizedFilename]
                        );
                    }
                }

                // Step 4: Attach to post featured image
                $post->attachMedia($media, ['featuredImage']);

            } catch (\Exception $e) {
                \Log::warning('Demo blog image attach failed for "' . $post->title . '": ' . $e->getMessage());
            }
        }
    }
}
