<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        if (Schema::hasTable('stories')) {
            Schema::table('stories', function (Blueprint $table): void {
                if (! Schema::hasColumn('stories', 'creator_id')) {
                    $table->foreignId('creator_id')->nullable()->after('id')->constrained('users')->nullOnDelete();
                }

                if (! Schema::hasColumn('stories', 'story_type')) {
                    $table->enum('story_type', [
                        'creator_story',
                        'tutorial',
                        'interview',
                        'project_breakdown',
                        'announcement',
                        'resource',
                    ])->default('creator_story')->after('content');
                }

                if (! Schema::hasColumn('stories', 'reading_time')) {
                    $table->unsignedInteger('reading_time')->default(1)->after('story_type');
                }

                if (! Schema::hasColumn('stories', 'likes_count')) {
                    $table->unsignedInteger('likes_count')->default(0)->after('views');
                }

                if (! Schema::hasColumn('stories', 'comments_count')) {
                    $table->unsignedInteger('comments_count')->default(0)->after('likes_count');
                }
            });

            if (Schema::hasColumn('stories', 'author_id') && Schema::hasTable('stories_authors')) {
                DB::table('stories')
                    ->join('stories_authors', 'stories_authors.id', '=', 'stories.author_id')
                    ->whereNull('stories.creator_id')
                    ->whereNotNull('stories_authors.user_id')
                    ->select(['stories.id as story_id', 'stories_authors.user_id as creator_id'])
                    ->orderBy('stories.id')
                    ->get()
                    ->each(function ($row): void {
                        DB::table('stories')
                            ->where('id', (int) $row->story_id)
                            ->update(['creator_id' => (int) $row->creator_id]);
                    });
            }
        }

        if (! Schema::hasTable('story_views')) {
            Schema::create('story_views', function (Blueprint $table): void {
                $table->id();
                $table->foreignId('story_id')->constrained('stories')->cascadeOnDelete();
                $table->foreignId('user_id')->nullable()->constrained('users')->nullOnDelete();
                $table->string('ip_address', 45)->nullable();
                $table->timestamp('created_at')->useCurrent();

                $table->index(['story_id', 'created_at']);
                $table->index(['user_id', 'created_at']);
            });
        }

        if (! Schema::hasTable('story_likes')) {
            Schema::create('story_likes', function (Blueprint $table): void {
                $table->id();
                $table->foreignId('story_id')->constrained('stories')->cascadeOnDelete();
                $table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
                $table->timestamp('created_at')->useCurrent();

                $table->unique(['story_id', 'user_id']);
                $table->index(['story_id', 'created_at']);
            });
        }
    }

    public function down(): void
    {
        Schema::dropIfExists('story_likes');
        Schema::dropIfExists('story_views');

        if (Schema::hasTable('stories')) {
            Schema::table('stories', function (Blueprint $table): void {
                if (Schema::hasColumn('stories', 'creator_id')) {
                    $table->dropConstrainedForeignId('creator_id');
                }

                foreach (['story_type', 'reading_time', 'likes_count', 'comments_count'] as $column) {
                    if (Schema::hasColumn('stories', $column)) {
                        $table->dropColumn($column);
                    }
                }
            });
        }
    }
};
